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...).
A Good DPCM Tutorial?
Moderator: Moderators
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.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.
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.
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.
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!
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:
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.
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"