blob: b297630b42383e9cd5b080e54a10b5b7b6e7571e [file] [log] [blame]
Adam Gashlinb73960d2007-02-14 03:34:55 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2006-2007 Adam Gashlin (hcs)
10 * Copyright (C) 2004-2007 Shay Green (blargg)
11 * Copyright (C) 2002 Brad Martin
12 *
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20
21/* The DSP portion (awe!) */
22
23enum { voice_count = 8 };
24enum { register_count = 128 };
25
26struct raw_voice_t
27{
28 int8_t volume [2];
29 uint8_t rate [2];
30 uint8_t waveform;
31 uint8_t adsr [2]; /* envelope rates for attack, decay, and sustain */
32 uint8_t gain; /* envelope gain (if not using ADSR) */
33 int8_t envx; /* current envelope level */
34 int8_t outx; /* current sample */
35 int8_t unused [6];
36};
37
38struct globals_t
39{
40 int8_t unused1 [12];
41 int8_t volume_0; /* 0C Main Volume Left (-.7) */
42 int8_t echo_feedback; /* 0D Echo Feedback (-.7) */
43 int8_t unused2 [14];
44 int8_t volume_1; /* 1C Main Volume Right (-.7) */
45 int8_t unused3 [15];
46 int8_t echo_volume_0; /* 2C Echo Volume Left (-.7) */
47 uint8_t pitch_mods; /* 2D Pitch Modulation on/off for each voice */
48 int8_t unused4 [14];
49 int8_t echo_volume_1; /* 3C Echo Volume Right (-.7) */
50 uint8_t noise_enables; /* 3D Noise output on/off for each voice */
51 int8_t unused5 [14];
52 uint8_t key_ons; /* 4C Key On for each voice */
53 uint8_t echo_ons; /* 4D Echo on/off for each voice */
54 int8_t unused6 [14];
55 uint8_t key_offs; /* 5C key off for each voice
56 (instantiates release mode) */
57 uint8_t wave_page; /* 5D source directory (wave table offsets) */
58 int8_t unused7 [14];
59 uint8_t flags; /* 6C flags and noise freq */
60 uint8_t echo_page; /* 6D */
61 int8_t unused8 [14];
62 uint8_t wave_ended; /* 7C */
63 uint8_t echo_delay; /* 7D ms >> 4 */
64 char unused9 [2];
65};
66
67enum state_t { /* -1, 0, +1 allows more efficient if statements */
68 state_decay = -1,
69 state_sustain = 0,
70 state_attack = +1,
71 state_release = 2
72};
73
74struct cache_entry_t
75{
76 int16_t const* samples;
77 unsigned end; /* past-the-end position */
78 unsigned loop; /* number of samples in loop */
79 unsigned start_addr;
80};
81
82enum { brr_block_size = 16 };
83
84struct voice_t
85{
86#if SPC_BRRCACHE
87 int16_t const* samples;
88 long wave_end;
89 int wave_loop;
90#else
91 int16_t samples [3 + brr_block_size + 1];
92 int block_header; /* header byte from current block */
93#endif
94 uint8_t const* addr;
95 short volume [2];
96 long position;/* position in samples buffer, with 12-bit fraction */
97 short envx;
98 short env_mode;
99 short env_timer;
100 short key_on_delay;
101};
102
103#if SPC_BRRCACHE
104/* a little extra for samples that go past end */
105static int16_t BRRcache [0x20000 + 32];
106#endif
107
108enum { fir_buf_half = 8 };
109
110struct Spc_Dsp
111{
112 union
113 {
114 struct raw_voice_t voice [voice_count];
115 uint8_t reg [register_count];
116 struct globals_t g;
117 int16_t align;
118 } r;
119
120 unsigned echo_pos;
121 int keys_down;
122 int noise_count;
123 uint16_t noise; /* also read as int16_t */
124
125 /* fir_buf [i + 8] == fir_buf [i], to avoid wrap checking in FIR code */
126 int fir_pos; /* (0 to 7) */
127 int fir_buf [fir_buf_half * 2] [2];
128 /* copy of echo FIR constants as int, for faster access */
129 int fir_coeff [voice_count];
130
131 struct voice_t voice_state [voice_count];
132
133#if SPC_BRRCACHE
134 uint8_t oldsize;
135 struct cache_entry_t wave_entry [256];
136 struct cache_entry_t wave_entry_old [256];
137#endif
138};
139
140struct src_dir
141{
142 char start [2];
143 char loop [2];
144};
145
146static void DSP_reset( struct Spc_Dsp* this )
147{
148 this->keys_down = 0;
149 this->echo_pos = 0;
150 this->noise_count = 0;
151 this->noise = 2;
152 this->fir_pos = 0;
153
154 this->r.g.flags = 0xE0; /* reset, mute, echo off */
155 this->r.g.key_ons = 0;
156
157 memset( this->voice_state, 0, sizeof this->voice_state );
158
159 int i;
160 for ( i = voice_count; --i >= 0; )
161 {
162 struct voice_t* v = this->voice_state + i;
163 v->env_mode = state_release;
164 v->addr = ram.ram;
165 }
166
167 #if SPC_BRRCACHE
168 this->oldsize = 0;
169 for ( i = 0; i < 256; i++ )
170 this->wave_entry [i].start_addr = -1;
171 #endif
172
173 memset( this->fir_buf, 0, sizeof this->fir_buf );
174 assert( offsetof (struct globals_t,unused9 [2]) == register_count );
175 assert( sizeof (this->r.voice) == register_count );
176}
177
178static void DSP_write( struct Spc_Dsp* this, int i, int data ) ICODE_ATTR;
179static void DSP_write( struct Spc_Dsp* this, int i, int data )
180{
181 assert( (unsigned) i < register_count );
182
183 this->r.reg [i] = data;
184 int high = i >> 4;
185 int low = i & 0x0F;
186 if ( low < 2 ) /* voice volumes */
187 {
188 int left = *(int8_t const*) &this->r.reg [i & ~1];
189 int right = *(int8_t const*) &this->r.reg [i | 1];
190 struct voice_t* v = this->voice_state + high;
191 v->volume [0] = left;
192 v->volume [1] = right;
193 }
194 else if ( low == 0x0F ) /* fir coefficients */
195 {
196 this->fir_coeff [7 - high] = (int8_t) data; /* sign-extend */
197 }
198}
199
200static inline int DSP_read( struct Spc_Dsp* this, int i )
201{
202 assert( (unsigned) i < register_count );
203 return this->r.reg [i];
204}
205
206/* if ( n < -32768 ) out = -32768; */
207/* if ( n > 32767 ) out = 32767; */
208#define CLAMP16( n, out )\
209{\
210 if ( (int16_t) n != n )\
211 out = 0x7FFF ^ (n >> 31);\
212}
213
214#if SPC_BRRCACHE
215static void decode_brr( struct Spc_Dsp* this, unsigned start_addr,
216 struct voice_t* voice,
217 struct raw_voice_t const* const raw_voice ) ICODE_ATTR;
218static void decode_brr( struct Spc_Dsp* this, unsigned start_addr,
219 struct voice_t* voice,
220 struct raw_voice_t const* const raw_voice )
221{
222 /* setup same variables as where decode_brr() is called from */
223 #undef RAM
224 #define RAM ram.ram
225 struct src_dir const* const sd =
226 (struct src_dir*) &RAM [this->r.g.wave_page * 0x100];
227 struct cache_entry_t* const wave_entry =
228 &this->wave_entry [raw_voice->waveform];
229
230 /* the following block can be put in place of the call to
231 decode_brr() below
232 */
233 {
234 DEBUGF( "decode at %08x (wave #%d)\n",
235 start_addr, raw_voice->waveform );
236
237 /* see if in cache */
238 int i;
239 for ( i = 0; i < this->oldsize; i++ )
240 {
241 struct cache_entry_t* e = &this->wave_entry_old [i];
242 if ( e->start_addr == start_addr )
243 {
244 DEBUGF( "found in wave_entry_old (oldsize=%d)\n",
245 this->oldsize );
246 *wave_entry = *e;
247 goto wave_in_cache;
248 }
249 }
250
251 wave_entry->start_addr = start_addr;
252
253 uint8_t const* const loop_ptr =
254 RAM + GET_LE16A( sd [raw_voice->waveform].loop );
255 short* loop_start = 0;
256
257 short* out = BRRcache + start_addr * 2;
258 wave_entry->samples = out;
259 *out++ = 0;
260 int smp1 = 0;
261 int smp2 = 0;
262
263 uint8_t const* addr = RAM + start_addr;
264 int block_header;
265 do
266 {
267 if ( addr == loop_ptr )
268 {
269 loop_start = out;
270 DEBUGF( "loop at %08x (wave #%d)\n", addr - RAM, raw_voice->waveform );
271 }
272
273 /* header */
274 block_header = *addr;
275 addr += 9;
276 voice->addr = addr;
277 int const filter = (block_header & 0x0C) - 0x08;
278
279 /* scaling
280 (invalid scaling gives -4096 for neg nybble, 0 for pos) */
281 static unsigned char const right_shifts [16] = {
282 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 29, 29, 29,
283 };
284 static unsigned char const left_shifts [16] = {
285 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 11, 11
286 };
287 int const scale = block_header >> 4;
288 int const right_shift = right_shifts [scale];
289 int const left_shift = left_shifts [scale];
290
291 /* output position */
292 out += brr_block_size;
293 int offset = -brr_block_size << 2;
294
295 do /* decode and filter 16 samples */
296 {
297 /* Get nybble, sign-extend, then scale
298 get byte, select which nybble, sign-extend, then shift based
299 on scaling. also handles invalid scaling values. */
300 int delta = (int) (int8_t) (addr [offset >> 3] << (offset & 4))
301 >> right_shift << left_shift;
302
303 out [offset >> 2] = smp2;
304
305 if ( filter == 0 ) /* mode 0x08 (30-90% of the time) */
306 {
307 delta -= smp2 >> 1;
308 delta += smp2 >> 5;
309 smp2 = smp1;
310 delta += smp1;
311 delta += (-smp1 - (smp1 >> 1)) >> 5;
312 }
313 else
314 {
315 if ( filter == -4 ) /* mode 0x04 */
316 {
317 delta += smp1 >> 1;
318 delta += (-smp1) >> 5;
319 }
320 else if ( filter > -4 ) /* mode 0x0C */
321 {
322 delta -= smp2 >> 1;
323 delta += (smp2 + (smp2 >> 1)) >> 4;
324 delta += smp1;
325 delta += (-smp1 * 13) >> 7;
326 }
327 smp2 = smp1;
328 }
329
330 CLAMP16( delta, delta );
331 smp1 = (int16_t) (delta * 2); /* sign-extend */
332 }
333 while ( (offset += 4) != 0 );
334
335 /* if next block has end flag set, this block ends early */
336 /* (verified) */
337 if ( (block_header & 3) != 3 && (*addr & 3) == 1 )
338 {
339 /* skip last 9 samples */
340 out -= 9;
341 goto early_end;
342 }
343 }
344 while ( !(block_header & 1) && addr < RAM + 0x10000 );
345
346 out [0] = smp2;
347 out [1] = smp1;
348
349 early_end:
350 wave_entry->end = (out - 1 - wave_entry->samples) << 12;
351
352 wave_entry->loop = 0;
353 if ( (block_header & 2) )
354 {
355 if ( loop_start )
356 {
357 int loop = out - loop_start;
358 wave_entry->loop = loop;
359 wave_entry->end += 0x3000;
360 out [2] = loop_start [2];
361 out [3] = loop_start [3];
362 out [4] = loop_start [4];
363 }
364 else
365 {
366 DEBUGF( "loop point outside initial wave\n" );
367 }
368 }
369
370 DEBUGF( "end at %08x (wave #%d)\n", addr - RAM, raw_voice->waveform );
371
372 /* add to cache */
373 this->wave_entry_old [this->oldsize++] = *wave_entry;
374wave_in_cache:;
375 }
376}
377#endif
378
379static void key_on(struct Spc_Dsp* const this, struct voice_t* const voice,
380 struct src_dir const* const sd,
381 struct raw_voice_t const* const raw_voice,
382 const int key_on_delay, const int vbit) ICODE_ATTR;
383static void key_on(struct Spc_Dsp* const this, struct voice_t* const voice,
384 struct src_dir const* const sd,
385 struct raw_voice_t const* const raw_voice,
386 const int key_on_delay, const int vbit) {
387 #undef RAM
388 #define RAM ram.ram
389 int const env_rate_init = 0x7800;
390 voice->key_on_delay = key_on_delay;
391 if ( key_on_delay == 0 )
392 {
393 this->keys_down |= vbit;
394 voice->envx = 0;
395 voice->env_mode = state_attack;
396 voice->env_timer = env_rate_init; /* TODO: inaccurate? */
397 unsigned start_addr = GET_LE16A( sd [raw_voice->waveform].start );
398 #if !SPC_BRRCACHE
399 {
400 voice->addr = RAM + start_addr;
401 /* BRR filter uses previous samples */
402 voice->samples [brr_block_size + 1] = 0;
403 voice->samples [brr_block_size + 2] = 0;
404 /* decode three samples immediately */
405 voice->position = (brr_block_size + 3) * 0x1000 - 1;
406 voice->block_header = 0; /* "previous" BRR header */
407 }
408 #else
409 {
410 voice->position = 3 * 0x1000 - 1;
411 struct cache_entry_t* const wave_entry =
412 &this->wave_entry [raw_voice->waveform];
413
414 /* predecode BRR if not already */
415 if ( wave_entry->start_addr != start_addr )
416 {
417 /* the following line can be replaced by the indicated block
418 in decode_brr() */
419 decode_brr( this, start_addr, voice, raw_voice );
420 }
421
422 voice->samples = wave_entry->samples;
423 voice->wave_end = wave_entry->end;
424 voice->wave_loop = wave_entry->loop;
425 }
426 #endif
427 }
428}
429
430static void DSP_run_( struct Spc_Dsp* this, long count, int32_t* out_buf )
431 ICODE_ATTR;
432static void DSP_run_( struct Spc_Dsp* this, long count, int32_t* out_buf )
433{
434 #undef RAM
435#ifdef CPU_ARM
436 uint8_t* const ram_ = ram.ram;
437 #define RAM ram_
438#else
439 #define RAM ram.ram
440#endif
441#if 0
442 EXIT_TIMER(cpu);
443 ENTER_TIMER(dsp);
444#endif
445
446 /* Here we check for keys on/off. Docs say that successive writes
447 to KON/KOF must be separated by at least 2 Ts periods or risk
448 being neglected. Therefore DSP only looks at these during an
449 update, and not at the time of the write. Only need to do this
450 once however, since the regs haven't changed over the whole
451 period we need to catch up with. */
452
453 {
454 int key_ons = this->r.g.key_ons;
455 int key_offs = this->r.g.key_offs;
456 /* keying on a voice resets that bit in ENDX */
457 this->r.g.wave_ended &= ~key_ons;
458 /* key_off bits prevent key_on from being acknowledged */
459 this->r.g.key_ons = key_ons & key_offs;
460
461 /* process key events outside loop, since they won't re-occur */
462 struct voice_t* voice = this->voice_state + 8;
463 int vbit = 0x80;
464 do
465 {
466 --voice;
467 if ( key_offs & vbit )
468 {
469 voice->env_mode = state_release;
470 voice->key_on_delay = 0;
471 }
472 else if ( key_ons & vbit )
473 {
474 voice->key_on_delay = 8;
475 }
476 }
477 while ( (vbit >>= 1) != 0 );
478 }
479
480 struct src_dir const* const sd =
481 (struct src_dir*) &RAM [this->r.g.wave_page * 0x100];
482
483#if !SPC_NOINTERP
484 int const slow_gaussian = (this->r.g.pitch_mods >> 1) |
485 this->r.g.noise_enables;
486#endif
487 /* (g.flags & 0x40) ? 30 : 14 */
488 int const global_muting = ((this->r.g.flags & 0x40) >> 2) + 14;
489
490 /* scaling to offset quietage */
491 int const global_vol_0 = this->r.g.volume_0 * 3;
492 int const global_vol_1 = this->r.g.volume_1 * 3;
493
494 /* each rate divides exactly into 0x7800 without remainder */
495 int const env_rate_init = 0x7800;
496 static unsigned short const env_rates [0x20] ICONST_ATTR =
497 {
498 0x0000, 0x000F, 0x0014, 0x0018, 0x001E, 0x0028, 0x0030, 0x003C,
499 0x0050, 0x0060, 0x0078, 0x00A0, 0x00C0, 0x00F0, 0x0140, 0x0180,
500 0x01E0, 0x0280, 0x0300, 0x03C0, 0x0500, 0x0600, 0x0780, 0x0A00,
501 0x0C00, 0x0F00, 0x1400, 0x1800, 0x1E00, 0x2800, 0x3C00, 0x7800
502 };
503
504 do /* one pair of output samples per iteration */
505 {
506 /* Noise */
507 if ( this->r.g.noise_enables )
508 {
509 if ( (this->noise_count -=
510 env_rates [this->r.g.flags & 0x1F]) <= 0 )
511 {
512 this->noise_count = env_rate_init;
513 int feedback = (this->noise << 13) ^ (this->noise << 14);
514 this->noise = (feedback & 0x8000) ^ (this->noise >> 1 & ~1);
515 }
516 }
517
518#if !SPC_NOECHO
519 int echo_0 = 0;
520 int echo_1 = 0;
521#endif
522 long prev_outx = 0; /* TODO: correct value for first channel? */
523 int chans_0 = 0;
524 int chans_1 = 0;
525 /* TODO: put raw_voice pointer in voice_t? */
526 struct raw_voice_t * raw_voice = this->r.voice;
527 struct voice_t* voice = this->voice_state;
528 int vbit = 1;
529 for ( ; vbit < 0x100; vbit <<= 1, ++voice, ++raw_voice )
530 {
531 /* pregen involves checking keyon, etc */
532#if 0
533 ENTER_TIMER(dsp_pregen);
534#endif
535
536 /* Key on events are delayed */
537 int key_on_delay = voice->key_on_delay;
538
539 if ( --key_on_delay >= 0 ) /* <1% of the time */
540 {
541 key_on(this,voice,sd,raw_voice,key_on_delay,vbit);
542 }
543
544 if ( !(this->keys_down & vbit) ) /* Silent channel */
545 {
546 silent_chan:
547 raw_voice->envx = 0;
548 raw_voice->outx = 0;
549 prev_outx = 0;
550 continue;
551 }
552
553 /* Envelope */
554 {
555 int const env_range = 0x800;
556 int env_mode = voice->env_mode;
557 int adsr0 = raw_voice->adsr [0];
558 int env_timer;
559 if ( env_mode != state_release ) /* 99% of the time */
560 {
561 env_timer = voice->env_timer;
562 if ( adsr0 & 0x80 ) /* 79% of the time */
563 {
564 int adsr1 = raw_voice->adsr [1];
565 if ( env_mode == state_sustain ) /* 74% of the time */
566 {
567 if ( (env_timer -= env_rates [adsr1 & 0x1F]) > 0 )
568 goto write_env_timer;
569
570 int envx = voice->envx;
571 envx--; /* envx *= 255 / 256 */
572 envx -= envx >> 8;
573 voice->envx = envx;
574 /* TODO: should this be 8? */
575 raw_voice->envx = envx >> 4;
576 goto init_env_timer;
577 }
578 else if ( env_mode < 0 ) /* 25% state_decay */
579 {
580 int envx = voice->envx;
581 if ( (env_timer -=
582 env_rates [(adsr0 >> 3 & 0x0E) + 0x10]) <= 0 )
583 {
584 envx--; /* envx *= 255 / 256 */
585 envx -= envx >> 8;
586 voice->envx = envx;
587 /* TODO: should this be 8? */
588 raw_voice->envx = envx >> 4;
589 env_timer = env_rate_init;
590 }
591
592 int sustain_level = adsr1 >> 5;
593 if ( envx <= (sustain_level + 1) * 0x100 )
594 voice->env_mode = state_sustain;
595
596 goto write_env_timer;
597 }
598 else /* state_attack */
599 {
600 int t = adsr0 & 0x0F;
601 if ( (env_timer -= env_rates [t * 2 + 1]) > 0 )
602 goto write_env_timer;
603
604 int envx = voice->envx;
605
606 int const step = env_range / 64;
607 envx += step;
608 if ( t == 15 )
609 envx += env_range / 2 - step;
610
611 if ( envx >= env_range )
612 {
613 envx = env_range - 1;
614 voice->env_mode = state_decay;
615 }
616 voice->envx = envx;
617 /* TODO: should this be 8? */
618 raw_voice->envx = envx >> 4;
619 goto init_env_timer;
620 }
621 }
622 else /* gain mode */
623 {
624 int t = raw_voice->gain;
625 if ( t < 0x80 )
626 {
627 raw_voice->envx = t;
628 voice->envx = t << 4;
629 goto env_end;
630 }
631 else
632 {
633 if ( (env_timer -= env_rates [t & 0x1F]) > 0 )
634 goto write_env_timer;
635
636 int envx = voice->envx;
637 int mode = t >> 5;
638 if ( mode <= 5 ) /* decay */
639 {
640 int step = env_range / 64;
641 if ( mode == 5 ) /* exponential */
642 {
643 envx--; /* envx *= 255 / 256 */
644 step = envx >> 8;
645 }
646 if ( (envx -= step) < 0 )
647 {
648 envx = 0;
649 if ( voice->env_mode == state_attack )
650 voice->env_mode = state_decay;
651 }
652 }
653 else /* attack */
654 {
655 int const step = env_range / 64;
656 envx += step;
657 if ( mode == 7 &&
658 envx >= env_range * 3 / 4 + step )
659 envx += env_range / 256 - step;
660
661 if ( envx >= env_range )
662 envx = env_range - 1;
663 }
664 voice->envx = envx;
665 /* TODO: should this be 8? */
666 raw_voice->envx = envx >> 4;
667 goto init_env_timer;
668 }
669 }
670 }
671 else /* state_release */
672 {
673 int envx = voice->envx;
674 if ( (envx -= env_range / 256) > 0 )
675 {
676 voice->envx = envx;
677 raw_voice->envx = envx >> 8;
678 goto env_end;
679 }
680 else
681 {
682 /* bit was set, so this clears it */
683 this->keys_down ^= vbit;
684 voice->envx = 0;
685 goto silent_chan;
686 }
687 }
688 init_env_timer:
689 env_timer = env_rate_init;
690 write_env_timer:
691 voice->env_timer = env_timer;
692 env_end:;
693 }
694#if 0
695 EXIT_TIMER(dsp_pregen);
696
697 ENTER_TIMER(dsp_gen);
698#endif
699 #if !SPC_BRRCACHE
700 /* Decode BRR block */
701 if ( voice->position >= brr_block_size * 0x1000 )
702 {
703 voice->position -= brr_block_size * 0x1000;
704
705 uint8_t const* addr = voice->addr;
706 if ( addr >= RAM + 0x10000 )
707 addr -= 0x10000;
708
709 /* action based on previous block's header */
710 if ( voice->block_header & 1 )
711 {
712 addr = RAM + GET_LE16A( sd [raw_voice->waveform].loop );
713 this->r.g.wave_ended |= vbit;
714 if ( !(voice->block_header & 2) ) /* 1% of the time */
715 {
716 /* first block was end block;
717 don't play anything (verified) */
718 /* bit was set, so this clears it */
719 this->keys_down ^= vbit;
720
721 /* since voice->envx is 0,
722 samples and position don't matter */
723 raw_voice->envx = 0;
724 voice->envx = 0;
725 goto skip_decode;
726 }
727 }
728
729 /* header */
730 int const block_header = *addr;
731 addr += 9;
732 voice->addr = addr;
733 voice->block_header = block_header;
734 int const filter = (block_header & 0x0C) - 0x08;
735
736 /* scaling (invalid scaling gives -4096 for neg nybble,
737 0 for pos) */
738 static unsigned char const right_shifts [16] = {
739 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 29, 29, 29,
740 };
741 static unsigned char const left_shifts [16] = {
742 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 11, 11
743 };
744 int const scale = block_header >> 4;
745 int const right_shift = right_shifts [scale];
746 int const left_shift = left_shifts [scale];
747
748 /* previous samples */
749 int smp2 = voice->samples [brr_block_size + 1];
750 int smp1 = voice->samples [brr_block_size + 2];
751 voice->samples [0] = voice->samples [brr_block_size];
752
753 /* output position */
754 short* out = voice->samples + (1 + brr_block_size);
755 int offset = -brr_block_size << 2;
756
757 /* if next block has end flag set,
758 this block ends early (verified) */
759 if ( (block_header & 3) != 3 && (*addr & 3) == 1 )
760 {
761 /* arrange for last 9 samples to be skipped */
762 int const skip = 9;
763 out += (skip & 1);
764 voice->samples [skip] = voice->samples [brr_block_size];
765 voice->position += skip * 0x1000;
766 offset = (-brr_block_size + (skip & ~1)) << 2;
767 addr -= skip / 2;
768 /* force sample to end on next decode */
769 voice->block_header = 1;
770 }
771
772 do /* decode and filter 16 samples */
773 {
774 /* Get nybble, sign-extend, then scale
775 get byte, select which nybble, sign-extend, then shift
776 based on scaling. also handles invalid scaling values.*/
777 int delta = (int) (int8_t) (addr [offset >> 3] <<
778 (offset & 4)) >> right_shift << left_shift;
779
780 out [offset >> 2] = smp2;
781
782 if ( filter == 0 ) /* mode 0x08 (30-90% of the time) */
783 {
784 delta -= smp2 >> 1;
785 delta += smp2 >> 5;
786 smp2 = smp1;
787 delta += smp1;
788 delta += (-smp1 - (smp1 >> 1)) >> 5;
789 }
790 else
791 {
792 if ( filter == -4 ) /* mode 0x04 */
793 {
794 delta += smp1 >> 1;
795 delta += (-smp1) >> 5;
796 }
797 else if ( filter > -4 ) /* mode 0x0C */
798 {
799 delta -= smp2 >> 1;
800 delta += (smp2 + (smp2 >> 1)) >> 4;
801 delta += smp1;
802 delta += (-smp1 * 13) >> 7;
803 }
804 smp2 = smp1;
805 }
806
807 CLAMP16( delta, delta );
808 smp1 = (int16_t) (delta * 2); /* sign-extend */
809 }
810 while ( (offset += 4) != 0 );
811
812 out [0] = smp2;
813 out [1] = smp1;
814
815 skip_decode:;
816 }
817 #endif
818
819 /* Get rate (with possible modulation) */
820 int rate = GET_LE16A( raw_voice->rate ) & 0x3FFF;
821 if ( this->r.g.pitch_mods & vbit )
822 rate = (rate * (prev_outx + 32768)) >> 15;
823
824 #if !SPC_NOINTERP
825 /* Interleved gauss table (to improve cache coherency). */
826 /* gauss [i * 2 + j] = normal_gauss [(1 - j) * 256 + i] */
827 static short const gauss [512] =
828 {
829370,1305, 366,1305, 362,1304, 358,1304, 354,1304, 351,1304, 347,1304, 343,1303,
830339,1303, 336,1303, 332,1302, 328,1302, 325,1301, 321,1300, 318,1300, 314,1299,
831311,1298, 307,1297, 304,1297, 300,1296, 297,1295, 293,1294, 290,1293, 286,1292,
832283,1291, 280,1290, 276,1288, 273,1287, 270,1286, 267,1284, 263,1283, 260,1282,
833257,1280, 254,1279, 251,1277, 248,1275, 245,1274, 242,1272, 239,1270, 236,1269,
834233,1267, 230,1265, 227,1263, 224,1261, 221,1259, 218,1257, 215,1255, 212,1253,
835210,1251, 207,1248, 204,1246, 201,1244, 199,1241, 196,1239, 193,1237, 191,1234,
836188,1232, 186,1229, 183,1227, 180,1224, 178,1221, 175,1219, 173,1216, 171,1213,
837168,1210, 166,1207, 163,1205, 161,1202, 159,1199, 156,1196, 154,1193, 152,1190,
838150,1186, 147,1183, 145,1180, 143,1177, 141,1174, 139,1170, 137,1167, 134,1164,
839132,1160, 130,1157, 128,1153, 126,1150, 124,1146, 122,1143, 120,1139, 118,1136,
840117,1132, 115,1128, 113,1125, 111,1121, 109,1117, 107,1113, 106,1109, 104,1106,
841102,1102, 100,1098, 99,1094, 97,1090, 95,1086, 94,1082, 92,1078, 90,1074,
842 89,1070, 87,1066, 86,1061, 84,1057, 83,1053, 81,1049, 80,1045, 78,1040,
843 77,1036, 76,1032, 74,1027, 73,1023, 71,1019, 70,1014, 69,1010, 67,1005,
844 66,1001, 65, 997, 64, 992, 62, 988, 61, 983, 60, 978, 59, 974, 58, 969,
845 56, 965, 55, 960, 54, 955, 53, 951, 52, 946, 51, 941, 50, 937, 49, 932,
846 48, 927, 47, 923, 46, 918, 45, 913, 44, 908, 43, 904, 42, 899, 41, 894,
847 40, 889, 39, 884, 38, 880, 37, 875, 36, 870, 36, 865, 35, 860, 34, 855,
848 33, 851, 32, 846, 32, 841, 31, 836, 30, 831, 29, 826, 29, 821, 28, 816,
849 27, 811, 27, 806, 26, 802, 25, 797, 24, 792, 24, 787, 23, 782, 23, 777,
850 22, 772, 21, 767, 21, 762, 20, 757, 20, 752, 19, 747, 19, 742, 18, 737,
851 17, 732, 17, 728, 16, 723, 16, 718, 15, 713, 15, 708, 15, 703, 14, 698,
852 14, 693, 13, 688, 13, 683, 12, 678, 12, 674, 11, 669, 11, 664, 11, 659,
853 10, 654, 10, 649, 10, 644, 9, 640, 9, 635, 9, 630, 8, 625, 8, 620,
854 8, 615, 7, 611, 7, 606, 7, 601, 6, 596, 6, 592, 6, 587, 6, 582,
855 5, 577, 5, 573, 5, 568, 5, 563, 4, 559, 4, 554, 4, 550, 4, 545,
856 4, 540, 3, 536, 3, 531, 3, 527, 3, 522, 3, 517, 2, 513, 2, 508,
857 2, 504, 2, 499, 2, 495, 2, 491, 2, 486, 1, 482, 1, 477, 1, 473,
858 1, 469, 1, 464, 1, 460, 1, 456, 1, 451, 1, 447, 1, 443, 1, 439,
859 0, 434, 0, 430, 0, 426, 0, 422, 0, 418, 0, 414, 0, 410, 0, 405,
860 0, 401, 0, 397, 0, 393, 0, 389, 0, 385, 0, 381, 0, 378, 0, 374,
861 };
862
863 /* Gaussian interpolation using most recent 4 samples */
864 long position = voice->position;
865 voice->position += rate;
866 short const* interp = voice->samples + (position >> 12);
867 int offset = position >> 4 & 0xFF;
868
869 /* Only left half of gaussian kernel is in table, so we must mirror
870 for right half */
871 short const* fwd = gauss + offset * 2;
872 short const* rev = gauss + 510 - offset * 2;
873
874 /* Use faster gaussian interpolation when exact result isn't needed
875 by pitch modulator of next channel */
876 int amp_0, amp_1;
877 if ( !(slow_gaussian & vbit) ) /* 99% of the time */
878 {
879 /* Main optimization is lack of clamping. Not a problem since
880 output never goes more than +/- 16 outside 16-bit range and
881 things are clamped later anyway. Other optimization is to
882 preserve fractional accuracy, eliminating several masks. */
883 int output = (((fwd [0] * interp [0] +
884 fwd [1] * interp [1] +
885 rev [1] * interp [2] +
886 rev [0] * interp [3] ) >> 11) * voice->envx) >> 11;
887
888 /* duplicated here to give compiler more to run in parallel */
889 amp_0 = voice->volume [0] * output;
890 amp_1 = voice->volume [1] * output;
891 raw_voice->outx = output >> 8;
892 }
893 else
894 {
895 int output = *(int16_t*) &this->noise;
896 if ( !(this->r.g.noise_enables & vbit) )
897 {
898 output = (fwd [0] * interp [0]) & ~0xFFF;
899 output = (output + fwd [1] * interp [1]) & ~0xFFF;
900 output = (output + rev [1] * interp [2]) >> 12;
901 output = (int16_t) (output * 2);
902 output += ((rev [0] * interp [3]) >> 12) * 2;
903 CLAMP16( output, output );
904 }
905 output = (output * voice->envx) >> 11 & ~1;
906
907 /* duplicated here to give compiler more to run in parallel */
908 amp_0 = voice->volume [0] * output;
909 amp_1 = voice->volume [1] * output;
910 prev_outx = output;
911 raw_voice->outx = (int8_t) (output >> 8);
912 }
913 #else
914 /* two-point linear interpolation */
915 #ifdef CPU_COLDFIRE
916 int32_t output = (int16_t)this->noise;
917
918 if ( (this->r.g.noise_enables & vbit) == 0 )
919 {
920 uint32_t f = voice->position;
921 int32_t y1;
922 asm (
923 "move.l %[f], %[y0] \n" /* separate fraction */
924 "and.l #0xfff, %[f] \n" /* and whole parts */
925 "lsr.l %[sh], %[y0] \n"
926 "move.l 2(%[s], %[y0].l*2), %[y1] \n" /* load two samples */
927 "move.l %[y1], %[y0] \n" /* separate samples */
928 "ext.l %[y1] \n" /* y0=s[1], y1=s[2] */
929 "swap %[y0] \n"
930 "ext.l %[y0] \n"
931 "sub.l %[y0], %[y1] \n" /* diff = y1 - y0 */
932 "muls.l %[f], %[y1] \n" /* y0 += f*diff */
933 "asr.l %[sh], %[y1] \n"
934 "add.l %[y1], %[y0] \n"
935 : [f]"+&d"(f), [y0]"=&d"(output), [y1]"=&d"(y1)
936 : [s]"a"(voice->samples), [sh]"r"(12)
937 );
938 }
939
940 voice->position += rate;
941 #else
942
943 /* Try this one out on ARM and see - similar to above but the asm
944 on coldfire removes a redundant register load worth 1 or 2%;
945 switching to loading two samples at once may help too. That's
946 done above and while 6 to 7% faster on cf over two 16 bit loads
947 it makes it endian dependant.
948
949 measured small improvement (~1.5%) - hcs
950 */
951
952 int output;
953
954 if ( (this->r.g.noise_enables & vbit) == 0 )
955 {
956 int const fraction = voice->position & 0xfff;
957 short const* const pos = (voice->samples + (voice->position >> 12)) + 1;
958 output = pos[0] + ((fraction * (pos[1] - pos[0])) >> 12);
959 } else {
960 output = *(int16_t *)&this->noise;
961 }
962
963 voice->position += rate;
964
965 /* old version */
966#if 0
967 int fraction = voice->position & 0xFFF;
968 short const* const pos = voice->samples + (voice->position >> 12);
969 voice->position += rate;
970 int output =
971 (pos [2] * fraction + pos [1] * (0x1000 - fraction)) >> 12;
972 /* no interpolation (hardly faster, and crappy sounding) */
973 /*int output = pos [0];*/
974 if ( this->r.g.noise_enables & vbit )
975 output = *(int16_t*) &this->noise;
976#endif
977 #endif /* CPU_COLDFIRE */
978
979 output = (output * voice->envx) >> 11;
980
981 /* duplicated here to give compiler more to run in parallel */
982 int amp_0 = voice->volume [0] * output;
983 int amp_1 = voice->volume [1] * output;
984
985 prev_outx = output;
986 raw_voice->outx = (int8_t) (output >> 8);
987 #endif
988
989 #if SPC_BRRCACHE
990 if ( voice->position >= voice->wave_end )
991 {
992 long loop_len = voice->wave_loop << 12;
993 voice->position -= loop_len;
994 this->r.g.wave_ended |= vbit;
995 if ( !loop_len )
996 {
997 this->keys_down ^= vbit;
998 raw_voice->envx = 0;
999 voice->envx = 0;
1000 }
1001 }
1002 #endif
1003#if 0
1004 EXIT_TIMER(dsp_gen);
1005
1006 ENTER_TIMER(dsp_mix);
1007#endif
1008 chans_0 += amp_0;
1009 chans_1 += amp_1;
1010 #if !SPC_NOECHO
1011 if ( this->r.g.echo_ons & vbit )
1012 {
1013 echo_0 += amp_0;
1014 echo_1 += amp_1;
1015 }
1016 #endif
1017#if 0
1018 EXIT_TIMER(dsp_mix);
1019#endif
1020 }
1021 /* end of voice loop */
1022
1023 #if !SPC_NOECHO
1024 /* Read feedback from echo buffer */
1025 int echo_pos = this->echo_pos;
1026 uint8_t* const echo_ptr = RAM +
1027 ((this->r.g.echo_page * 0x100 + echo_pos) & 0xFFFF);
1028 echo_pos += 4;
1029 if ( echo_pos >= (this->r.g.echo_delay & 15) * 0x800 )
1030 echo_pos = 0;
1031 this->echo_pos = echo_pos;
1032 int fb_0 = GET_LE16SA( echo_ptr );
1033 int fb_1 = GET_LE16SA( echo_ptr + 2 );
1034
1035 /* Keep last 8 samples */
1036 int (* const fir_ptr) [2] = this->fir_buf + this->fir_pos;
1037 this->fir_pos = (this->fir_pos + 1) & (fir_buf_half - 1);
1038 fir_ptr [ 0] [0] = fb_0;
1039 fir_ptr [ 0] [1] = fb_1;
1040 /* duplicate at +8 eliminates wrap checking below */
1041 fir_ptr [fir_buf_half] [0] = fb_0;
1042 fir_ptr [fir_buf_half] [1] = fb_1;
1043
1044 /* Apply FIR */
1045 fb_0 *= this->fir_coeff [0];
1046 fb_1 *= this->fir_coeff [0];
1047
1048 #define DO_PT( i )\
1049 fb_0 += fir_ptr [i] [0] * this->fir_coeff [i];\
1050 fb_1 += fir_ptr [i] [1] * this->fir_coeff [i];
1051
1052 DO_PT( 1 )
1053 DO_PT( 2 )
1054 DO_PT( 3 )
1055 DO_PT( 4 )
1056 DO_PT( 5 )
1057 DO_PT( 6 )
1058 DO_PT( 7 )
1059
1060 /* Generate output */
1061 int amp_0 = (chans_0 * global_vol_0 + fb_0 * this->r.g.echo_volume_0)
1062 >> global_muting;
1063 int amp_1 = (chans_1 * global_vol_1 + fb_1 * this->r.g.echo_volume_1)
1064 >> global_muting;
1065 CLAMP16( amp_0, amp_0 );
1066 out_buf [0] = amp_0 * (1 << 8);
1067 CLAMP16( amp_1, amp_1 );
1068 out_buf [WAV_CHUNK_SIZE] = amp_1 * (1 << 8);
1069 out_buf ++;
1070
1071 /* Feedback into echo buffer */
1072 int e0 = (echo_0 >> 7) + ((fb_0 * this->r.g.echo_feedback) >> 14);
1073 int e1 = (echo_1 >> 7) + ((fb_1 * this->r.g.echo_feedback) >> 14);
1074 if ( !(this->r.g.flags & 0x20) )
1075 {
1076 CLAMP16( e0, e0 );
1077 SET_LE16A( echo_ptr , e0 );
1078 CLAMP16( e1, e1 );
1079 SET_LE16A( echo_ptr + 2, e1 );
1080 }
1081 #else
1082 /* Generate output */
1083 int amp_0 = (chans_0 * global_vol_0) >> global_muting;
1084 int amp_1 = (chans_1 * global_vol_1) >> global_muting;
1085 CLAMP16( amp_0, amp_0 );
1086 out_buf [0] = amp_0 * (1 << 8);
1087 CLAMP16( amp_1, amp_1 );
1088 out_buf [WAV_CHUNK_SIZE] = amp_1 * (1 << 8);
1089 out_buf ++;
1090 #endif
1091 }
1092 while ( --count );
1093#if 0
1094 EXIT_TIMER(dsp);
1095 ENTER_TIMER(cpu);
1096#endif
1097}
1098
1099static inline void DSP_run( struct Spc_Dsp* this, long count, int32_t* out )
1100{
1101 /* Should we just fill the buffer with silence? Flags won't be cleared */
1102 /* during this run so it seems it should keep resetting every sample. */
1103 if ( this->r.g.flags & 0x80 )
1104 DSP_reset( this );
1105
1106 DSP_run_( this, count, out );
1107}