summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2013-05-21 16:51:23 -0400
committerMichael Sevakis <jethead71@rockbox.org>2013-05-21 16:59:58 -0400
commit1f76edabf9dca3b1cb25de77f6572a12370e35c4 (patch)
treeda912dd9a37468c6ed4ca6ca8e2bcbced037c47f
parentde86b4a3c5f6e2add2dc7588e6be37c8df2302f0 (diff)
downloadrockbox-1f76edabf9dca3b1cb25de77f6572a12370e35c4.tar.gz
rockbox-1f76edabf9dca3b1cb25de77f6572a12370e35c4.zip
SPC Codec: Need to restore a bit more data from cached waves.
'Nuff said. Last update wasn't quite right. Change-Id: I082a79c4e0c82b968fe2375cb82ee5c3a64a208b
-rw-r--r--lib/rbcodec/codecs/libspc/spc_codec.h21
-rw-r--r--lib/rbcodec/codecs/libspc/spc_dsp.c91
2 files changed, 53 insertions, 59 deletions
diff --git a/lib/rbcodec/codecs/libspc/spc_codec.h b/lib/rbcodec/codecs/libspc/spc_codec.h
index 9686694134..fad5a49916 100644
--- a/lib/rbcodec/codecs/libspc/spc_codec.h
+++ b/lib/rbcodec/codecs/libspc/spc_codec.h
@@ -272,18 +272,21 @@ enum state_t
272 state_release = 2 272 state_release = 2
273}; 273};
274 274
275enum { BRR_BLOCK_SIZE = 16 };
276
277#if SPC_BRRCACHE
275struct cache_entry_t 278struct cache_entry_t
276{ 279{
277 int16_t const* samples; 280 int16_t const* samples; /* decoded samples (cached) */
278 unsigned end; /* past-the-end position */ 281 unsigned end; /* past-the-end position (cached) */
279 unsigned loop; /* number of samples in loop */ 282 unsigned loop; /* number of samples in loop (cached) */
280 unsigned start_addr; 283 uint16_t start_addr; /* RAM start address */
284 uint16_t loop_addr; /* RAM loop address */
285 uint8_t block_header; /* final wave block header */
281}; 286};
282 287
283enum { BRR_BLOCK_SIZE = 16 };
284enum { BRR_CACHE_SIZE = 0x20000 + 32}; 288enum { BRR_CACHE_SIZE = 0x20000 + 32};
285 289
286#if SPC_BRRCACHE
287struct voice_wave_t 290struct voice_wave_t
288{ 291{
289 int16_t const* samples; /* decoded samples in cache */ 292 int16_t const* samples; /* decoded samples in cache */
@@ -291,7 +294,7 @@ struct voice_wave_t
291 long end; /* end position in samples buffer */ 294 long end; /* end position in samples buffer */
292 int loop; /* length of looping area */ 295 int loop; /* length of looping area */
293 unsigned block_header; /* header byte from current BRR block */ 296 unsigned block_header; /* header byte from current BRR block */
294 uint8_t const* addr; /* BRR waveform address in RAM */ 297 unsigned start_addr; /* BRR waveform address in RAM */
295 unsigned loop_addr; /* Loop address in RAM */ 298 unsigned loop_addr; /* Loop address in RAM */
296}; 299};
297#else /* !SPC_BRRCACHE */ 300#else /* !SPC_BRRCACHE */
@@ -300,7 +303,7 @@ struct voice_wave_t
300 int16_t samples [3 + BRR_BLOCK_SIZE + 1]; /* last decoded block */ 303 int16_t samples [3 + BRR_BLOCK_SIZE + 1]; /* last decoded block */
301 int32_t position; /* position in samples buffer, 12-bit frac */ 304 int32_t position; /* position in samples buffer, 12-bit frac */
302 unsigned block_header; /* header byte from current BRR block */ 305 unsigned block_header; /* header byte from current BRR block */
303 uint8_t const* addr; /* BRR waveform address in RAM */ 306 unsigned start_addr; /* BRR waveform address in RAM */
304}; 307};
305#endif /* SPC_BRRCACHE */ 308#endif /* SPC_BRRCACHE */
306 309
@@ -359,7 +362,7 @@ struct Spc_Dsp
359#endif /* !SPC_NOECHO */ 362#endif /* !SPC_NOECHO */
360 363
361#if SPC_BRRCACHE 364#if SPC_BRRCACHE
362 uint8_t oldsize; 365 unsigned oldsize;
363 struct cache_entry_t wave_entry [256]; 366 struct cache_entry_t wave_entry [256];
364 struct cache_entry_t wave_entry_old [256]; 367 struct cache_entry_t wave_entry_old [256];
365#endif 368#endif
diff --git a/lib/rbcodec/codecs/libspc/spc_dsp.c b/lib/rbcodec/codecs/libspc/spc_dsp.c
index 0df0ab04f7..6ad194aba6 100644
--- a/lib/rbcodec/codecs/libspc/spc_dsp.c
+++ b/lib/rbcodec/codecs/libspc/spc_dsp.c
@@ -154,15 +154,14 @@ void DSP_write( struct Spc_Dsp* this, int i, int data )
154 154
155/* Decode BRR block */ 155/* Decode BRR block */
156static inline void 156static inline void
157decode_brr_block( struct voice_t* voice, uint8_t const* addr, int16_t* out ) 157decode_brr_block( struct voice_t* voice, unsigned start_addr, int16_t* out )
158{ 158{
159 /* header */ 159 /* header */
160 unsigned block_header = *addr; 160 start_addr += 9; /* point to next header */
161 uint8_t const* addr = ram.ram + start_addr;
162 unsigned block_header = addr[-9];
161 voice->wave.block_header = block_header; 163 voice->wave.block_header = block_header;
162 164 voice->wave.start_addr = start_addr;
163 /* point to next header */
164 addr += 9;
165 voice->wave.addr = addr;
166 165
167 /* previous samples */ 166 /* previous samples */
168 int smp2 = out [0]; 167 int smp2 = out [0];
@@ -318,20 +317,15 @@ brr_decode_cache( struct Spc_Dsp* this, struct src_dir const* sd,
318 /* a little extra for samples that go past end */ 317 /* a little extra for samples that go past end */
319 static int16_t BRRcache [BRR_CACHE_SIZE] CACHEALIGN_ATTR; 318 static int16_t BRRcache [BRR_CACHE_SIZE] CACHEALIGN_ATTR;
320 319
321 DEBUGF( "decode at %08x (wave #%d)\n", start_addr, waveform ); 320 DEBUGF( "decode at %04x (wave #%u)\n", start_addr, waveform );
322 321
323 struct cache_entry_t* const wave_entry = &this->wave_entry [waveform]; 322 struct cache_entry_t* const wave_entry = &this->wave_entry [waveform];
324
325 wave_entry->start_addr = start_addr; 323 wave_entry->start_addr = start_addr;
326 324
327 unsigned loop_addr = letoh16( sd [waveform].loop ); 325 unsigned const loop_addr = letoh16( sd [waveform].loop );
328 uint8_t const* const loop_ptr = ram.ram + loop_addr;
329
330 DEBUGF( "loop addr at %08x\n", (unsigned)loop_addr );
331
332 int16_t* loop_start = NULL; 326 int16_t* loop_start = NULL;
333 327
334 uint8_t const* addr = ram.ram + start_addr; 328 DEBUGF( "loop addr at %04x (wave #%u)\n", loop_addr, waveform );
335 329
336 int16_t* out = BRRcache + start_addr * 2; 330 int16_t* out = BRRcache + start_addr * 2;
337 wave_entry->samples = out; 331 wave_entry->samples = out;
@@ -350,35 +344,36 @@ brr_decode_cache( struct Spc_Dsp* this, struct src_dir const* sd,
350 344
351 do 345 do
352 { 346 {
353 if ( addr == loop_ptr ) 347 if ( start_addr == loop_addr )
354 { 348 {
355 loop_start = out; 349 loop_start = out;
356 DEBUGF( "loop found at %08lx (wave #%d)\n", 350 DEBUGF( "loop found at %04x (wave #%u)\n", start_addr, waveform );
357 (unsigned long)(addr - RAM), waveform );
358 } 351 }
359 352
360 /* output position - preincrement */ 353 /* output position - preincrement */
361 out += BRR_BLOCK_SIZE; 354 out += BRR_BLOCK_SIZE;
362 355
363 decode_brr_block( voice, addr, out ); 356 decode_brr_block( voice, start_addr, out );
364 357
365 block_header = voice->wave.block_header; 358 block_header = voice->wave.block_header;
366 addr = voice->wave.addr; 359 start_addr = voice->wave.start_addr;
367 360
368 /* if next block has end flag set, this block ends early */ 361 /* if next block has end flag set, this block ends early */
369 /* (verified) */ 362 /* (verified) */
370 if ( (block_header & 3) != 3 && (*addr & 3) == 1 ) 363 if ( (block_header & 3) != 3 && (start_addr[ram.ram] & 3) == 1 )
371 { 364 {
372 /* skip last 9 samples */ 365 /* skip last 9 samples */
373 DEBUGF( "block early end\n" ); 366 DEBUGF( "block early end (wave #%u)\n", waveform );
374 out -= 9; 367 out -= 9;
375 break; 368 break;
376 } 369 }
377 } 370 }
378 while ( !(block_header & 1) && addr < RAM + 0x10000 ); 371 while ( !(block_header & 1) && start_addr < 0x10000 );
379 372
380 wave_entry->end = (out - 1 - wave_entry->samples) << 12; 373 wave_entry->end = (out - 1 - wave_entry->samples) << 12;
381 wave_entry->loop = 0; 374 wave_entry->loop = 0;
375 wave_entry->loop_addr = 0;
376 wave_entry->block_header = block_header;
382 377
383 if ( (block_header & 2) ) 378 if ( (block_header & 2) )
384 { 379 {
@@ -399,10 +394,11 @@ brr_decode_cache( struct Spc_Dsp* this, struct src_dir const* sd,
399 next [BRR_BLOCK_SIZE + 1] = out [0]; 394 next [BRR_BLOCK_SIZE + 1] = out [0];
400 next [BRR_BLOCK_SIZE + 2] = out [1]; 395 next [BRR_BLOCK_SIZE + 2] = out [1];
401 } 396 }
397
398 wave_entry->loop_addr = loop_addr;
402 } 399 }
403 400
404 DEBUGF( "end at %08lx (wave #%d)\n", 401 DEBUGF( "end at %04x (wave #%u)\n\n", start_addr, waveform );
405 (unsigned long)(addr - RAM), waveform );
406 402
407 /* add to cache */ 403 /* add to cache */
408 this->wave_entry_old [this->oldsize++] = *wave_entry; 404 this->wave_entry_old [this->oldsize++] = *wave_entry;
@@ -416,15 +412,15 @@ brr_probe_cache( struct Spc_Dsp* this, unsigned start_addr,
416 if ( wave_entry->start_addr == start_addr ) 412 if ( wave_entry->start_addr == start_addr )
417 return true; 413 return true;
418 414
419 for ( int i = 0; i < this->oldsize; i++ ) 415 for ( unsigned i = 0; i < this->oldsize; i++ )
420 { 416 {
421 struct cache_entry_t* e = &this->wave_entry_old [i]; 417 struct cache_entry_t* e = &this->wave_entry_old [i];
422 418
423 if ( e->start_addr == start_addr ) 419 if ( e->start_addr == start_addr )
424 { 420 {
425#if 0 /* do NOT want to see all the key down stuff for cached waves */ 421#if 0 /* do NOT want to see all the key down stuff for cached waves */
426 DEBUGF( "found in wave_entry_old (oldsize=%d)\n", 422 DEBUGF( "found in wave_entry_old (oldsize=%u)\n",
427 this->oldsize ); 423 this->oldsize );
428#endif 424#endif
429 *wave_entry = *e; 425 *wave_entry = *e;
430 return true; /* Wave in cache */ 426 return true; /* Wave in cache */
@@ -458,11 +454,13 @@ brr_key_on( struct Spc_Dsp* this, struct src_dir const* sd,
458 initial_point ); 454 initial_point );
459 } 455 }
460 456
461 voice->wave.position = 3 * 0x1000 - 1; /* 0x2fff */ 457 voice->wave.position = 3 * 0x1000 - 1; /* 0x2fff */
462 voice->wave.samples = wave_entry->samples; 458 voice->wave.samples = wave_entry->samples;
463 voice->wave.end = wave_entry->end; 459 voice->wave.end = wave_entry->end;
464 voice->wave.loop = wave_entry->loop; 460 voice->wave.loop = wave_entry->loop;
465 voice->wave.loop_addr = letoh16( sd [waveform].loop ); 461 voice->wave.start_addr = wave_entry->start_addr;
462 voice->wave.loop_addr = wave_entry->loop_addr;
463 voice->wave.block_header = wave_entry->block_header;
466} 464}
467 465
468static inline int brr_decode( struct Spc_Dsp* this, struct src_dir const* sd, 466static inline int brr_decode( struct Spc_Dsp* this, struct src_dir const* sd,
@@ -496,7 +494,7 @@ brr_key_on( struct Spc_Dsp* this, struct src_dir const* sd,
496 struct voice_t* voice, struct raw_voice_t const* raw_voice, 494 struct voice_t* voice, struct raw_voice_t const* raw_voice,
497 unsigned start_addr ) 495 unsigned start_addr )
498{ 496{
499 voice->wave.addr = ram.ram + letoh16( sd [raw_voice->waveform].start ); 497 voice->wave.start_addr = letoh16( sd [raw_voice->waveform].start );
500 /* BRR filter uses previous samples */ 498 /* BRR filter uses previous samples */
501 voice->wave.samples [BRR_BLOCK_SIZE + 1] = 0; 499 voice->wave.samples [BRR_BLOCK_SIZE + 1] = 0;
502 voice->wave.samples [BRR_BLOCK_SIZE + 2] = 0; 500 voice->wave.samples [BRR_BLOCK_SIZE + 2] = 0;
@@ -510,23 +508,15 @@ static inline int brr_decode( struct Spc_Dsp* this, struct src_dir const* sd,
510 struct voice_t* voice, 508 struct voice_t* voice,
511 struct raw_voice_t const* raw_voice ) 509 struct raw_voice_t const* raw_voice )
512{ 510{
513 #undef RAM
514#if defined(CPU_ARM) && !SPC_BRRCACHE
515 uint8_t* const ram_ = ram.ram;
516 #define RAM ram_
517#else
518 #define RAM ram.ram
519#endif
520
521 if ( voice->wave.position < BRR_BLOCK_SIZE * 0x1000 ) 511 if ( voice->wave.position < BRR_BLOCK_SIZE * 0x1000 )
522 return 0; 512 return 0;
523 513
524 voice->wave.position -= BRR_BLOCK_SIZE * 0x1000; 514 voice->wave.position -= BRR_BLOCK_SIZE * 0x1000;
525 515
526 uint8_t const* addr = voice->wave.addr; 516 unsigned start_addr = voice->wave.start_addr;
527 517
528 if ( addr >= RAM + 0x10000 ) 518 if ( start_addr >= 0x10000 )
529 addr -= 0x10000; 519 start_addr -= 0x10000;
530 520
531 unsigned block_header = voice->wave.block_header; 521 unsigned block_header = voice->wave.block_header;
532 522
@@ -535,7 +525,7 @@ static inline int brr_decode( struct Spc_Dsp* this, struct src_dir const* sd,
535 525
536 if ( block_header & 1 ) 526 if ( block_header & 1 )
537 { 527 {
538 addr = RAM + letoh16( sd [raw_voice->waveform].loop ); 528 start_addr = letoh16( sd [raw_voice->waveform].loop );
539 dec = 1; 529 dec = 1;
540 530
541 if ( !(block_header & 2) ) /* 1% of the time */ 531 if ( !(block_header & 2) ) /* 1% of the time */
@@ -546,7 +536,8 @@ static inline int brr_decode( struct Spc_Dsp* this, struct src_dir const* sd,
546 } 536 }
547 } 537 }
548 538
549 decode_brr_block( voice, addr, &voice->wave.samples [1 + BRR_BLOCK_SIZE] ); 539 decode_brr_block( voice, start_addr,
540 &voice->wave.samples [1 + BRR_BLOCK_SIZE] );
550 541
551 return dec; 542 return dec;
552 (void)this; 543 (void)this;
@@ -956,13 +947,13 @@ void DSP_reset( struct Spc_Dsp* this )
956 { 947 {
957 struct voice_t* v = this->voice_state + i; 948 struct voice_t* v = this->voice_state + i;
958 v->env_mode = state_release; 949 v->env_mode = state_release;
959 v->wave.addr = ram.ram; 950 v->wave.start_addr = 0;
960 } 951 }
961 952
962#if SPC_BRRCACHE 953#if SPC_BRRCACHE
963 this->oldsize = 0; 954 this->oldsize = 0;
964 for ( int i = 0; i < 256; i++ ) 955 for ( int i = 0; i < 256; i++ )
965 this->wave_entry [i].start_addr = -1; 956 this->wave_entry [i].start_addr = 0xffff;
966#endif /* SPC_BRRCACHE */ 957#endif /* SPC_BRRCACHE */
967 958
968#if !SPC_NOECHO 959#if !SPC_NOECHO