It is currently Sat Nov 25, 2017 12:56 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: DMC confusion
PostPosted: Tue Feb 10, 2015 12:21 am 
Offline
User avatar

Joined: Sun Oct 12, 2014 11:06 am
Posts: 123
Location: Finland
I was just trying out DMC samples, but I'm a little confused on how they exactly work. The $4011 degister is the most confusing one, since some documents call it DMC Load, some call it DMC Raw and some call it DAC. Which one is correct and what is it actually used for? Next thing is that I don't know which one of the DMC registers activate the sample playback when you write to them. The last things are the sample address and length. How can you load a 16 bit sample address with a 8 bit value? Do I write it twice like in PPUScroll? An what if sample lenth is longer than what 8 bit values can handle? Do I have to play it as two individual samples or is there a way around this?

_________________
UP SIDE DOWN A B A B B A B A Hidari migi
L R L R STOP & DASH & UP & TALK Ijou nashi


Top
 Profile  
 
 Post subject: Re: DMC confusion
PostPosted: Tue Feb 10, 2015 1:36 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5842
Location: Canada
Playing a sample requires that you set the frequency ($4010), the sample address ($4012) and length ($4013) of the sample, then enabling the channel with $4015.

Your other specific questions should be answered here: http://wiki.nesdev.com/w/index.php/APU_DMC

If it's not clear from the wiki, ask again.


Top
 Profile  
 
 Post subject: Re: DMC confusion
PostPosted: Tue Feb 10, 2015 11:58 pm 
Offline

Joined: Sun Mar 03, 2013 1:52 am
Posts: 94
Location: Texas, USA
Here are some other documents:

Address and Length

  • APU says "DPCM samples must begin in the memory range $C000-FFFF at an address set by register $4012 (address = %11AAAAAA.AA000000). The length of the sample in bytes is set by register $4013 (length = %LLLL.LLLL0001)."
  • Blargg's NES APU Reference says "When the DMC sample is restarted, the address counter is set to register $4012 * $40 + $C000 and the bytes counter is set to register $4013 * $10 + 1."

I found Blargg's explaination easier to understand. In the wiki documents, be aware that % is sometimes used to prefix binary digits, like $ is used to prefix hexadecimal digits. And the . seems to just mark a byte boundary. Then you can see the % code is showing you how the bits you put in the register affect the resulting address and length values used.

$4011 register
Tsutarja wrote:
The $4011 degister is the most confusing one, since some documents call it DMC Load, some call it DMC Raw and some call it DAC. Which one is correct and what is it actually used for?

The various names all mean the same thing: The $4011 register sets the "current level" the DMC is outputting. (Most people didn't have an official Nintendo document to know the "official" name for the register, so different documents give it different names. When an official Nintendo document was found, the official APU register names were rather undescriptive, so it's unlikely anyone would use the official name.)

Here are some things this "direct load" register is used for:

    Changing the starting level of a sample

    As you may know, the sample format only lets you specify each point as "go up" or "go down", not at exact value. As the sample is played, if the level is too low to go down further, or too high to go up further, it will stay where it is. By using different starting levels before playing the sample, you might be able to get different variations of sound from the same sample.

    In Ikinari Musician, a sample with a general downward trend is used. When the starting level is set to higher values, this causes the sample to be audible slightly longer before it bottoms out and effectively becomes silent. Using the different starting levels produces different variations of a click sound from the same sample.

    Attachment:
    downward-sample.png
    downward-sample.png [ 1.71 KiB | Viewed 1350 times ]

    (P.S. In emulator FCEUX's lua scripting environment, register $4011 is called dmcseed, likely because it's used to set a seed or starting value for the sample.)

    Making sounds directly

    APU says "The $4011 register can be used to play PCM samples directly by setting the counter value at a high frequency. Because this requires intensive use of the CPU, when used in games all other gameplay is usually halted to facilitate this."

    That is, if you are able to load the "direct load" register at a fast enough rate, you can make sounds beyond the restrictions of the "go up" / "go down" sample format. You are in charge of the exact value of each point, but you have to spend a lot of time updating the register.

    Battletoads uses direct DMC loading for some percussion sounds. TMNTDEMO.NES plays the Teenage Mutant Ninja Turtles cartoon theme song using direct DMC loading. (In FCEUX, use SoundDisplay.lua and you can see the "DMC Seed" changing, but the note line doesn't flash because a sample is never started.)

    Triangle volume control (partial)

    APU says "Because of the APU's nonlinear mixing, a high value in the PCM counter reduces the volume of the triangle and noise channels. This is sometimes used to apply limited volume control to the triangle channel (e.g. Super Mario Bros. adjusts the counter between levels to accomplish this)."


Top
 Profile  
 
 Post subject: Re: DMC confusion
PostPosted: Wed Feb 11, 2015 6:11 am 
Offline
User avatar

Joined: Sun Oct 12, 2014 11:06 am
Posts: 123
Location: Finland
Thanks for the help.

One last thing is that what do I use to trigger the DMC sample playback? Does the APU check that I have at least written something to $4010, $4012 and $4013 and then play the sample, or do I have to write the DMC triggering somewhere else?

I remember seeing a RAM address in RECCA that quickly changes to 1 and then back to 0 when DMC is triggered. Is this just for the game to keep track that the sample has started, or is it used somehow else?

Lastly, how should I make the DMC tracks for the music? Should I have a counter that counts down from specified value and then once it hits 0, it will play the next sample? Also, should I start the counter from DMC trigger or end?

_________________
UP SIDE DOWN A B A B B A B A Hidari migi
L R L R STOP & DASH & UP & TALK Ijou nashi


Top
 Profile  
 
 Post subject: Re: DMC confusion
PostPosted: Wed Feb 11, 2015 8:15 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19259
Location: NE Indiana, USA (NTSC)
Tsutarja wrote:
Lastly, how should I make the DMC tracks for the music? Should I have a counter that counts down from specified value and then once it hits 0, it will play the next sample?

In your music engine, how do you tell when any other note starts?


Top
 Profile  
 
 Post subject: Re: DMC confusion
PostPosted: Wed Feb 11, 2015 10:14 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5842
Location: Canada
Tsutarja wrote:
One last thing is that what do I use to trigger the DMC sample playback? Does the APU check that I have at least written something to $4010, $4012 and $4013 and then play the sample, or do I have to write the DMC triggering somewhere else?

The frequency state ($4010) applies immediately. The sample address and length ($4012 and $4013) apply at the next sample start or loop.

To play a new sample, you use $4015. Typically you want to write to $4015 with the DMC bit clear first to stop any playing sample, then write a second time with the bit set to start the new sample.

Tsutarja wrote:
I remember seeing a RAM address in RECCA that quickly changes to 1 and then back to 0 when DMC is triggered. Is this just for the game to keep track that the sample has started, or is it used somehow else?

What any game does with any RAM address is entirely arbitrary, so there's no way for me to tell you anything about what that RAM byte means from just this description.

Tsutarja wrote:
Lastly, how should I make the DMC tracks for the music? Should I have a counter that counts down from specified value and then once it hits 0, it will play the next sample? Also, should I start the counter from DMC trigger or end?

The DMC maintains its own counter. You can read $4015 to check if the DMC bit is still on to see if the sample has finished. Are you trying to play a long stream of continuous sound through it? If you just want to stitch samples end to end, you might use the IRQ feature, possibly in combination with the looping state.


Top
 Profile  
 
 Post subject: Re: DMC confusion
PostPosted: Thu Mar 05, 2015 7:37 am 
Offline
User avatar

Joined: Sun Oct 12, 2014 11:06 am
Posts: 123
Location: Finland
Sorry for not getting back to this one sooner. I just finished my code that plays DMC samples when pressing 'A'. 'Left' and 'Right' Lets you choose a different sample. All the selections caused by button presses seems to be working, but the first time I play a sample I hear a 'pop' sound and after that nothing if I try again.

Here is whats in my main loop (and few lines before it):
Code:
 LDA #%00010000
 STA APUStatus

MainLoop:
 LDA joy_1_frame
 AND #%00000001
 CMP #%00000001
 BNE SkipA
 LDA #$01
 STA DMCTrigger

SkipA:
 LDA joy_1_frame
 AND #%01000000
 CMP #%01000000
 BNE SkipLeft
 LDA DMCSample
 SEC
 SBC #$01
 CMP #$FF
 BNE SkipUnderflow
 LDA #$00
SkipUnderflow:
 STA DMCSample

SkipLeft:
 LDA joy_1_frame
 AND #%10000000
 CMP #%10000000
 BNE SkipRight
 LDA DMCSample
 CLC
 ADC #$01
 CMP #$06
 BNE SkipOverflow
 LDA #$05
SkipOverflow:
 STA DMCSample

SkipRight:
 LDA #$01
 STA sleeping
MainSleep:
 LDX sleeping
 CPX #$00
 BNE MainSleep
 JMP MainLoop


Here is my DMC code (in NMI):
Code:
DMCPlay:
 LDX DMCTrigger
 CPX #$01
 BNE SkipDMC
 LDY DMCSample
 LDA DPCMFreq, y
 STA DMCFreq
 LDA DPCMLoad, y
 STA DMCLoad
 LDA DPCMAddr, y
 STA DMCAddr
 LDA DPCMLength, y
 STA DMCLength

 LDX #$00
 STX DMCTrigger

SkipDMC:
...


Here are the lookup tables:
Code:
DPCMFreq:
 .db $0F,$0F,$0F,$0F,$0F,$0F

DPCMLoad:
 .db $3C,$40,$40,$3C,$40,$30

DPCMAddr:
 .db $00,$24,$1E,$04,$11,$2C

DPCMLength:
 .db $10,$20,$18,$34,$34,$1C


And here is the .incbins:
Code:
 .bank 3
 .org $C000
 .incbin "Recca_$C000.dmc"
 .org $C100
 .incbin "Recca_$C100.dmc"
 .org $C440
 .incbin "Recca_$C440.dmc"
 .org $C780
 .incbin "Recca_$C780.dmc"
 .org $C900
 .incbin "Recca_$C900.dmc"
 .org $CB00
 .incbin "Recca_$CB00.dmc"


The samples and lookup table values are from Recca (didn't include the pitched down samples) to make it easier for me to at least get things working.

_________________
UP SIDE DOWN A B A B B A B A Hidari migi
L R L R STOP & DASH & UP & TALK Ijou nashi


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 1 guest


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