It is currently Fri Sep 22, 2017 5:22 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 8 posts ] 
Author Message
PostPosted: Mon Sep 12, 2011 5:41 am 
Offline
User avatar

Joined: Mon Jul 05, 2010 7:59 am
Posts: 53
UPDATE 2: I resolved this issue by setting the length counter to 0 if the channel is ever set to disabled during the $4015 write.

--------------------------------------------------------

UPDATE: Shortly after typing this, I thought of a possible typo that I could have made. Sure enough, I checked and had a variable in the wrong place. While that fixed a few other sound problems I had, this one still remains, but sounds a little different. I'll upload a new video when I get a chance.

Also, this seems to only happen with blocks when I'm in the underground worlds (like 1-2).

---------------------------------------------------------

I have only implemented the first two channels and am trying to work out all of the kinks before moving on to the other channels. There are certain sounds that are not being silenced during their sweep (as I assume they should be). I silenced the second channel shortly after the video starts. Here is an example:

(incorrect sweep sounds)
http://www.youtube.com/watch?v=mTrhzaMnrC0 (Updated)

(another video to show how other sounds....sound)
http://www.youtube.com/watch?v=fHxJRyJtlpw

The video shows mario jumping and hitting a block (or the fireball hitting the block). The values for the block hit are

Code:
$4000: 0x9E, $4000: 0x93, $4000: 0x3A, $4000: 0x0A
$4000: 0x9E, $4000: 0xBB, $4000: 0x3A, $4000: 0x0A


The constant volume flag is set and the length counter is almost at max still. When I load the last four values shown into the sndtest.nes rom, it plays exactly like it does in the video. This is true for other emulators as well.

My question is... is there something else that should be silencing the channel at that point that I am missing?

Thanks!


Last edited by tineras on Mon Sep 12, 2011 3:29 pm, edited 4 times in total.

Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 12, 2011 11:50 am 
Offline

Joined: Sun Sep 19, 2004 11:07 pm
Posts: 154
Aside from $4015 writes...

Sweep sounds a bit slow, do you have the frame sequencer implemented right? It should be clocking twice a frame, so the last set of values should be ticking a new timer period every other frame.

The sweep ought to drop the period below 8 after 38 ticks, or a little under 1.3 seconds, and silence the channel.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 12, 2011 11:55 am 
Offline
User avatar

Joined: Mon Jul 05, 2010 7:59 am
Posts: 53
ReaperSMS wrote:
...Sweep sounds a bit slow, do you have the frame sequencer implemented right? ...


You are right. Now that I have fixed the typo I had, it produces a similar (sweeping upward) sound, but the duration is shorter (and cleaner). However, it is still much longer than it should be and there is still an obvious problem.

I'll re-check the $4015 writes to make sure everything looks correct when I get home. And I'll take another updated video to show the new output.

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 12, 2011 1:13 pm 
Offline

Joined: Sun Sep 19, 2004 11:07 pm
Posts: 154
What does your sweep code look like?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 12, 2011 1:48 pm 
Offline
User avatar

Joined: Mon Jul 05, 2010 7:59 am
Posts: 53
ReaperSMS wrote:
What does your sweep code look like?


Some of my APU code is similar to the MyNES emulator. My sweep function is more or less identical. Below is my sweep function along with my $4001 write code.

Code:
/** SWEEP **/

void APU_rect1::updateSweep()
{
   if(sweepEnable && !sweepSilence)
   {
      if(sweepCount > 0)
      {
         sweepCount--;
      }
      else
      {
         sweepCount = sweepRate;

         if(!sweepNegFlag)   // Sweep Updward
         {
            period += (period >> sweepShift);
         }
         else if(sweepNegFlag)   // Sweep Downward
         {
            period -= (period >> sweepShift) + 1;
         }

         // Check for sweep silence and update frequency
         checkSweepSilence();
      }
   }
   if(sweepReset)
   {
      sweepReset = false;
      sweepCount = sweepRate;
   }
}

Code:
/** $4001 WRITE **/

if(data & 0x80)  rect1.sweepEnable = true;  else  rect1.sweepEnable = false;
rect1.sweepRate = ((data >> 4) & 0x07);
if(data & 0x08)  rect1.sweepNegFlag = true;  else  rect1.sweepNegFlag = false;
rect1.sweepShift = data & 0x07;

if(rect1.sweepShift == 0)
     rect1.sweepEnable = false;

rect1.sweepReset = true;
rect1.checkSweepSilence();

Code:
/*** SWEEP SILENCE ***/

sweepSilence = false;

if(period < 8 || (!sweepNegFlag && period > 0x7FF))
{
   sweepSilence = true;
}
if(!sweepSilence)   // Calculate new samples per period
{
   double freq = 1790000 / 16 / (period + 1);
   samplesPerPeriod = (unsigned int)(samplingRate / freq);
}


Also, I should note that almost every other sound seems correct (music, jumping, going down pipes, getting mushrooms, etc.).

Here is an updated video: http://www.youtube.com/watch?v=mTrhzaMnrC0
And another to compare other sounds: http://www.youtube.com/watch?v=fHxJRyJtlpw

Thanks


Last edited by tineras on Mon Sep 12, 2011 2:50 pm, edited 4 times in total.

Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 12, 2011 1:59 pm 
Offline

Joined: Sun Sep 19, 2004 11:07 pm
Posts: 154
and checkSweepSilence is something along the lines of:

Code:
checkSweepSilence()
{
      if (sweepNegFlag)
            sweepSilence = (period < 8);
      else
            sweepSilence = ((period + (period >> sweepShift)) > 0x7FF);
}

?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 12, 2011 2:04 pm 
Offline
User avatar

Joined: Mon Jul 05, 2010 7:59 am
Posts: 53
ReaperSMS wrote:
and checkSweepSilence is something along the lines of:

Code:
checkSweepSilence()
{
      if (sweepNegFlag)
            sweepSilence = (period < 8);
      else
            sweepSilence = ((period + (period >> sweepShift)) > 0x7FF);
}

?


I updated the previous post with the checkSweepSilence code.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 12, 2011 7:20 pm 
Offline

Joined: Mon Mar 27, 2006 5:23 pm
Posts: 1338
Small note:

Code:
if(data & 0x80)  rect1.sweepEnable = true;  else  rect1.sweepEnable = false;


Can be written as:
Code:
rect1.sweepEnable = data & 0x80;


Boolean assign will cast a non-zero value to true (1).


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group