diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2013-05-18 01:45:03 -0400 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2013-05-21 00:02:14 -0400 |
commit | 87021f7c0ac4620eafd185ff11905ee643f72b6c (patch) | |
tree | 03ae48f3d999cd8743af40cc5df933f64f6df2d2 /lib/rbcodec/codecs/libspc/spc_codec.h | |
parent | a17d6de5bc727b0bb55764ecef2605ae689e8dab (diff) | |
download | rockbox-87021f7c0ac4620eafd185ff11905ee643f72b6c.tar.gz rockbox-87021f7c0ac4620eafd185ff11905ee643f72b6c.zip |
SPC Codec: Refactor for CPU and clean up some things.
CPU optimization gets its own files in which to fill-in optimizable
routines.
Some pointless #if 0's for profiling need removal. Those macros are
empty if not profiling.
Force some functions that are undesirable to be force-inlined by the
compiler to be not inlined.
Change-Id: Ia7b7e45380d7efb20c9b1a4d52e05db3ef6bbaab
Diffstat (limited to 'lib/rbcodec/codecs/libspc/spc_codec.h')
-rw-r--r-- | lib/rbcodec/codecs/libspc/spc_codec.h | 147 |
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 |
214 | extern struct cpu_ram_t ram; | 214 | extern struct cpu_ram_t ram; |
215 | 215 | ||
216 | long CPU_run( THIS, long start_time ) ICODE_ATTR_SPC; | 216 | long CPU_run( THIS, long start_time ) |
217 | ICODE_ATTR_SPC; | ||
218 | |||
217 | void CPU_Init( THIS ); | 219 | void 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 | ||
266 | enum { ENV_RATE_INIT = 0x7800 }; | ||
264 | enum state_t | 267 | enum 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 | ||
280 | enum { BRR_BLOCK_SIZE = 16 }; | 283 | enum { BRR_BLOCK_SIZE = 16 }; |
281 | enum { BRR_CACHE_SIZE = 0x20000 + 32} ; | 284 | enum { BRR_CACHE_SIZE = 0x20000 + 32}; |
285 | |||
286 | #if SPC_BRRCACHE | ||
287 | struct 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 */ | ||
297 | struct 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 | ||
283 | struct voice_t | 306 | struct 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 */ | 318 | enum { FIR_BUF_HALF = 8 }; |
304 | extern int16_t BRRcache [BRR_CACHE_SIZE]; | ||
305 | #endif | 319 | #endif |
306 | 320 | ||
307 | enum { FIR_BUF_HALF = 8 }; | 321 | struct 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) |
313 | enum | ||
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 |
322 | enum | 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 |
330 | enum | 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 | ||
340 | struct Spc_Dsp | 340 | struct 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 | ||
399 | void DSP_run_( struct Spc_Dsp* this, long count, int32_t* out_buf ) ICODE_ATTR_SPC; | 367 | void DSP_run_( struct Spc_Dsp* this, long count, int32_t* out_buf ) |
368 | ICODE_ATTR_SPC; | ||
369 | |||
400 | void DSP_reset( struct Spc_Dsp* this ); | 370 | void DSP_reset( struct Spc_Dsp* this ); |
401 | 371 | ||
402 | static inline void DSP_run( struct Spc_Dsp* this, long count, int32_t* out ) | 372 | static inline void DSP_run( struct Spc_Dsp* this, long count, int32_t* out ) |
@@ -474,7 +444,8 @@ void SPC_Init( THIS ); | |||
474 | int SPC_load_spc( THIS, const void* data, long size ); | 444 | int SPC_load_spc( THIS, const void* data, long size ); |
475 | 445 | ||
476 | /**************** DSP interaction ****************/ | 446 | /**************** DSP interaction ****************/ |
477 | void DSP_write( struct Spc_Dsp* this, int i, int data ) ICODE_ATTR_SPC; | 447 | void DSP_write( struct Spc_Dsp* this, int i, int data ) |
448 | ICODE_ATTR_SPC; | ||
478 | 449 | ||
479 | static inline int DSP_read( struct Spc_Dsp* this, int i ) | 450 | static 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 | ||
485 | int SPC_read( THIS, unsigned addr, long const time ) ICODE_ATTR_SPC; | 456 | int SPC_read( THIS, unsigned addr, long const time ) |
486 | void SPC_write( THIS, unsigned addr, int data, long const time ) ICODE_ATTR_SPC; | 457 | ICODE_ATTR_SPC; |
458 | |||
459 | void SPC_write( THIS, unsigned addr, int data, long const time ) | ||
460 | ICODE_ATTR_SPC; | ||
487 | 461 | ||
488 | /**************** Sample generation ****************/ | 462 | /**************** Sample generation ****************/ |
489 | int SPC_play( THIS, long count, int32_t* out ) ICODE_ATTR_SPC; | 463 | int SPC_play( THIS, long count, int32_t* out ) |
464 | ICODE_ATTR_SPC; | ||
490 | 465 | ||
491 | #endif /* _SPC_CODEC_H_ */ | 466 | #endif /* _SPC_CODEC_H_ */ |