I was wondering whether or not to start this thread, but I decided that I must, because I just have no clue what I'm doing in this field. I've been interested in learning about the DMC channel, but everywhere I look leaves me with one question: "...What?"
I honestly don't know what the documents are talking about. But, I did look around in a few threads on this site that pointed me to a few programs, such as Tepple's program for converting WAV files to DMC files. So I recorded a sound, and turned it into a WAV file, and then converted it to a DMC file.
However, I don't know exactly what to do with this file. I tried to .incbin my file at a specific location; one that was a multiple of $40 + $C000 ($C400 to be exact). I don't know what it is, but I can't get it to play. The file is 7 KB. Is this even a valid file size? Doesn't the length counter only allow for around 4 KB ($FF * $10 + 1 = $FF1 = 4081)? Well, Perhaps someone could point me in the right direction by telling me how I can initiate this file with a small peice of sample code. With that, I could study the documents, and study the code, and possibly get some useful information out of it. If someone could do that for me, I'd be very very happy.
Celius wrote:
The file is 7 KB. Is this even a valid file size? Doesn't the length counter only allow for around 4 KB ($FF * $10 + 1 = $FF1 = 4081)?
You are correct. Your file is too long to play in its entirety. Shorten it by either shortening the wav you're converting, or using a lower frequency/quality setting when converting it.
Playing them is pretty simple:
Code:
LDA #$0F
STA $4010 ; set frequency ($0F is highest quality/pitch. Experiment with
; lower values, but beware that below $0A or so they get pretty slow)
LDA #$3F
STA $4011 ; set output to "center line". This step can possibly be skipped,
; but I'd recommend leaving it in... see notes at bottom)
LDA #$10
STA $4012 ; set address to $C400
LDA #$FF
STA $4013 ; set length to max ($FF1 bytes) -- lower this if you shrink your dmc sample.
LDA #$0F
STA $4015 ; stop DMC if it's currently playing
LDA #$1F
STA $4015 ; and restart it
That's all there is to it. Flipping on bit 4 of $4015 will start your sample. But note that only works if the DMC is not playing (which is why you stop it first by clearing that bit)
As far as the "center line" stuff goes -- if your wave extends too high or too low it will end up getting clipped which will distort the sound. Setting the center line to $3F or $40 keeps it right in the middle so there's the least chance of clipping occuring.
EDIT
I made this a while back so you can preview your DMC sample before dropping it in your program:
http://disch.arc-nova.org/dmcplayer.zip
Thank you very much Disch, you've pretty much answered my questions. And it turns out that it wasn't playing at first due to a completely unrelated reason. However, all of this information was very helpful. So pretty much anyone who's new to the DMC channel should be pointed to this thread. Does anyone think it would be a good idea to write a small document for those who want to learn about the DMC channel, but can't really understand what the docs are saying?
EDIT: By the way, very nice little program. I'll be using it quite frequently =).
Curious, has anyone ever tried converting an entire song & slapping it into a ROM?
atari2600a wrote:
Curious, has anyone ever tried converting an entire song & slapping it into a ROM?
I've done so. But
512 KiB for a <2 minute song is impractical. Better is to
do it without DPCM.
I'm just wondering how that would be possible, because can't you only stick DMC data in $C000-$FFFF? Is the ROM 1024k? I think I may have heard that before actually...
EDIT: No, actually, I had a different ROM that was 1024k, and it had a DMC file in it, and it was really really nice sound. I remember that it was when I wasn't even into NESdev yet, and I was so blown away by the quality and I didn't know how it was even possible to do such a thing.
you can stream raw PCM data to $4011 to produce your own sound wav. A few games do this (Battletoads comes to mind right away).
That is to say... you can output a 44.1 KHz wave (good quality) if you write to $4011 with a new sample 44100 times every second (spaced evenly, of course).
You're still limited to 7-bit mono samples though.
Celius wrote:
I'm just wondering how that would be possible, because can't you only stick DMC data in $C000-$FFFF?
MMC3 has two switchable banks. In one common configuration, one is placed at $C000-$DFFF and the other at $A000-$BFFF.
Quote:
EDIT: No, actually, I had a different ROM that was 1024k, and it had a DMC file in it, and it was really really nice sound. I remember that it was when I wasn't even into NESdev yet, and I was so blown away by the quality and I didn't know how it was even possible to do such a thing.
But why would someone waste that much NOR flash on one song? Sure it's possible, just like it's possible to hack a low-quality reproduction of
Sonic Adventure music into
Sonic the Hedgehog for Sega Genesis. But that doesn't make it desirable.
Disch wrote:
spaced evenly
This would be the hard part, if you are doing anything besides playing the samples. But I guess this would allow for some sort of audio compression, if the decompression engine was simple enough and everything was very well timed.
tepples wrote:
Sure it's possible, just like it's possible to hack a low-quality reproduction of Sonic Adventure music into Sonic the Hedgehog for Sega Genesis. But that doesn't make it desirable.
It does indeed sound like crap.
tokumaru wrote:
Disch wrote:
spaced evenly
This would be the hard part, if you are doing anything besides playing the samples. But I guess this would allow for some sort of audio compression, if the decompression engine was simple enough and everything was very well timed.
I believe that's called
Big Bird's Hide and Speak. I tried tracing through its audio decompression code. It has about eight "flavors" of compressed sample blocks; they take different amounts of time to decode so each byte just JSRs into a big NOP slide to kill time. Eventually, I said screw it, I'm just writing my own ADPCM playback engine.
So in other words, you'd have to update it every X scanlines, where X = (However many cycles are in a frame) * 60 / 44100. So you could do something with MMC3's scanline counter. That would be interesting. That seems like it would be really hard without a scanline counter. I have to admit, the DMC address byte is a really stupid concept. It would have caused way less problems if they just made it like $2005/$2006, where you can do two writes to it. It's actually kind of dissapointing to know that there isn't that much flexibility with it.
Celius wrote:
So in other words, you'd have to update it every X scanlines
Scanlines? I don't think any scanline counter will be able to help you there... 44100 is the number of samples in a second... since the NES runs at nearly 60 frames per second, that'd be 735 samples per frame, and that number is quite larger than the number of scanlines. I think you'd have to write a byte every 40 or so CPU cycles.
EDIT: In the formula you presented, X is the number of cycles, not scanlines, and it evaluates to 40 and some fraction of cycle.
Oh, yeah, oops. That just wouldn't work if it were scanlines. That would be terribly difficult to do every 40 cycles. Actually updating it could take more than 40 cycles (If you're doing math or something). Doesn't sound so worth it to me.
Celius wrote:
Doesn't sound so worth it to me.
The quality sure is better than DPCM, but not being able to do anything else sure is a pain in the ass.
Well, there must be some good use to it. We're talking about this in the thread that was split from this one.
tepples wrote:
tokumaru wrote:
Disch wrote:
spaced evenly
This would be the hard part, if you are doing anything besides playing the samples. But I guess this would allow for some sort of audio compression, if the decompression engine was simple enough and everything was very well timed.
I believe that's called
Big Bird's Hide and Speak. I tried tracing through its audio decompression code. It has about eight "flavors" of compressed sample blocks; they take different amounts of time to decode so each byte just JSRs into a big NOP slide to kill time. Eventually, I said screw it, I'm just writing my own ADPCM playback engine.
Wait, aren't you the member I was able to find a Wiki article on saying you where a fan of Sesame St.?
tepples wrote:
atari2600a wrote:
Curious, has anyone ever tried converting an entire song & slapping it into a ROM?
I've done so. But
512 KiB for a <2 minute song is impractical. Better is to
do it without DPCM.
I *finally* figured out what was wrong w/ FCEU on my linux distro so I finally got this working. Sounds decent, although it obvious why it sounds bad as it's trance/techno & therefore virtually depends on stereo effects...
Would you be willing to release the source to this? I have some mono-tastic oldskool (1930-ish to 60's) MP3's I'd like to try this out on...
I guess I will tell you my opinion about the DMC channel. You don't have to agreee, but I think this channel really, really suck. Any wav file converted to this format sounds absolutely terrible. Maybe the only game that made good use of it is Gradius II, wich has voices when you select "Speed Up", "Missile", "Laser", etc... Since those words are already written on the screen you know what the voice says, and since the music is playing quite loud you don't notice the terrible quality of the sound, so this sounds cool. Also the last boss says very slow "Speed Up Missile, etc.." when you reach it, and it looks like an weird scream.
Anyways, maybe some Bass Drum can sound decent on the DMC channel if used with other music to cover the hiss noise, but any other drums sounds terrible, not to mention melodic instruments. I'd stick with the noise channel to do drums, listen to Mega Man 6, it has awesome drum patters without any DMC, and maybe it's possible to do even better than this. Batman : Return of the Joker and some other Sunsoft games were able to play bass with DMC, that sounds allright, but it also sounds monotonous and boring, and you can perorm no effects such as slide, vibrato, and the sound is often detuned. Finally, Sunsoft used triangle for drums instead, so this didn't even add one voice, they should have redirected their bass on triangle, and make all drums with noise, this would have sounded better and taken much less space on the ROM.
So I really hate the DMC channel and I probably will never use it at all.
About the manual DMC channel I have nothing against it, but the fact doing anything freezes the CPU pretty much sets the facts. Maybe it could be used for Tales-of-Phantasia like voices, which may sound cool, and good since there wouldn't be this horrible hiss noise present on the automatic DMC channel.
Celius wrote:
I'm just wondering how that would be possible, because can't you only stick DMC data in $C000-$FFFF? Is the ROM 1024k? I think I may have heard that before actually...
Play more than one DMC sample back-to-back, bank switching your samples out. Also, the DMC can actually play samples from $8000-$FFFF, just the start address is limited to $C000-$FFC0 (it wraps from $FFFF to $8000).
Quote:
I have to admit, the DMC address byte is a really stupid concept. It would have caused way less problems if they just made it like $2005/$2006, where you can do two writes to it. It's actually kind of dissapointing to know that there isn't that much flexibility with it.
That'd require more bits in the counter. Having only 10 significant bits means they can just hard-wire the low bits of the address to 0, reducing the number of transistors.
I guess I wouldn't be able to have too many DMC samples in my games, because I usually just have the engine in $C000-$FFFF, and the game data in $8000-$BFFF. I obviously wouldn't want to bankswitch the engine out, that's like selling your car for gas money. Isn't there something where you can switch 8k at a time?
EDIT: Oh, and Bregalad, while the sound quality of the DMC channel may be low, there are some sounds that the NES just can't make without it. If you absolutely need someone screaming on a game or something, the DMC is the way to go in my mind.
And another question. Do you have to reset the start address every time you play a new sample? Because if you don't, that makes it a lot easier to play stuff from $8000-$BFFF.
Bregalad wrote:
Anyways, maybe some Bass Drum can sound decent on the DMC channel if used with other music to cover the hiss noise, but any other drums sounds terrible, not to mention melodic instruments.
The drums in Super Mario Bros. 3 sounded OK.
Celius wrote:
I guess I wouldn't be able to have too many DMC samples in my games, because I usually just have the engine in $C000-$FFFF, and the game data in $8000-$BFFF. I obviously wouldn't want to bankswitch the engine out, that's like selling your car for gas money. Isn't there something where you can switch 8k at a time?
Yeah. It's called MMC3, and SMB3 uses it.
Quote:
And another question. Do you have to reset the start address every time you play a new sample? Because if you don't, that makes it a lot easier to play stuff from $8000-$BFFF.
But if you play $FFC0 through $8xx1, you also get garbage from the vectors.
I think the drum in Mario 3 sounded great. I always use that as an example when trying to explain the DMC channel to people who don't know anything about the NES.
I was also thinking about playing $FFC0-$FFFF. You would get garbage from the vectors, but it wouldn't be that noticable, would it? It's just 6 bytes... I tried to start a little later in my sample by making the start address higher by #$40, and you could barely even tell the difference. So I don't think 6 bytes would be that noticable. I could be wrong though.
I'd prefer have a scream made with a square wave that sounds fun that a laughable recorded scream that is made with DMC that sounds 2000% fuzzy and that will make people think "Am I supposed to be impressed by them making such a sound out of the NES ?".
And yes the drums in SMB 3 sounds almost decent, but they only play 2 notes that are detuned and that sounds horrible. I guess they chose a pitch that is a multiple of the frequency they converted to or something so that the conversion end up with better results. Anything I try to convert to DMC sounds just horrible. Exept for brown noise, wich is the only thing DMC can do. Kick drum is close enough to brown noise if it's a really short kick.
I think your problem is you're expecting the DMC to sound like the original wav. It's not going to.
The DMC has a sound all its own. The second you start comparing it to other (superior) mediums you're dooming your opinion of it.
Could a game specialized for a PowerPak pop some sample bytes (either Raw PCM or DPCM) off of extra files on the CF card and rewrite the PRG chip's space for samples every frame? If such a game could pop off enough bytes at a decent speed - and the PowerPak's file loading routines and its mapper don't interfere with too much of the CPU space, I think it could be plausible. But even then, it'd be tricky - but wouldn't be too impossible - to limit the programming structure of such a game to support the routines.
Disch wrote:
The DMC has a sound all its own. The second you start comparing it to other (superior) mediums you're dooming your opinion of it.
Yes, and what I say is that it's own unique sound sound crappy to me.
So instead of considering the DMC channel as an ability to play sample, you consider it as a channel that can output a customiseable stream of fuzzy junk that is supposed to be usefull to the programmer (maximal sarcasm) ?
Note that this remembers me an older debate about the sound of the Genesis, some said it sounded good in some case, and some said it sucked.
You must really hate the noise channel, then. =P
Actually, I have to say that I don't really care for the noise channel. It is what it is, and I guess I have to work with it, but I think it outputs really odd sounds, half of which I'll never use.
Bregalad wrote:
So instead of considering the DMC channel as an ability to play sample, you consider it as a channel that can output a customiseable stream of fuzzy junk that is supposed to be usefull to the programmer (maximal sarcasm) ?
That or just a timer that can replace the scanline timer on a mapper. A couple Codemasters games do this.
You are right tepples, that seems like the best sound the DMC can do (silent !). This is usefull if you want to "simulate" mapper IRQ by using a combination of DMC + sprite zero (I never tried this but it sounds easily doable).
And I didn't say anything against the noise channel, on the other way I promote it for faking drums instead of DMC, beacuse I prefer clean and easily customisable noise to crappy fuzzy loud stream. However, the noise channel on the gameboy doesn't sound half as good as on the NES for some reason.
I've read that the smoothest sound the DMC can play are triangle waves (so maybe you can say that triangle waves are the "best sound" the DMC can make) - even if a programmer really really hated how most DMC samples are of low quality, he/she could still just use the DMC as an extra triangle wave voice in the music.
I personally think that the DMC is best used as a sound enhancer - like to add texture to say, guitar solos or drums. Ninja Gaiden II, Tecmo Super Bowl, and Captain Tsubasa II usually combine noise with DMC well to create what are high quality drums IMO. I think there, the drums are mainly noise, but DMC is used to add texture and realism. As a bonus, the fuzzy noise from the DMC is practically gone.
In the second-form boss music from Hebereke/Ufouria, there's a guitar solo which uses the square channels and DMC at the same time - it sounds really nice and the DMC is needed for this solo, but you can't really hear the fuzzyness at all.
I don't think the DMC works well if its used for sound and music effects where only the DMC is used - this is why I personally don't like certain games' drums, like Klax and Skate or Die 2.
If I was to use the DMC, I'd make sure the other channels also play a part in the effect - like for a scream, I would play the recorded scream from the DMC, but I would also use one of the square wave channels to accompany the scream and try to drown out the fuzziness without drowning out the scream itself.
I didn't feel like starting a new thread for this, but I have a really newbie sound question.
I am messing around with some values for the square wave, and it says that you can make a lower sound with bit 2 of $4003. However, the lowest sound I can make without getting complete silence is by having these values in these registers:
lda #$FF
sta $4002
lda #$0B
sta $4003
In FamiTracker I've heard it go about an octave lower. If I put these values in:
lda #$00
sta $4002
lda #$0C
sta $4003
I get silence. Can someone explain why?
The sweep unit is silencing your channel. Write $08 to $4001.
EDIT
Also, you probably should've started a new thread. This has nothing to do with the DMC and splitting topics up into relative threads makes forum searching much easier.
As blargg says... "new threads don't cost anything"
Thank you, that helped a lot. I can now get it down to that low "A".
I know that starting a new thread doesn't hurt, but I feel kind of annoying when I do it. I guess that talking about something unrelated in a thread is more annoying though
.
IMO, Journey to Sillious has great music because the generic slap bass and don't forget about skate or die 2 the electric guitar sound like crap even though it uses PCM.
NotTheCommonDose wrote:
and don't forget about skate or die 2 the electric guitar sound like crap even though it uses PCM.
The guitar in SoD2 sounds like crap partly because they were trying to read the controller, animate the palette, and run the other channels at the same time as playing PCM.
The Legend of Zelda makes sparing but effective use of the DMC channel for a few samples (shooting sword, door closing in dungeon, boss "breathing" sound, Link getting hurt). Other systems at that time didn't have anything that could compare. Since the Famicom came out in 1983, even including any kind of sample playback was probably novel.
If you're going to mention "Famicom" and "Legend of Zelda" in the same post, remember that the Famicom version of Zelda was on the Famicom Disk System*, and as such, got FDS sound. It's the NES that got DMC samples.
*(until its much much later cartridge re-release)
You're saying that the Famicom didn't have two square channels, triangle, noise, and DMC?!? I thought it used the 2A03 and had these from the start.
I read the assertion as follows: The Famicom has DMC, but Zeruda no Densetsu for FDS did not use it.
Yes, but I think Zelda FDS uses FDS sounds and doesn't use DMC for the stuff you mentionned.
I remember a C64 game called "Space Taxi" that was able to reproduce (terrible) speech only with square waves, by changing the frequency very quickly I guess. You did have to bring clients who hurls "Hey taxi", "Pad 1 please", Pad 2 please" and so on trough the old C64 SID soundchip, wich doesn't feature any DMC or anything.
Can sounds fro mthe original pitfall be put on the NES?
Pitfall originated on the 2600 right? If my memory holds correctly the 2600's Stella had only 2 square wave channels, each w/ it's own frequency (however horridly off) & volume registers. I can guarantee it'd be easier to use the square wave channels than anything DMC can produce.
The 2600 has 2 channels? It sounds like it only has one. It kind of reminds me of when you make sounds in QBasic, where your computer makes the sound instead of your speakers, and you can only do one tone at a time.
But yes, you would want to use something other than the DMC to do atari sounds. I would actually suggest the Triangle channel, or the Square Wave channels on Duty Cycle 2.
Listen to Ms. Pacman's opening sound. But think about it, would 2 really offset tones really sound pleasant?
2600 has 2 channels, what I like about them is that they have this crazy-ass distortion setting (4-bit), one setting makes a square wave, the others range between noise and some combination of square + pseudo-random.
It's a shame the frequency range is horrible.
http://qotile.net/files/2600_music_guide.txt
DMC channel might do alright with some of them maybe, pulse channels would be pretty weak though for reproducing settings besides the square. The $4011 DAC would work good, of course.
Ms. Pacman's intro song sounds like it could be easily replicated with the square waves. There are some really wierd sounds on 2600 games that could also be simulated with the noise channel.
Trivia of the Day: Most of SMB2's DMC samples (Birdo hit, doors opening, etc.) are merely recordings of the original Doki Doki Panic FDS sounds.
[insert "The More You Know" logo here]
Same goes with Zelda (US/PAL) DPCM sound effects.
BMF54123 wrote:
Trivia of the Day: Most of SMB2's DMC samples (Birdo hit, doors opening, etc.) are merely recordings of the original Doki Doki Panic FDS sounds.
[insert "The More You Know" logo here]
Wow, that strikes me as more than surprised. How did you find that out?
Celius wrote:
EDIT: No, actually, I had a different ROM that was 1024k, and it had a DMC file in it, and it was really really nice sound. I remember that it was when I wasn't even into NESdev yet, and I was so blown away by the quality and I didn't know how it was even possible to do such a thing.
So yeah, I found what I was talking about in that post. It's some song spanned across multiple banks, I think it's about 2 minutes.
http://www.freewebs.com/the_bott/pcm.nes
I remember about that one. Of course playing a sample into $4011 is easy as long as it's not compressed and if the CPU does absolutely nothing during that time.
atari2600a wrote:
Curious, has anyone ever tried converting an entire song & slapping it into a ROM?
I've seen a PD ROM like this but the song was bleh.
BMF54123 wrote:
Trivia of the Day: Most of SMB2's DMC samples (Birdo hit, doors opening, etc.) are merely recordings of the original Doki Doki Panic FDS sounds.
[insert "The More You Know" logo here]
Yeah, I've learned that when I played Zelda & Doki. Very simular.
Bregalad wrote:
I remember about that one. Of course playing a sample into $4011 is easy as long as it's not compressed and if the CPU does absolutely nothing during that time.
If I gave you a song could you make me a .NES rom out of it or can you make a program for that? It would be so
if you did!
You should probably learn how to do that yourself. I would really like to see my game idea up and running, so I have to make it. So if you'd like to see a song sample of yours playing, I'd suggest making it yourself, because a lot of the people on this board don't have time to do their projects as well as someone else's.
It's basically as simple as something like this :
Code:
.org $8000
include "MySong.raw"
PlayDMC:
ldy #$00
sty Pointer
lda #$80
sta Pointer+1
- nop
nop (as many NOP as you want in function of the frequency)
nop
lda [Pointer],Y
((add potential decompressioon algorithm, format converting and end of sample checks here))
sta $4011
iny
bne -
inc Pointer+1
bne -
etc....
"etc...."? what? and what do I use to compile this? 6502.exe NESHLA? I''m very confused.
NotTheCommonDose wrote:
If I gave you a song could you make me a .NES rom out of it or can you make a program for that?
I could probably expand my $4011 demo to work with longer samples, but I can't fit more than 2 minutes into a 512 KiB (max mmc1/mmc3 size) file unless I use tricks like only storing the chorus once.
I don't get what you mean now.
The common mappers have a 512 KiB limit on the size of a program. At this rate, I can't fit more than two minutes of telephone quality sound.
tepples wrote:
but I can't fit more than 2 minutes into a 512 KiB (max mmc1/mmc3 size) file
Store the samples in CHR-ROM!
Then you could go up to 768KB...
tokumaru wrote:
tepples wrote:
but I can't fit more than 2 minutes into a 512 KiB (max mmc1/mmc3 size) file
Store the samples in CHR-ROM!
Then you could go up to 768KB...
That'd be a bitch to do, even with a static display. Big Bird stored its shortest samples in unused parts of CHR, but I don't feel like tracing the code.
I've been wanting to experiment with using $4011 for sound samples for a while. I understand basically all you have to do is at (carefully) timed intervals, load and store a value into $4011. That's easy enough.
However, I'm a total newb when it comes to the way sound works in general. So the actual data that is stored in there, I have no idea how it works. I don't know what the values actually represent, and I just thought I'd ask: what do they mean?
Secondly, what should I do to go about making a store-it-into-$4011-friendly sound sample from an audio file?
Thanks so much in advance.
Celius wrote:
However, I'm a total newb when it comes to the way sound works in general. So the actual data that is stored in there, I have no idea how it works. I don't know what the values actually represent, and I just thought I'd ask: what do they mean?
Sound works in waves, length of the wave is the frequency. The timing that the sample changes with (your $4011 update rate) is the frequency (aka digital sample-rate). The values that you write to $4011 is the amplitude for each sample.
Quote:
Secondly, what should I do to go about making a store-it-into-$4011-friendly sound sample from an audio file?
Save it in an 8-bit unsigned format. Since $4011 is 7-bit, you could either reduce the volume by half on the whole sample beforehand, or do an LSR on-the-fly as you play each sample.
Celius wrote:
what do they mean?
The values are raw PCM data. Each value is a "photo" taken of a sound wave at a particular instant in time. With a series of values you can draw any sound wave you want, with 7 bits of precision.
WAV files are just like that, a series of "photos" of a sound wave taken at a certain frequency. You can easily convert information from WAV files into the raw values the NES expects, you just have to research the exact format of the numbers. You have to know if they are signed or not, that kind of thing.
This is a place with a few documents about the WAV format.
You'll have to see the frequency at which you'll be able to write the values on the NES, and you'll probably have to use a sound editor to convert the source WAV file to that frequency. Or you could just try to achieve the same frequency used by the original WAV file.
Thanks for the replies, guys.
So you have to convert a WAV file to a raw format (assuming you have a WAV file)?
Also, I understand that pitch is determined by frequency, and that if you play the sample faster, the pitch will be higher. But I still don't know how pitch is determined within the sample. All the values are "amplitudes", you say. Does that just mean they're like Y values for a "pixelated" (quantized?) sound wave? And also, are the values signed or unsigned?
Sorry for all the questions. Thanks again, guys for helping me.
The pitch is determined within a simple at which rate a waveform repeats. If you understand what a square wave is, how close to each other the edge are determines the frequency (or pitch). How height the wave is determine the amplitude (or volume).
WAV files can be made with more complex forms than square waves. With fourrier transform, everything can be decomposed into a sum of sine waves. The lowest freqency sine wave is the fundamental and determines the pitch of the sound. The higher frequency of sine waves are the harmonics and determine how the sound sounds. Note that some waves, such as white noise cannot be decomposed into sine waves because they are random, so this doesn't appy. That's why you don't hear any pitch when you hear white noise (or any other kind of "noise").
Celius wrote:
However, I'm a total newb when it comes to the way sound works in general.
Bores.com has a DSP tutorial that should help you understand.
Celius wrote:
Does that just mean they're like Y values for a "pixelated" (quantized?) sound wave?
That's pretty much it. The frequency in which these Y coordinates are updated is... well, the frequency.
I second your question: The 7 bits the NES expects should represent a signed value?
Values written to $4011 are not signed. $40 is center,[1] $00 is bottom, and $7F is top.
[1] Almost. The DAC is in fact slightly nonlinear, though not nearly as much as on the Game Gear.
So take these graphs of waves:
Code:
|
|
| xx xx xx xx x
|xxxxxxxxxxxxxx
|xxxxxxxxxxxxxx
|--------------
| x x x
| xxx xxx xxx
|xxxxxxxxxxxxxx
|xxxxxxxxxxxxxx
|xxxxxxxxxxxxxx
|--------------
All "x"s are 1 sample fetch wide, and the higher the number of x's stacked, the higher the number stored into $4011 is. Basically it's a bad graph. But the top one would make a higher, quieter sound, and the lower one would make a lower, louder sound, right?
Correct. The top one has a period (time between repeats) of 3 samples and an amplitude (half the distance between top and bottom) of 0.5. The bottom one has a period of 5 samples and an amplitude of 1.0.
Okay, I've got some samples working now by doing the lsr trick memblers mentioned. It was an 8-bit mono WAV file at 6 KHz. I'm not quite sure why it didn't work when I tried it last, but now it did.
I was hoping to make some use of this channel running at 60 Hz (hahaha). Yeah, probably not going to happen for anything but like a helicopter sound effect. It might be possible to play sounds clocked at really low speeds though (6000 Hz max if you plan on performing anything while playing samples, even if using an IRQ). For example, I wanted to have my character die in the game, and possibly let out a scream of some sort. Their body flies back, and the screen would scroll over a little while it plays the game over music. For that, I'd have to do a little game logic, and would probably want to play the sound with a scanline counter. And I would want to do that as little as possible, so the quality would have to be lowish...
Celius wrote:
I was hoping to make some use of this channel running at 60 Hz (hahaha). Yeah, probably not going to happen for anything but like a helicopter sound effect.
I just tried an S3M simulation of writing $7F, $3F, $1F, $00, at 60 Hz, and it made a sound that could be used as a passable kick drum.
Quote:
For example, I wanted to have my character die in the game, and possibly let out a scream of some sort. Their body flies back
You could try hardware DPCM playback instead. Otherwise, OAM DMA will cause a 512-cycle hiccup in your sample playback.
One thing you can do to save space is convert your samples into 4-bit and pack two samples to the byte. Plenty of commercial NES games did this with linear PCM (e.g. $8A $43 $67 $D6 in wav -> $84 $6D in rom -> $40 $20 $30 $68 in $4011) for a modest improvement over hardware DPCM quality especially in the treble. In
another topic, I explained a software ADPCM technique that brought still more improvement.
Yeah, from my tests, it actually made a few usable sounds, but nothing to use musically. They were all super low (well, being at 60 Hz, that's pretty inevitable), but for spells and maybe a drum like you said.
I hear that the DPCM "locks up" the CPU. Or am I wrong? Anyways, it's understandable how the quality is so low, with only +1 or -1 as your options with controlling the wave. Also, I can't compress the samples without somehow having RAM located where ROM usually is, which basically = no thanks. That's the one advantage to using PCM in $4011; you can compress the data (and also the quality is better).
Celius wrote:
I hear that the DPCM "locks up" the CPU.
It doesn't. It just steals a couple of cycles here and there and causes controller reading errors. It's $4011 that practically locks up the CPU, because using it requires so much time and precision that it's next to impossible to do anything else while using it.
Quote:
That's the one advantage to using PCM in $4011; you can compress the data (and also the quality is better).
Yeah, but it's next to impossible to use $4011 for sound while anything else is running. Like tepples mentioned, you'd have to take a 512-cycle break for the sprite DMA every frame, and that will make the sound weird. Also, in order to keep a constant frequency, there will be very little free CPU time for other operations between $4011 writes, considering that if you use mapper IRQs you'll not only have to decompress the sound samples but you'll also have to setup the next IRQ. Without IRQs it'd be impossible to run game logic, because you'd need timed code.
Unless you want to freeze the whole program while the character screams, which I think every player in the world will hate. I can't name any games right now, but I'm sure I've played games that froze everything when playing sound clips, and I always hated that.
I think the effect you guys are talking about is in Battletoads, but I feel it's done very well. It gives more of a feeling to the player of "Oh shit, I just got hit HARD!" It looks like everything stops for the sound, and it's not that long at all. I think it happens when you do a big hit to enemies too, actually. "OHHHH! I just knocked the CRAP out of that guy! Yeah!"
Man, I love that game : )
tokumaru wrote:
Unless you want to freeze the whole program while the character screams
Home Alone for Super NES did just that.
Quote:
I can't name any games right now, but I'm sure I've played games that froze everything when playing sound clips, and I always hated that.
A lot of games on U*ROM or S*ROM boards do that because they have more audio than will fit in $C000-$FFFF. I can immediately think of Blades of Steel, Bart vs. the Space Mutants, Big Bird's Hide and Speak, and SCAT.
I think it should be possible technically to do regular writes to $4011 while the main programm is doing something singificant, if the sample rate is low enough and if you don't mind some minor distortion at 60Hz.
It may just be insanely difficult to do a programm that stopp so many cycles to write to $4011, likely you would only do a few opperation, write to $4011, etc... and all of it would have to be timed right (altoug if the timing is not *very* exact it's not catastrophic, will just add some noise to the sound that will anyway not be exact). Also it would slow things down dratiscally because the CPU is used to write to $4011 and take a lot of ROM as all loops would have to be unrolled (writing regularly to $4011). In fact it sounds like a nice challenge to me. But I remember writing a programm that does matrix transormation and raster effects at the same time (second version of my Rotation demo) was really a pain.
Bregalad, my
4-channel wavetable player does that. It breaks operations into short blocks which each last exactly 21 cycles (using a short delay to use up cycles if the useful code is less than 21). Between each block is a call to the routine that updates $4011. If it were just playing a single sample without any rate adjustment, it each block could use a lot more than 21 cycles.
Gauntlet II plays decent PCM samples and uses sprite DMA in gameplay at the same time, using MMC3 IRQs to update $4011 every 3 scanlines. It seems to write to sprite DMA at every 5.333 frames (it does a pattern of 4, 8, 4), maybe to reduce distortion caused by the DMA write. However, forcing the game to update sprite DMA every frame doesn't cause any noticeable aliasing. This could be because the time for sprite DMA (about 4.5 scanlines) is close to the time per $4011 write (3 scanlines). I used Nestopia to record the same sound sample played with and without constant sprite DMA. The sample under constant sprite DMA was just 15% longer than the one without.
WWF King of the Ring also plays decent PCM samples during gameplay, using MMC3 IRQs to update $4011 every 2 scanlines, but it skips the VBlank period. But they still sound decent.
@blargg : Wow this sure should have been a headache to code.
If I were to do some PCM playing and some playengine at the same time, I'd definitely want to have the programm working completely without PCM (and keep a backup of it), then break everything in pieces of about 100 cycles and do that, altough it sounds really tedious if this is a complete game engine !!
Now if the NES would be able to play software mixed samples with $4011, play music with normal PSG channel and run a game engine at the same time, it would really have similar sound capabilities as the GBA ! However, the NES is slower, and have less IRQ sources
With an external microprocessor and IRQ source this should definitely be very possible and not even hard (squeedo comes to mind).
Bregalad wrote:
With an external microprocessor and IRQ source this should definitely be very possible and not even hard (squeedo comes to mind).
You mean something that interrupts the code, or something that works on its own and doesn't interrupt the game engine (is that even possible?)? Because it would be cool to have something that doesn't interrupt code, like MMC5's multiplier (though that requires writing and reading).
Well there is 3 ways it could be possible :
- An external on-cart CPU does the sound mixing and interrupts the main programm in the NES regularly with the IRQ pin to feed $4011 with music data.
- An external on-cart CPU does the game engine logic, while the CPU inside the NES is only used to deal with the PPU, APU and controller input, and does the sound mixing. Some way for communication between CPUs, likely using some interrupts, is achevied to keep everything in sync. That would probably be the most optimal solution but it would be somewhat revolutionary (you get NES dual-core !)
- No external on-cart CPU is used, and a normal mapper is used to fire interrupts regularly. The slow 6502 have to do everything, music logic, sound mixing AND game engine, and that while being inerrupted very frequently for $4011 updates so it can probably not do much even if working at 100%.
- Same as above but without even using interrupts for $4011 updates, would be completely a pain to write. However, if only one sample is played no mixing is needed and this could be possible, altough a headache (that's what I'm saying in my previous poses).
Quote:
I think the effect you guys are talking about is in Battletoads, but I feel it's done very well. It gives more of a feeling to the player of "Oh shit, I just got hit HARD!" It looks like everything stops for the sound, and it's not that long at all. I think it happens when you do a big hit to enemies too, actually. "OHHHH! I just knocked the CRAP out of that guy! Yeah!"
Man, I love that game : )
Don't we all? :P ...but I have to differ here and say that while the RAW PCM playback doesn't interfere with gameplay in single-player mode and even adds charm to it, it can be REALLY annoying in two-player mode because the other player (who isn't getting hit or beating the crap out of an enemy) is paused as well, without warning.
Then again, Battletoads is virtually impossible in two-player mode anyway. It's when I actually swallow my pride and equip the cart with a Game Genie, because you're lucky to even find someone who'll want to play it for any substantial amount of time even WITH infinite lives enabled. ;)
Bregalad wrote:
Well there is 3 ways it could be possible :
- An external on-cart CPU does the sound mixing and interrupts the main programm in the NES regularly with the IRQ pin to feed $4011 with music data.
- An external on-cart CPU does the game engine logic, while the CPU inside the NES is only used to deal with the PPU, APU and controller input, and does the sound mixing. Some way for communication between CPUs, likely using some interrupts, is achevied to keep everything in sync. That would probably be the most optimal solution but it would be somewhat revolutionary (you get NES dual-core !)
- No external on-cart CPU is used, and a normal mapper is used to fire interrupts regularly. The slow 6502 have to do everything, music logic, sound mixing AND game engine, and that while being inerrupted very frequently for $4011 updates so it can probably not do much even if working at 100%.
It would be awesome to have the second one! It would be awesome to have two programs running at once especially during Vblank! Then again, probably not because $2006 can't hold multiple values and you'd write to $2007 at the same time in both programs and it would be a disaster. But I don't really know how that works, so that might be garbage.
Having IRQs interrupting the code regularly would make everything super slow, because not only do you move on to the next sample every IRQ and store it in $4011, you have to back up the A, X, and Y registers. What a waste of cycles..
Who said anything about X and Y? To work around the air-gap in the expansion port needs about 22 cycles:
Code:
irqhandler:
pha
lda $4111 ; current mixer output
sta $4011
pla
rti
But a hardware mixer that outputs a DPCM stream on $FFC0 would still waste the NES CPU less (four cycles per eight samples), at the cost of slope overload.
tepples wrote:
Who said anything about X and Y? To work around the air-gap in the expansion port needs about 22 cycles:
Code:
irqhandler:
pha
lda $4111 ; current mixer output
sta $4011
pla
rti
But a hardware mixer that outputs a DPCM stream on $FFC0 would still waste the NES CPU less (four cycles per eight samples), at the cost of slope overload.
If the same mapper also saves A before an interrupt, you could load the mapper register that holds A instead of using PHA and PLA, saving 4 cycles but using up an extra byte of ROM.
If it also keeps track of the PC, then (assuming the CPU was running off of PRG-ROM) it could simply disable PRG-ROM, generate a jump, and then turn back on ROM instead of requesting an IRQ. And when it needs to return, it could do an indirect jump off a mapper register carrying the last PC. This would save 8 cycles without the interrupt timing and RTI, but use up two extra bytes of ROM.
strangenesfreak wrote:
If the same mapper also saves A before an interrupt
Registers A, X, and Y are internal to the CPU, and mappers can't see them until the CPU puts them on the data bus with the PHA, STA, STX, or STY instruction. The only way I can see that a mapper can "save" register A is by providing a single byte of RAM where the CPU can STA and LDA, and that would appear more complicated than just requiring the CPU to PHA/PLA.
Tracking PC also has a problem: how would the mapper distinguish between instruction and data fetches, or between 1-byte and 2-byte instructions, without including the 6502's entire instruction decoder?
tepples wrote:
Registers A, X, and Y are internal to the CPU, and mappers can't see them until the CPU puts them on the data bus with the PHA, STA, STX, or STY instruction. The only way I can see that a mapper can "save" register A is by providing a single byte of RAM where the CPU can STA and LDA, and that would appear more complicated than just requiring the CPU to PHA/PLA.
Tracking PC also has a problem: how would the mapper distinguish between instruction and data fetches, or between 1-byte and 2-byte instructions, without including the 6502's entire instruction decoder?
True. For saving the A register, I was thinking of the mapper watching LDA and other instructions that modify A, but that would cause bus conflicts in certain cases. I was indeed thinking of the mapper carrying an instruction encoder, which I guess could be just as or more complicated than the sound synthesis. Still, theoretically, it would be very nice if the mapper could help optimize code in PRG-ROM as much as possible.
Nothing that crazy would be needed !! It doesn't really make sense.
And I was talking about raw PCM mixing. DPCM just produce horrible sound ! I don't see how you could play anything meaningfull with it with real time mixing.
The ideal would have some mapper that would have an intergreated CPU, and some RAM that are dual ported to the internal CPU and the 6502. This RAM can handle $2006/$2007 updates for VBlank, can can hold the joypad data. Also, the sound code would set some varaibles in this piece of RAM to tell the NES CPU what to write to it's APU registers. On the other side, the NES CPU would also set some flags when it synchronizes with the PPU.
Celuis, it's effectively 2 programms runnign at the same time, but they do NOT acess to the same external ports, exept for a small area of dual-ported RAM. For example $5c00-$5fff could be dual ported RAM like on the MMC5.
The programm inside the NES (after the init) would be very small (probably 8kb) and could look like something like that :
Code:
RESET
sei
........ ;Some initilaisiation code
cli
- jmp -
NMI
bit $2002
lda #$00
sta $5xxx ;The mapper knowns we're in NMI
lda #$5c
sta $4014 ;SpriteDMA from external memory for simplicity
jsr Update20062007 ;Read some buffer from $5d00-$5fff
lda ScrollH
sta $2005
lda ScrollV ;Those variables reside somewhere at $5d00-$5fff
sta $2005
lda Nametable
sta $2000
lda #$01
sta $5xxx ;The mapper knowns we're at the end of the NMI
lda $5xxxx ;Update the PSG sound registers (could be done
sta $4000 ;a more sofisticated way)
lda $5xxx
sta $4001
etc....
rti
IRQ ;Interrupt every scanline ?
ldx SoundIndex
inc SoundIndex
lda $5xxxx,X ;256-byte ring buffer
sta $4011 ;Write PCM data
ldy RasterFlag,X ;This system allows to write to any of $2000-$2007 regs
beq + ;During the frame
- ldx RasterIndex,Y
lda RasterData,Y
sta $2000,X
dey
bne -
+ rti
And you don't even need dual-ported RAM, just interleaved access (as the SPC-700 does, where the CPU accesses it on the first cycle, and the DSP on the second and third).
So the game runs on a CPU inside the cart, and the NES just passes I/O through.
Where have I heard that before?
But imagine that we don't want to go that far. How much of a synthesizer or sample mixer could fit onto a CPLD? Or would one need an FPGA + level shifters for that?