summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libspc/spc_codec.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libspc/spc_codec.h')
-rw-r--r--lib/rbcodec/codecs/libspc/spc_codec.h147
1 files changed, 61 insertions, 86 deletions
diff --git a/lib/rbcodec/codecs/libspc/spc_codec.h b/lib/rbcodec/codecs/libspc/spc_codec.h
index 7f6b6e2e9f..a8eee6bfef 100644
--- a/lib/rbcodec/codecs/libspc/spc_codec.h
+++ b/lib/rbcodec/codecs/libspc/spc_codec.h
@@ -213,7 +213,9 @@ struct cpu_ram_t
213#define RAM ram.ram 213#define RAM ram.ram
214extern struct cpu_ram_t ram; 214extern struct cpu_ram_t ram;
215 215
216long CPU_run( THIS, long start_time ) ICODE_ATTR_SPC; 216long CPU_run( THIS, long start_time )
217 ICODE_ATTR_SPC;
218
217void CPU_Init( THIS ); 219void CPU_Init( THIS );
218 220
219/* The DSP portion (awe!) */ 221/* The DSP portion (awe!) */
@@ -261,6 +263,7 @@ struct globals_t
261 char unused9 [2]; 263 char unused9 [2];
262}; 264};
263 265
266enum { ENV_RATE_INIT = 0x7800 };
264enum state_t 267enum state_t
265{ /* -1, 0, +1 allows more efficient if statements */ 268{ /* -1, 0, +1 allows more efficient if statements */
266 state_decay = -1, 269 state_decay = -1,
@@ -278,64 +281,61 @@ struct cache_entry_t
278}; 281};
279 282
280enum { BRR_BLOCK_SIZE = 16 }; 283enum { BRR_BLOCK_SIZE = 16 };
281enum { BRR_CACHE_SIZE = 0x20000 + 32} ; 284enum { BRR_CACHE_SIZE = 0x20000 + 32};
285
286#if SPC_BRRCACHE
287struct voice_wave_t
288{
289 int16_t const* samples; /* decoded samples in cache */
290 long position; /* position in samples buffer, 12-bit frac */
291 long end; /* end position in samples buffer */
292 int loop; /* length of looping area */
293 unsigned block_header; /* header byte from current BRR block */
294 uint8_t const* addr; /* BRR waveform address in RAM */
295};
296#else /* !SPC_BRRCACHE */
297struct voice_wave_t
298{
299 int16_t samples [3 + BRR_BLOCK_SIZE + 1]; /* last decoded block */
300 int32_t position; /* position in samples buffer, 12-bit frac */
301 unsigned block_header; /* header byte from current BRR block */
302 uint8_t const* addr; /* BRR waveform address in RAM */
303};
304#endif /* SPC_BRRCACHE */
282 305
283struct voice_t 306struct voice_t
284{ 307{
285#if SPC_BRRCACHE 308 struct voice_wave_t wave;
286 int16_t const* samples;
287 long wave_end;
288 int wave_loop;
289#else
290 int16_t samples [3 + BRR_BLOCK_SIZE + 1];
291 int block_header; /* header byte from current block */
292#endif
293 uint8_t const* addr;
294 short volume [2]; 309 short volume [2];
295 long position;/* position in samples buffer, with 12-bit fraction */
296 short envx; 310 short envx;
297 short env_mode; 311 short env_mode;
298 short env_timer; 312 short env_timer;
299 short key_on_delay; 313 short key_on_delay;
314 short rate;
300}; 315};
301 316
302#if SPC_BRRCACHE 317#if !SPC_NOECHO
303/* a little extra for samples that go past end */ 318enum { FIR_BUF_HALF = 8 };
304extern int16_t BRRcache [BRR_CACHE_SIZE];
305#endif 319#endif
306 320
307enum { FIR_BUF_HALF = 8 }; 321struct Spc_Dsp;
308 322
309#if defined(CPU_COLDFIRE) 323/* These must go before the definition of struct Spc_Dsp because a
310/* global because of the large aligment requirement for hardware masking - 324 definition of struct echo_filter is required. Only declarations
311 * L-R interleaved 16-bit samples for easy loading and mac.w use. 325 are created unless SPC_DSP_C is defined before including these. */
312 */ 326#if defined(CPU_ARM)
313enum
314{
315 FIR_BUF_CNT = FIR_BUF_HALF,
316 FIR_BUF_SIZE = FIR_BUF_CNT * sizeof ( int32_t ),
317 FIR_BUF_ALIGN = FIR_BUF_SIZE * 2,
318 FIR_BUF_MASK = ~((FIR_BUF_ALIGN / 2) | (sizeof ( int32_t ) - 1))
319};
320#elif defined (CPU_ARM)
321#if ARM_ARCH >= 6 327#if ARM_ARCH >= 6
322enum 328#include "cpu/spc_dsp_armv6.h"
323{
324 FIR_BUF_CNT = FIR_BUF_HALF * 2,
325 FIR_BUF_SIZE = FIR_BUF_CNT * sizeof ( int32_t ),
326 FIR_BUF_ALIGN = FIR_BUF_SIZE,
327 FIR_BUF_MASK = ~((FIR_BUF_ALIGN / 2) | (sizeof ( int32_t ) - 1))
328};
329#else 329#else
330enum 330#include "cpu/spc_dsp_armv4.h"
331{ 331#endif
332 FIR_BUF_CNT = FIR_BUF_HALF * 2 * 2, 332#elif defined (CPU_COLDFIRE)
333 FIR_BUF_SIZE = FIR_BUF_CNT * sizeof ( int32_t ), 333#include "cpu/spc_dsp_coldfire.h"
334 FIR_BUF_ALIGN = FIR_BUF_SIZE, 334#endif
335 FIR_BUF_MASK = ~((FIR_BUF_ALIGN / 2) | (sizeof ( int32_t ) * 2 - 1)) 335
336}; 336/* Above may still use generic implementations. Also defines final
337#endif /* ARM_ARCH */ 337 function names. */
338#endif /* CPU_* */ 338#include "spc_dsp_generic.h"
339 339
340struct Spc_Dsp 340struct Spc_Dsp
341{ 341{
@@ -347,47 +347,15 @@ struct Spc_Dsp
347 int16_t align; 347 int16_t align;
348 } r; 348 } r;
349 349
350 unsigned echo_pos;
351 int keys_down; 350 int keys_down;
352 int noise_count; 351 int noise_count;
353 uint16_t noise; /* also read as int16_t */ 352 uint16_t noise; /* also read as int16_t */
354
355#if defined(CPU_COLDFIRE)
356 /* FIR history is interleaved. Hardware handles wrapping by mask.
357 * |LR|LR|LR|LR|LR|LR|LR|LR| */
358 int32_t *fir_ptr;
359 /* wrapped address just behind current position -
360 allows mac.w to increment and mask fir_ptr */
361 int32_t *last_fir_ptr;
362 /* copy of echo FIR constants as int16_t for use with mac.w */
363 int16_t fir_coeff [VOICE_COUNT];
364#elif defined (CPU_ARM)
365 /* fir_buf [i + 8] == fir_buf [i], to avoid wrap checking in FIR code */
366 int32_t *fir_ptr;
367#if ARM_ARCH >= 6
368 /* FIR history is interleaved with guard to eliminate wrap checking
369 * when convolving.
370 * |LR|LR|LR|LR|LR|LR|LR|LR|--|--|--|--|--|--|--|--| */
371 /* copy of echo FIR constants as int16_t, loaded as int32 for
372 * halfword, packed multiples */
373 int16_t fir_coeff [VOICE_COUNT];
374#else
375 /* FIR history is interleaved with guard to eliminate wrap checking
376 * when convolving.
377 * |LL|RR|LL|RR|LL|RR|LL|RR|LL|RR|LL|RR|LL|RR|LL|RR|...
378 * |--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--| */
379 /* copy of echo FIR constants as int32_t, for faster access */
380 int32_t fir_coeff [VOICE_COUNT];
381#endif /* ARM_ARCH */
382#else /* Unoptimized CPU */
383 /* fir_buf [i + 8] == fir_buf [i], to avoid wrap checking in FIR code */
384 int fir_pos; /* (0 to 7) */
385 int fir_buf [FIR_BUF_HALF * 2] [2];
386 /* copy of echo FIR constants as int, for faster access */
387 int fir_coeff [VOICE_COUNT];
388#endif
389
390 struct voice_t voice_state [VOICE_COUNT]; 353 struct voice_t voice_state [VOICE_COUNT];
354
355#if !SPC_NOECHO
356 unsigned echo_pos;
357 struct echo_filter fir;
358#endif /* !SPC_NOECHO */
391 359
392#if SPC_BRRCACHE 360#if SPC_BRRCACHE
393 uint8_t oldsize; 361 uint8_t oldsize;
@@ -396,7 +364,9 @@ struct Spc_Dsp
396#endif 364#endif
397}; 365};
398 366
399void DSP_run_( struct Spc_Dsp* this, long count, int32_t* out_buf ) ICODE_ATTR_SPC; 367void DSP_run_( struct Spc_Dsp* this, long count, int32_t* out_buf )
368 ICODE_ATTR_SPC;
369
400void DSP_reset( struct Spc_Dsp* this ); 370void DSP_reset( struct Spc_Dsp* this );
401 371
402static inline void DSP_run( struct Spc_Dsp* this, long count, int32_t* out ) 372static inline void DSP_run( struct Spc_Dsp* this, long count, int32_t* out )
@@ -474,7 +444,8 @@ void SPC_Init( THIS );
474int SPC_load_spc( THIS, const void* data, long size ); 444int SPC_load_spc( THIS, const void* data, long size );
475 445
476/**************** DSP interaction ****************/ 446/**************** DSP interaction ****************/
477void DSP_write( struct Spc_Dsp* this, int i, int data ) ICODE_ATTR_SPC; 447void DSP_write( struct Spc_Dsp* this, int i, int data )
448 ICODE_ATTR_SPC;
478 449
479static inline int DSP_read( struct Spc_Dsp* this, int i ) 450static inline int DSP_read( struct Spc_Dsp* this, int i )
480{ 451{
@@ -482,10 +453,14 @@ static inline int DSP_read( struct Spc_Dsp* this, int i )
482 return this->r.reg [i]; 453 return this->r.reg [i];
483} 454}
484 455
485int SPC_read( THIS, unsigned addr, long const time ) ICODE_ATTR_SPC; 456int SPC_read( THIS, unsigned addr, long const time )
486void SPC_write( THIS, unsigned addr, int data, long const time ) ICODE_ATTR_SPC; 457 ICODE_ATTR_SPC;
458
459void SPC_write( THIS, unsigned addr, int data, long const time )
460 ICODE_ATTR_SPC;
487 461
488/**************** Sample generation ****************/ 462/**************** Sample generation ****************/
489int SPC_play( THIS, long count, int32_t* out ) ICODE_ATTR_SPC; 463int SPC_play( THIS, long count, int32_t* out )
464 ICODE_ATTR_SPC;
490 465
491#endif /* _SPC_CODEC_H_ */ 466#endif /* _SPC_CODEC_H_ */