It is currently Fri Nov 17, 2017 12:38 pm

All times are UTC - 7 hours



Forum rules


Related:



Post new topic Reply to topic  [ 39 posts ]  Go to page 1, 2, 3  Next
Author Message
PostPosted: Fri Mar 05, 2010 5:43 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
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.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 05, 2010 5:48 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19220
Location: NE Indiana, USA (NTSC)
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.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 05, 2010 8:08 pm 
Offline

Joined: Mon Mar 27, 2006 5:23 pm
Posts: 1339
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 ...


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 05, 2010 8:36 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
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.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 06, 2010 1:46 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7265
Location: Chexbres, VD, Switzerland
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.

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 06, 2010 3:08 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
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...


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 06, 2010 9:53 pm 
Offline

Joined: Mon Mar 27, 2006 5:23 pm
Posts: 1339
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 :)


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 07, 2010 8:18 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
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.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 10, 2010 8:51 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
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.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 10, 2010 10:04 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19220
Location: NE Indiana, USA (NTSC)
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.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 10, 2010 11:38 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
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.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 10, 2010 11:51 am 
Offline

Joined: Fri Feb 20, 2009 10:07 am
Posts: 40
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! :shock: Simply amazing. Great work, blargg. :D


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 12, 2010 8:23 am 
Offline

Joined: Mon Mar 27, 2006 5:23 pm
Posts: 1339
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.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 12, 2010 9:03 am 
Offline

Joined: Thu Oct 05, 2006 6:29 am
Posts: 911
Sounds very noisy for me with Snes9x 1.51 on XP.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 12, 2010 11:10 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
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.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 39 posts ]  Go to page 1, 2, 3  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: LuigiBlood and 9 guests


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