This is the bug/patch tracker for Rockbox. Click here for more information.
Quick links: Bugs · Patches · Rockbox frontpage
FS#6542 - SPC Player
Attached to Project:
Rockbox
Opened by Adam Gashlin (AdamGashlin) - Monday, 15 January 2007, 11:57 GMT+2
Opened by Adam Gashlin (AdamGashlin) - Monday, 15 January 2007, 11:57 GMT+2
|
DetailsHere is a port of blargg's Game_Music_Emu SPC player (based partly on OpenSPC). It plays fast enough on my F40 Gigabeat, it also runs on my iPod photo but not full speed.
Very much unfinished. |
This task depends upon
Closed by Alexander Spyridakis (xaviergr)
Wednesday, 14 February 2007, 05:11 GMT+2
Reason for closing: Accepted
Wednesday, 14 February 2007, 05:11 GMT+2
Reason for closing: Accepted
Any ideas to make it faster on the targets with less processing power?
On my iPod photo a 1:55 track plays in 3:35 (53% speed) without any of these defined, and 2:24 (80% speed) with SPC_NOINTERP and SPC_NOECHO, and it still sounds reasonable. Still have to find a way to get a bit more speed...
The code is an absolute disaster with all the rearrangements necessary, but hooray!
Also now patches against the latest SVN, which now includes my NSF port (which could probably stand a lot of improvement, i'll have to see about getting blargg to help me fix that up...)
I've got some builds here:
http://hcs64.com/rockbox/spc.html
This happens if I try to play the second file from the Doom archive at snesmusic.org
Specifically, which "wave" is ending?
With repeat=1 current playtime is now fixed at 0.
I added some extra history to the BRR cache. Doom likes to fiddle around with the sample table (which is used to convert the sample index into a memory address) while running, which throws off the old cache. The new cache remembers the addresses of past samples independent of whether they've been purged from the sample table so the decoding now only needs to be done strictly once per sample per track. I don't see any reason why this would be incorrect (short of songs modifying the sample data in realtime, which I ignore the possibility of by providing a cache) and it allows Doom tracks to play full speed on iPod.
This part:
while (!ci->pcmbuf_insert((char *)samples, WAV_CHUNK_SIZE*2))
ci->yield();
Should now be:
ci->pcmbuf_insert(samples, NULL, WAV_CHUNK_SIZE/2)
ci->yield();
blargg has sent me some new code, but I haven't thoroughly tested it yet.
Haven't yet looked at what needs to be changed, but the failure's in ID3.H, I think it just relates to the codec number.
27 fixes the incompatibility with the Speex thing.
28 additionally renders in noninterleaved 24-bit, which I am told enables the DSP to process it more efficiently.
I was intending to run some speed tests to determine what kind of impact the 24-bit rendering (which just shifts over the old 16-bit samples) would have, but I didn't get around to any of the tests I wanted to do today.
Still not quite fast enough with echo, though we may have that assembly-optimized for coldfire soon, and blargg and I will be looking into improvements on ARM.
BTW: Have you looked at any of the FRACMUL stuff in dsp.c? That's available optimized for ARM too and is very convenient for handling volume and envelope mul-divs. I've used some of that already since gcc seems to produce faster code using it in some places instead of a large asm block.
I have not had a looked at FRACMUL, I will make a point of doing so.
I'm thinking hard about how to have some dynamic recompilation to ease the overhead of the CPU core. Might be possible to string assembly fragments together as it executes. And does all of the synth state have to be computed along with the output itself? The work is cut out for anyone doing anything on this. :)
This needs to be more modularized for sure...maybe put the code for each part into .c files?
BTW: What's your boost ratio on the iPods with Uncharted Waters 2?
I do have a lot of the state in IRAM already, the RAM and BRR cache won't fit but I think anything else is in IRAM or registers.
I'm doing a double check on the this pointer vs. globals on ColdFire with spc35.patch and then contribute some stuff...probably the interpolator and why not throw in the FRACMUL usage if that's ok. Things got changed around alot.
I also made a BRR cache that has a direct inverse lookup to eliminate looping to do cache lookups. Seemed to help too. Optimization in the decompression isn't that important since all samples will eventually be decompressed and cached and all lookups will hit if I understand correctly how it works. The SPC700 can have up to 256 samples in memory to look up?
Just change how the macros get defined at the top of spc_codec.h.
Assembly stuff will follow shortly after sleep.
So, yeah, here's my proposed patch for commital. Gonna run all the builds locally before sending it up.
uint32_t f = voice->position;
int32_t output = (int16_t)this->noise;
if ( (this->r.g.noise_enables & vbit) == 0 )
{
...
Can be:
int32_t output = (int16_t)this->noise;
if ( (this->r.g.noise_enables & vbit) == 0 )
{
uint32_t f = voice->position;
...