A Good DPCM Tutorial?

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

Post Reply
NEStegg
Posts: 10
Joined: Fri Jul 29, 2011 12:31 pm
Location: Seattle

A Good DPCM Tutorial?

Post by NEStegg »

Hello. I got most of my programming skills from Nerdy Nights. (http://nintendoage.com/forum/messagevie ... eadid=7155) However, in looking at the sound tutorials, I notice there is no DPCM tutorial.

Can anyone recommend a good DPCM tutorial, that would implement Nerdy Nights' logic? One of my ultimate goals is to build a DPCM-based speech engine similar to the one used in Big Bird's Hide and Speak (I don't know whether or not I will be able to implement it in a game I am designing, but it is worth experimenting with...).
User avatar
Dwedit
Posts: 4470
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Post by Dwedit »

Big Bird's hide and speak did not use DMC. It used a number of compressed audio samples. There was no speech snythesis there.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
NEStegg
Posts: 10
Joined: Fri Jul 29, 2011 12:31 pm
Location: Seattle

Post by NEStegg »

Dwedit wrote:Big Bird's hide and speak did not use DMC. It used a number of compressed audio samples. There was no speech snythesis there.
I thought the DPCM was a sample-playback system. I should have done more research, though. I was playing Hide & Speak on FCEUX and the voice's volume was controlled by the PCM slider, so that was the logic behind my initial assumption.
Shiru
Posts: 1161
Joined: Sat Jan 23, 2010 11:41 pm

Post by Shiru »

DMC channel has a DAC and a DMA-driven DPCM decoder. You can either use DPCM part to stream DPCM-encoded samples into the DAC, or just use the DAC directly, with well timed code - this allows to play unpacked samples or packed in other format than DPCM.
NEStegg
Posts: 10
Joined: Fri Jul 29, 2011 12:31 pm
Location: Seattle

Post by NEStegg »

Let me see if I got this straight--

So in Hide & Speak (and Sesame Street Countdown) the audio is just PCM--no "D."
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

It's compressed PCM, though not in the 1-bit DPCM format that the automatic playback expects. Any format other than DPCM needs pretty much 100% attention from the CPU, and very little animation is possible during playback. You can draw Big Bird's mouth flaps, or a scrolling picture of Rick Astley, but not much more.
User avatar
Dwedit
Posts: 4470
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Post by Dwedit »

The "Street Dance" pirate DDR game did a lot of stuff while playing back ADPCM, like simple animated sprites, changing scrolling offsets, game logic, etc.

Even though the game still sucks. There's very little relation between the music playback and the arrows you need to hit.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
Shiru
Posts: 1161
Joined: Sat Jan 23, 2010 11:41 pm

Post by Shiru »

Street Dance uses custom hardware for sample playback, so it could depack a packet of samples and then do other things while it plays through DMA.
User avatar
Memblers
Site Admin
Posts: 3901
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Post by Memblers »

I made a DPCM speech synth. I never really polished the program properly, or implemented saving/loading like I wanted, but you can check it out here.

If it would help, maybe I could post the full source code. Most of the source covers the editor and file format, the actual sound part is just an IRQ routine and a sample info table.

File format is pretty simple, each 2 bytes is either "sample speed, sample number" or "frame delay time, frame delay marker (3F)", and zero ends playback of the speech "string".

Version of the source with only the important parts:

Code: Select all


        lda #$C0  ; must to do this to use internal IRQ source
        sta $4017
        cli
        jmp main_loop


irq:
        pha
        txa
        pha
        tya
        pha

        lda speech_enable
        bne talk
temp_delay:
        lda #%00000000
        sta $4015
        beq endirq

talk:

        lda frame_delay
        bne temp_delay

        ldy #0
        lda (speech_lo),y
        beq stop_madness

        sty $4015

        tax
        ora #%10000000
        sta $4010

        iny
        lda (speech_lo),y
        cmp #$3F
        beq pause_madness

        asl
        tax

        lda sample_length_index,x
        sta $4013
        lda sample_addr_index,x
        sta $4012

        lda #%00010000
        sta $4015

before_end:

        inc16 speech_lo
        inc16 speech_lo

endirq:
        pla
        tay
        pla
        tax
        pla
	rti

stop_madness:
        sta speech_enable
        sta $4015
        beq endirq

pause_madness:
        stx frame_delay
        lda #0
        sta $4015
        jmp before_end

sample_addr_index:

         .word (voc00-$C000)/$40
         .word (voc01-$C000)/$40
         .word (voc02-$C000)/$40
         .word (voc03-$C000)/$40
         .word (voc04-$C000)/$40
         .word (voc05-$C000)/$40
         .word (voc06-$C000)/$40


sample_length_index:

        .word (voc01-voc00)/16  ; a
        .word (voc02-voc01)/16  ; ae
        .word (voc03-voc02)/16  ; aw
        .word (voc04-voc03)/16  ; ar
        .word (voc05-voc04)/16  ; e
        .word (voc06-voc05)/16  ; ee


.segment "SAMPLES"              ; $C000 - $FFF9

voc00:  .incbin "set1\a.dmc"
voc01:  .incbin "set1\ae.dmc"
voc02:  .incbin "set1\aw.dmc"
voc03:  .incbin "set1\ar.dmc"

One thing I would have done differently, is to use bankswitching so a higher sample-rate would fit. The 'nominal' DPCM sample rate I used was $C (where $F would be the maximum), so all the samples could fit into 16kB.
Post Reply