It is currently Fri Oct 20, 2017 6:28 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 44 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
 Post subject: Re: Audio psuedo-code
PostPosted: Mon Jan 25, 2016 5:01 am 
Offline
User avatar

Joined: Sun Mar 19, 2006 3:06 am
Posts: 583
Location: Gothenburg/Sweden
Thanks again for your great help.

Triangle-channel is causing me a little headache. I attach a sample from "Mario Bros". Zero-volume doesn't seem to be zero if you check the wav-file. I've checked your psuedo-code and compared it to my code and it should be the same, so...
Or should it behave like that?


Attachments:
File comment: Triangle-only from "Mario Bros" titlescreen.
mariobros-triangle-20160125.zip [8.95 KiB]
Downloaded 59 times

_________________
http://nes.goondocks.se/
Top
 Profile  
 
 Post subject: Re: Audio psuedo-code
PostPosted: Mon Jan 25, 2016 6:21 am 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
It's that way, but there's a fix. When stopped, the triangle always outputs the last sample. Use a volume decay method, like... output -= output >> shf_factor (usually, a number between 5 and 8 - for 16bit output mode).


Top
 Profile  
 
 Post subject: Re: Audio psuedo-code
PostPosted: Mon Jan 25, 2016 10:22 am 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
Zepper is correct. Such a filter will cause output to "drift" towards zero. Though his pseudo-code is a little off... you'd want to keep track of a previous sample... otherwise you're just reducing the volume without actually introducing drift.

Blargg posted a close approximation of the filters used by the actual NES in another thread... here:
viewtopic.php?p=44255#p44255


Specifically there are 3 filters:

1 lowpass:
out[i]=(in[i]-out[i-1])*0.815686

and 2 highpass:
out[i]=out[i-1]*0.996039+in[i]-in[i-1]
out[i]=out[i-1]*0.999835+in[i]-in[i-1]


(note the 0.8... and 0.99... numbers are balanced for 44100 Hz audio output and will need adjusting for different samplerates)

If the above isn't clear, I'll provide pseudocode for it when I get some free time. Right now I gotta run.



EDIT:


Pseudo-code:
Code:
// 'sample' is your output sample as generated by your APU
// 'output' is what you will actually output
//
// initialize all intermediate vars to 0.0

// low pass
LP_In = sample
LP_Out = (LP_In - LP_Out) * 0.815686


// high pass A
HPA_Out = HPA_Out*0.996039 + LP_Out - HPA_Prev
HPA_Prev = LP_Out

// high pass B
HPB_Out = HPB_Out*0.999835 + HPA_Out - HPB_Prev
HPB_Prev = HPA_Out


output = HPB_Out

// scale output to be within min/max bounds


Top
 Profile  
 
 Post subject: Re: Audio psuedo-code
PostPosted: Mon Jan 25, 2016 2:50 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
Argh... :?
At every triangle clock: output += sample[ phase++ ]
At every APU update: output -= output >> sft


Top
 Profile  
 
 Post subject: Re: Audio psuedo-code
PostPosted: Wed Jan 27, 2016 5:33 am 
Offline
User avatar

Joined: Sun Mar 19, 2006 3:06 am
Posts: 583
Location: Gothenburg/Sweden
Disch, I suspect there's something wrong the DMC psuedocode. All I get is zero-output..
I reach the
"sample_buffer = DMAReadFromCPU( addr )" part but it doesn't ever seems to reach "output".

_________________
http://nes.goondocks.se/


Top
 Profile  
 
 Post subject: Re: Audio psuedo-code
PostPosted: Wed Jan 27, 2016 9:24 am 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
The sample buffer is moved to the output unit in the 'clock DMC unit' section.... after the channel has received 8 clocks (one for each bit in the sample buffer). bits_in_output_unit should count down, and once it hits zero, sample buffer is moved into 'output_shift'.


One problem I can see is that if you are initializing bits_in_output_unit to zero, then it will go negative and that "bits_in_output_unit == 0" check would take REALLY long to catch because the var will have to loop all the way around. Maybe that should have been <= 0. Other than that I don't see any problems with the pseudo-code.


Top
 Profile  
 
 Post subject: Re: Audio psuedo-code
PostPosted: Wed Jan 27, 2016 11:57 am 
Offline
User avatar

Joined: Sun Mar 19, 2006 3:06 am
Posts: 583
Location: Gothenburg/Sweden
You're right. Initializing the bit to anything else bit zero did the trick, thanks. :)
I also discovered a length-problem with $4013 (it was playing too much). Changing it to:
lengthload = v<<3 + 1
instead of
lengthload = v<<4 + 1
worked better. I am not entirely sure why though... :)

_________________
http://nes.goondocks.se/


Top
 Profile  
 
 Post subject: Re: Audio psuedo-code
PostPosted: Wed Jan 27, 2016 2:09 pm 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
Hmm... no the length should definitely be << 4

See: http://wiki.nesdev.com/w/index.php/APU_DMC

Can you post your code?


EDIT:

Wait a minute....

+ has a higher precedent than <<.
So: val<<4 + 1 is being interpreted as val << (4+1)

So you'll need parenthesis here:

lengthload = (val << 4) + 1;


Top
 Profile  
 
 Post subject: Re: Audio psuedo-code
PostPosted: Thu Jan 28, 2016 12:39 am 
Offline
User avatar

Joined: Sun Mar 19, 2006 3:06 am
Posts: 583
Location: Gothenburg/Sweden
Ah, that did the trick obviously.

_________________
http://nes.goondocks.se/


Top
 Profile  
 
 Post subject: Re: Audio psuedo-code
PostPosted: Fri Feb 05, 2016 1:14 pm 
Offline
User avatar

Joined: Sun Mar 19, 2006 3:06 am
Posts: 583
Location: Gothenburg/Sweden
I suspect there might be something off with the triangle-lengthcounter. There are times when the triangle "wears off" too slowly. For example, the time counter on "Mario Bros" bonuslevels, it's almost a constant tone, it should be ticking, sort of.
Of course, it might be problems with my code. :) But there isn't that much code to check so and I haven't found anything that differs from your psuedocode (yet).

Other than that, other channels are working great! :)

_________________
http://nes.goondocks.se/


Top
 Profile  
 
 Post subject: Re: Audio psuedo-code
PostPosted: Sat Feb 06, 2016 5:20 am 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
oRBIT2002 wrote:
I suspect there might be something off with the triangle-lengthcounter. There are times when the triangle "wears off" too slowly. For example, the time counter on "Mario Bros" bonuslevels, it's almost a constant tone, it should be ticking, sort of.
Of course, it might be problems with my code. :) But there isn't that much code to check so and I haven't found anything that differs from your psuedocode (yet).

Other than that, other channels are working great! :)


Writes to $4003/$4007 should set the duty cycle to zero. Don't take the example code as "fully functional".


Last edited by Zepper on Sun Feb 07, 2016 9:43 am, edited 2 times in total.

Top
 Profile  
 
 Post subject: Re: Audio psuedo-code
PostPosted: Sat Feb 06, 2016 6:46 pm 
Offline
User avatar

Joined: Wed Nov 10, 2004 6:47 pm
Posts: 1845
Zepper wrote:
Writes to $4003/$4007 should set the lenght counter to zero. Don't take the example code as "fully functional".


???

AFAIK 4003/4007/400B sets the length counter to whatever value you specify -- and that is covered in the example code. If it set the length to zero, your channel would be silent all the time.


oRBIT2002 wrote:
I suspect there might be something off with the triangle-lengthcounter.


Tri is probably using the Linear counter, not the Length.
And the culprit is probably questionable Frame Counter timing.

Check to see if Mario Bros is writing to 4017 with the high bit set every frame. I suspect it is. Remember that such a write will clock audio subunits (like length/linear) immediately in addition to resetting the Frame Counter and changing the mode.


Top
 Profile  
 
 Post subject: Re: Audio psuedo-code
PostPosted: Sun Feb 07, 2016 9:42 am 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
Argh... :lol: :lol: The duty cycle is set to zero on $4003/$4007 writes. :? :?


Top
 Profile  
 
 Post subject: Re: Audio psuedo-code
PostPosted: Sun Feb 07, 2016 12:34 pm 
Offline
User avatar

Joined: Sun Mar 19, 2006 3:06 am
Posts: 583
Location: Gothenburg/Sweden
I've changed a few things related to the APU Frame Counter but the triangle lengthproblem hasn't changed in the scenario with Mario Bros I explained. Back to the drawingboard.

What's the purpose of the "frame interrupt flag"?

_________________
http://nes.goondocks.se/


Top
 Profile  
 
 Post subject: Re: Audio psuedo-code
PostPosted: Sun Feb 07, 2016 12:46 pm 
Online

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19111
Location: NE Indiana, USA (NTSC)
APU Frame IRQ isn't very useful in the NES. It's mostly for other applications of the 2A03, which may have no NMI source, to keep time.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 44 posts ]  Go to page Previous  1, 2, 3  Next

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