Today I got 16-bit
stereo 32 kHz uncompressed streaming to the SPC-700 working. It sets the echo buffer size to one sample, and disables echo write. This results in the DSP reading the stereo samples every 32 clocks and playing them. Then some timed S-SMP code copies the samples from the S-CPU to the echo buffer every 32 clocks.
The core S-SMP code uses word moves from the IO registers, and has the echo buffer at address 0 so it can use word writes as well. The lack of indexed writing is what allows this to stream 128 K/sec, well over the apparent maximum transfer rate detailed in another post.
Code:
; Stream samples from S-CPU
- movw ya,CPUIO0 ; 5 left
movw 0,ya ; 5
mov CPUIO3,#$80 ; 5 acknowledge
movw ya,CPUIO2 ; 5 right
mov CPUIO3,#0 ; 5 clear acknowledge
movw 2,ya ; 5
movw ya,CPUIO0 ; 5 left
movw 0,ya ; 5
mov CPUIO3,#$80 ; 5 acknowledge
movw ya,CPUIO2 ; 5 right
mov CPUIO3,#0 ; 5 clear acknowledge
movw 2,ya ; 5
bra - ; 4
Even though there seem to be no spare cycles, a couple can be squeezed out. You'll note that the acknowledgements back to the S-CPU change twice per sample. This simplifies the S-CPU synchronization code.
On the S-CPU side, writing samples is very easy:
Code:
; A,X,Y all 16 bits wide
loop:
; Wait for S-SMP to be ready for more samples
: bit APUIO2
bpl :-
; Write left and right samples. There's time
; to do some table lookups instead of having
; them pre-calculated in x and y.
nop
stx APUIO0
sty APUIO2
; Calculate next samples.
; 486 master clocks available to do so.
...
bra loop
Note how the synchronization merely waits for the small window in which the fourth I/O register is set to $80. I used this instead of a comparison with a counter, because that would have required more cycles on the S-CPU side. Better to make the S-SMP do a bit more work (write two acknowledgement values each sample) rather than the S-CPU.
I've been able to write a simple mono real-time FM synthesizer, but it doesn't have volume control as there's not enough time. I figured I'd post this in case anyone did have some actual samples worth outputting. The above code works perfectly, as I've tested it carefully with things like sine waves and various samples. I can put together a complete demo if anyone's interested.
So you found how to emulate NES $4011
I wonder how suitable this would be for speech synthesis. For this, you won't really need more than 8-bit mono at 8.0 or 10.7 kHz, so filling an entire page of the echo buffer might simplify the S-CPU side of it and allow game logic to run at the same time.
Even generating music will be tough. 128K/s is a lot of bandwidth. The entirety of SNES work RAM.
But if this can be dropped to a lower bit rate, say 16KHz 8-bit mono or stereo, then it could lead to something really impressive if an SA-1 coprocessor were used as a custom audio mixer. The quality gain would be in avoiding 4-bit ADPCM.
Or perhaps someone could make some really awesome synth music in the 486 clock window ...
The main challenge here was to reach the full rate of the SPC-700's DAC, to see whether it could even be done. Lower rates allow plenty of time for indexed addressing on the SMP side, and thus buffering, as tepples mentioned. Buffering is more efficient on the S-CPU side too, and allows other tasks like graphics at the same time.
Well this is clever, as always, Blarg. Congratulations on finding this method. I always wondered if the echo buffer could be used for streaming, it seems it does ! Echo can definitely turn into a 9th channel for the SPC somehow.
You can't do anything else, though, since it ties up the S-SMP. It's more of a curiosity, unless someone sticks an MPEG decoder in a cartridge and uses the SPC-700 as a roundabout DAC. Or maybe someone wants to stick a really high quality, short sample in his homebrew game and play it at the title screen. This just establishes that it can be done...
Using the audio mixing stereo pins on the cartridge connector would mix directly into the DAC, completely bypassing the need for S-CPU and S-SMP code. You could in fact end up using the S-SMP as a dedicated logic coprocessor.
But yes, showing that it's possible is truly awesome. A tech demo playing a song at 32KHz stereo with no ADPCM compression would be most cool. Just need a really great 48 second song. And then we can put to rest the arguments that the Genesis had a better sound chip once and for all :)
Haha, I like the idea of something to outdo the Genesis, as the latter only has something like an 8-bit DAC. Maybe someone can make a song that uses a few looped samples. It's definitely possible to layer a few. It needs to be something with some quiet passages, to show the dynamic range possible. It also must have some complex things that couldn't be synthesized with the DSP normally. Maybe something classical? Heh, it could start out with that FM synthesis I worked on, sounding like the Genesis, then meld into the sample, showing that it can do both.
I've got the perfect piece: Mozart's
Eine kleine Nachtmusik.
Finally, I finished a one-minute near-CD-quality demo for the SNES (2.9 MB download):
blargg_near_cd_quality.7z (
mirror).
Thanks to byuu for some assistance with the ROM access and testing. We found that it only plays properly on bsnes (or a SNES of course); the current SNES9x plays it much lower quality than it should. Put on headphones if possible, otherwise you can't really tell that it's 16-bit stereo.
Dynamic range is possible even with the existing ADPCM because the "A" is for Adaptive. This means the bitstream encodes the volume somehow, either explicitly (
number of shits in BRR on Super NES) or implicitly (10% decay per sample in IMA on Nintendo DS). I'm more interested in the real-time synthesis aspects.
Heh, that's exactly what I did here. I compressed the original 16-bit samples to 8-bit samples, with a shift count stored for each group of 15 samples. There's barely enough time to decompress it in real-time on the S-CPU. I only did this to allow double the time in a 4MB ROM. For real-time synthesis, it'd make more sense to do a buffered approach, which would be entirely different than this (and much lower than 128KB/sec transfer to the SPC-700). That would run at a lower rate, probably 16 kHz, 8-bit mono or something.
blargg wrote:
Finally, I finished a one-minute near-CD-quality demo for the SNES (2.9 MB download):
blargg_near_cd_quality.7z (
mirror).
Just tried this on the PowerPak. WOW!
Simply amazing. Great work, blargg.
Would anyone mind testing this on the Windows Snes9X v1.52 release under Windows XP? It seems to crackle and pop for me, but not for the Windows port author.
If it works cleanly there, then there's no reason not to use Snes9X instead for the lower system requirements.
Sounds very noisy for me with Snes9x 1.51 on XP.
I noticed that the DSP configuration I used wasn't as loud as it could be, and thus wasn't using the full DAC precision. Here's an updated one:
blargg_near_cd_quality2.7z (
mirror). I've also updated the link in the original message.
Before I had a single FIR constant of $3F (49%) and evol of $7F (99%). I had used the $3F because I was getting what sounded like overdriving when I was first developing the technique. I tried again yesterday and couldn't hear any of that, so I changed the FIR constant to $80 (-100%) and evol to $80 (-100%). Combined these give exactly 100%, i.e. no change in volume. There's no way to get +100%, so I used the two negatives to cancel each other out. This still technically only gives 15 bits per sample, due to the DSP always clearing the low bit during echo calculation, but there's no way around that.
It's truly amazing to hear such great quality music come from the SNES. Would it be possible to play a song longer than one minute? I realize the rom size would be significantly larger, but it could be done on the PowerPak provided it is less than 128Mbits. I realize 16MB is a lot of data for one song in particular, but it would be pretty cool to play a 3-5 minute song on the SNES. Maybe functionality for an MP3 player could be added to the PowerPak if blargg were able to colaborate with bunnyboy on the coding. A converter would need to be written for the PC to down sample songs so that they could be played back on the SNES. Just some thoughts.
Well decoding MP3 takes serious CPU resources that the SNES does not have. But it would be cool to have a utility to convert music to this ROM and use it on a PowerPak. Too bad it is limited by 128mbit. As far as I get it - it is not possible to use the CF card on the PowerPak directly (like a media player on a SNES) but everything that the SNES reads is first copied to the 128mbit RAM chip and then the SNES can read it. Maybe playtime can be optimized with a really simple lossless coding (should be less calculations than lossy)? Or maybe PowerPak developer has some nice tricks up his sleeve that could update the 128mbit RAM area while it is in use ... let's say it is split in half and when the first half is read the second is updated and the other way around? Well these are all fantastic ideas but ASM is way over my head to even start to think about this.
Oh and PowerPak has DSP-1, is it of any use for audio?
I actually use 2:1 compression for this demo ROM, using an 8-bit mantissa and 3-bit exponent (shared among groups of 15*2 samples). I'm told someone else has written a 4:1 ADPCM decompressor, which might be more appropriate if length is more important than quality.
Apparently you can make 12MB SNES ROMs, or even higher with custom chips. The PowerPak could certainly allow some kind of banked or streamed access to the entire CF card, for even greater capacities. I'm not sure what use it is besides a tech demo though.
Well imagine ... playing for many hours and then without moving going to The Dark Side of the Moon
blargg wrote:
I'm not sure what use it is besides a tech demo though.
It's a pretty nifty tech demo though. I now have it as the lone ROM in the root of my PowerPak (the games are all in directories).
Sounds like I need to release a version that can play uncompressed PCM, and perhaps the compressor or something. Sort of an extended ringtones for the SNES.
That would be awesome! SoX
http://sox.sourceforge.net/ could be used as a first step to downsample/change bit depth/format.
blargg wrote:
Sounds like I need to release a version that can play uncompressed PCM, and perhaps the compressor or something. Sort of an extended ringtones for the SNES.
At the risk of redundancy, that would be awesome (and ADPCM support would be even better).
i ,m glad to know that the snes is capable of true 16bit stereo 32khz sound.
But sadly no game had ever made full use of it.
this proves for once and for all that the snes sound is better then the megadrive & gba,despites the gba cpu is 32bit (wich could even decompress mp3 files on the fly while running a game),but it's dac's are just 8bit.
I,ve played this 1 minute sound demo on the powerpak, so if we will ever find a way of exceeding the 128mb limit of the powerpak by using a cluster chain file system trough an os update. It may be possible to take full advantage of the cf flashcard space to play for instance a 10 minute audio recording on it.
Note; exeeding the 512 kb limit on the nes powerpak has been barely proven trough a cluster chain format rom and the required update to achief this.
It does this by updating the 512KB space once needed.
Quote:
this proves for once and for all that the snes sound comes close to cd,it,s better then the gba
"Better" is subjective.
One might argue the GBA sound is "better" because the GBA has the CPU power to decompress recorded music in real time, at the same time as playing a game, using a more sophisticated codec than BRR.
What does 30 kbps GSM sound like?
I'm pretty sure the CD add-on would have used the audio in pins.
tepples wrote:
Quote:
this proves for once and for all that the snes sound comes close to cd,it,s better then the gba
"Better" is subjective.
- Surely it is.
Is interpolation bypassed when one uses the echo buffer to play samples ?
In that case : awesome
Your demo is unique in that not a single channel is apparantley used... on SNES9X, muting the channel does nothing to the sound.
While the snes is able to stream 16bit sound!!??,but that will eat all the availible ram inside the snes,so sadly l,despites the soundchip has it's own proccesor,theres no room for proccesing any game logic or FMV data.
Maybe if we reduce those samples down to 8bit,then there will be room for game data etc,,,
But if you want a game with non-stop near cd quality,you need to stick an external soundchip inside your homebrewed game.
While the sega genesis has 1 8bit dac,the Z80 can control it so there will be no hit in porfomance , the genesis also has a psg chip were you can trickery simulate 1bit pcm,so even digital stereo sound is also possible on the genesis(!).
Trough the snes can somehow interpolate or decompress those 4bit brr samples back to 16bit along with gaessian noise filtering etc,, all without taking a porfomance hit on the main cpu.
for the snes9x it does crackle and pop and sound really bad but go to
Sound > Playback Rate > 35KHz
or
Sound > Playback Rate > 48KHz
Those are the two that made it sound better.
wow this is awesome! sounded ok for me on snes9x with directsound.
just awesome!
blargg wrote:
I noticed that the DSP configuration I used wasn't as loud as it could be, and thus wasn't using the full DAC precision. Here's an updated one:
blargg_near_cd_quality2.7z (
mirror). I've also updated the link in the original message.
Before I had a single FIR constant of $3F (49%) and evol of $7F (99%). I had used the $3F because I was getting what sounded like overdriving when I was first developing the technique. I tried again yesterday and couldn't hear any of that, so I changed the FIR constant to $80 (-100%) and evol to $80 (-100%). Combined these give exactly 100%, i.e. no change in volume. There's no way to get +100%, so I used the two negatives to cancel each other out. This still technically only gives 15 bits per sample, due to the DSP always clearing the low bit during echo calculation, but there's no way around that.
Huh,what,are you saying that those streamed samples are not 16bit but 15bit? Are those ADPCM samples in snes titles also just only 15bit??
Well ,if the snes can only stream 15bit sound,then it makes no sense to put 2 16bit DAC's inside a snes,in this can as a snes fan,i will feel myself soooo misleaded after all these years being dissappointed,but maybe am wrong maybe it could still generate 16bit but maybe at only 22 or 11 khz.
I don't know,i hope i have it wrong,maybe 15bit was just a typo,but if this is not generating 16bit,then it should,ve been called 15bit.
But again,i suppose it should be able to generate 16bit audion,hence those 2 16bit dacs!!??
THX.
A 15-bit stereo DAC is still a heck of a lot better than the 8-bit mono DAC (plus hard-panned FM and PSG channels) on the Genesis.
BRR is 4-bit, but it has emphasis filters and volume companding (the "shift") to improve dynamic range. And in a practical composition, different channels mask other channels' noise to an extent. Remind me when I get home and I might make an example showing exactly how lossy BRR doesn't sound.
johannesmutlu wrote:
Huh,what,are you saying that those streamed samples are not 16bit but 15bit? Are those ADPCM samples in snes titles also just only 15bit??
Well ,if the snes can only stream 15bit sound,then it makes no sense to put 2 16bit DAC's inside a snes,in this can as a snes fan,i will feel myself soooo misleaded after all these years being dissappointed,but maybe am wrong maybe it could still generate 16bit but maybe at only 22 or 11 khz.
I don't know,i hope i have it wrong,maybe 15bit was just a typo,but if this is not generating 16bit,then it should,ve been called 15bit.
But again,i suppose it should be able to generate 16bit audion,hence those 2 16bit dacs!!??
THX.
If I understand things correctly, it's only the echo buffer that's effectively 15-bit. This streaming technique bypasses most of the DSP hardware (which is designed to play compressed samples, not to stream raw PCM) It's the audio equivalent of the DMA bitmap trick.
Sorry to re-float such an old thread, but I'm researching about SNES audio sub-system and its maximum usable bandwidth and watched a youtube video about this same blargg's ROM. I would like to have a look to the code, but both download links are broken.
Is there any other mirror where I can download the ROM?
Thanks!
I have the ROM (or at least its most recent version).
KungFuFurby wrote:
I have the ROM (or at least its most recent version).
Thanks!! I would like to do some test with audio programming in SNES, streaming samples to APU using HDMA... blargg's code for the SPC-700 could be useful because reduces at maximum acknowledge of samples in register $2140, so I can use HDMA without caring about SPC-700 getting the samples on time.