summaryrefslogtreecommitdiff
path: root/apps/dsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/dsp.c')
-rw-r--r--apps/dsp.c354
1 files changed, 170 insertions, 184 deletions
diff --git a/apps/dsp.c b/apps/dsp.c
index be851e2305..3b95145b39 100644
--- a/apps/dsp.c
+++ b/apps/dsp.c
@@ -38,9 +38,14 @@
38#define WORD_FRACBITS 27 38#define WORD_FRACBITS 27
39 39
40#define NATIVE_DEPTH 16 40#define NATIVE_DEPTH 16
41/* If the buffer sizes change, check the assembly code! */
41#define SAMPLE_BUF_COUNT 256 42#define SAMPLE_BUF_COUNT 256
42#define RESAMPLE_BUF_COUNT (256 * 4) /* Enough for 11,025 Hz -> 44,100 Hz*/ 43#define RESAMPLE_BUF_COUNT (256 * 4) /* Enough for 11,025 Hz -> 44,100 Hz*/
43#define DEFAULT_GAIN 0x01000000 44#define DEFAULT_GAIN 0x01000000
45#define SAMPLE_BUF_LEFT_CHANNEL 0
46#define SAMPLE_BUF_RIGHT_CHANNEL (SAMPLE_BUF_COUNT/2)
47#define RESAMPLE_BUF_LEFT_CHANNEL 0
48#define RESAMPLE_BUF_RIGHT_CHANNEL (RESAMPLE_BUF_COUNT/2)
44 49
45/* enums to index conversion properly with stereo mode and other settings */ 50/* enums to index conversion properly with stereo mode and other settings */
46enum 51enum
@@ -66,11 +71,10 @@ enum
66 * NOTE: Any assembly routines that use these structures must be updated 71 * NOTE: Any assembly routines that use these structures must be updated
67 * if current data members are moved or changed. 72 * if current data members are moved or changed.
68 */ 73 */
69 /* 32-bit achitecture offset */
70struct resample_data 74struct resample_data
71{ 75{
72 long delta; /* 00h */ 76 uint32_t delta; /* 00h */
73 long phase; /* 04h */ 77 uint32_t phase; /* 04h */
74 int32_t last_sample[2]; /* 08h */ 78 int32_t last_sample[2]; /* 08h */
75 /* 10h */ 79 /* 10h */
76}; 80};
@@ -93,9 +97,10 @@ struct dsp_data
93 int output_scale; /* 00h */ 97 int output_scale; /* 00h */
94 int num_channels; /* 04h */ 98 int num_channels; /* 04h */
95 struct resample_data resample_data; /* 08h */ 99 struct resample_data resample_data; /* 08h */
96 int clip_min; /* 18h */ 100 int32_t clip_min; /* 18h */
97 int clip_max; /* 2ch */ 101 int32_t clip_max; /* 1ch */
98 /* 30h */ 102 int32_t gain; /* 20h - Note that this is in S8.23 format. */
103 /* 24h */
99}; 104};
100 105
101/* No asm...yet */ 106/* No asm...yet */
@@ -132,13 +137,18 @@ struct eq_state
132#include <dsp_asm.h> 137#include <dsp_asm.h>
133 138
134/* Typedefs keep things much neater in this case */ 139/* Typedefs keep things much neater in this case */
135typedef int (*sample_input_fn_type)(int count, const char *src[], 140typedef void (*sample_input_fn_type)(int count, const char *src[],
136 int32_t *dst[]); 141 int32_t *dst[]);
137typedef int (*resample_fn_type)(int count, struct dsp_data *data, 142typedef int (*resample_fn_type)(int count, struct dsp_data *data,
138 int32_t *src[], int32_t *dst[]); 143 int32_t *src[], int32_t *dst[]);
139typedef void (*sample_output_fn_type)(int count, struct dsp_data *data, 144typedef void (*sample_output_fn_type)(int count, struct dsp_data *data,
140 int32_t *src[], int16_t *dst); 145 int32_t *src[], int16_t *dst);
146/* Single-DSP channel processing in place */
141typedef void (*channels_process_fn_type)(int count, int32_t *buf[]); 147typedef void (*channels_process_fn_type)(int count, int32_t *buf[]);
148/* DSP local channel processing in place */
149typedef void (*channels_process_dsp_fn_type)(int count, struct dsp_data *data,
150 int32_t *buf[]);
151
142 152
143/* 153/*
144 ***************************************************************************/ 154 ***************************************************************************/
@@ -152,16 +162,16 @@ struct dsp_config
152 int sample_bytes; 162 int sample_bytes;
153 int stereo_mode; 163 int stereo_mode;
154 int frac_bits; 164 int frac_bits;
155 long gain; /* Note that this is in S8.23 format. */
156 /* Functions that change depending upon settings - NULL if stage is 165 /* Functions that change depending upon settings - NULL if stage is
157 disabled */ 166 disabled */
158 sample_input_fn_type input_samples; 167 sample_input_fn_type input_samples;
159 resample_fn_type resample; 168 resample_fn_type resample;
160 sample_output_fn_type output_samples; 169 sample_output_fn_type output_samples;
161 /* These will be NULL for the voice codec and is more economical that 170 /* These will be NULL for the voice codec and is more economical that
162 way */ 171 way */
163 channels_process_fn_type apply_crossfeed; 172 channels_process_dsp_fn_type apply_gain;
164 channels_process_fn_type channels_process; 173 channels_process_fn_type apply_crossfeed;
174 channels_process_fn_type channels_process;
165}; 175};
166 176
167/* General DSP config */ 177/* General DSP config */
@@ -211,7 +221,7 @@ static struct dsp_config *dsp IDATA_ATTR = audio_dsp;
211 * of copying needed is minimized for that case. 221 * of copying needed is minimized for that case.
212 */ 222 */
213 223
214static int32_t sample_buf[SAMPLE_BUF_COUNT] IBSS_ATTR; 224int32_t sample_buf[SAMPLE_BUF_COUNT] IBSS_ATTR;
215static int32_t resample_buf[RESAMPLE_BUF_COUNT] IBSS_ATTR; 225static int32_t resample_buf[RESAMPLE_BUF_COUNT] IBSS_ATTR;
216 226
217/* set a new dsp and return old one */ 227/* set a new dsp and return old one */
@@ -258,23 +268,20 @@ void sound_set_pitch(int permille)
258 dsp_configure(DSP_SWITCH_FREQUENCY, dsp->codec_frequency); 268 dsp_configure(DSP_SWITCH_FREQUENCY, dsp->codec_frequency);
259} 269}
260 270
261/* Convert at most count samples to the internal format, if needed. Returns 271/* Convert count samples to the internal format, if needed. Updates src
262 * number of samples ready for further processing. Updates src to point 272 * to point past the samples "consumed" and dst is set to point to the
263 * past the samples "consumed" and dst is set to point to the samples to 273 * samples to consume. Note that for mono, dst[0] equals dst[1], as there
264 * consume. Note that for mono, dst[0] equals dst[1], as there is no point 274 * is no point in processing the same data twice.
265 * in processing the same data twice.
266 */ 275 */
267 276
268/* convert count 16-bit mono to 32-bit mono */ 277/* convert count 16-bit mono to 32-bit mono */
269static int sample_input_lte_native_mono( 278static void sample_input_lte_native_mono(
270 int count, const char *src[], int32_t *dst[]) 279 int count, const char *src[], int32_t *dst[])
271{ 280{
272 count = MIN(SAMPLE_BUF_COUNT/2, count);
273
274 const int16_t *s = (int16_t *) src[0]; 281 const int16_t *s = (int16_t *) src[0];
275 const int16_t * const send = s + count; 282 const int16_t * const send = s + count;
276 int32_t *d = dst[0] = dst[1] = sample_buf; 283 int32_t *d = dst[0] = dst[1] = &sample_buf[SAMPLE_BUF_LEFT_CHANNEL];
277 const int scale = WORD_SHIFT; 284 int scale = WORD_SHIFT;
278 285
279 do 286 do
280 { 287 {
@@ -283,21 +290,17 @@ static int sample_input_lte_native_mono(
283 while (s < send); 290 while (s < send);
284 291
285 src[0] = (char *)s; 292 src[0] = (char *)s;
286
287 return count;
288} 293}
289 294
290/* convert count 16-bit interleaved stereo to 32-bit noninterleaved */ 295/* convert count 16-bit interleaved stereo to 32-bit noninterleaved */
291static int sample_input_lte_native_i_stereo( 296static void sample_input_lte_native_i_stereo(
292 int count, const char *src[], int32_t *dst[]) 297 int count, const char *src[], int32_t *dst[])
293{ 298{
294 count = MIN(SAMPLE_BUF_COUNT/2, count);
295
296 const int32_t *s = (int32_t *) src[0]; 299 const int32_t *s = (int32_t *) src[0];
297 const int32_t * const send = s + count; 300 const int32_t * const send = s + count;
298 int32_t *dl = dst[0] = sample_buf; 301 int32_t *dl = dst[0] = &sample_buf[SAMPLE_BUF_LEFT_CHANNEL];
299 int32_t *dr = dst[1] = sample_buf + SAMPLE_BUF_COUNT/2; 302 int32_t *dr = dst[1] = &sample_buf[SAMPLE_BUF_RIGHT_CHANNEL];
300 const int scale = WORD_SHIFT; 303 int scale = WORD_SHIFT;
301 304
302 do 305 do
303 { 306 {
@@ -313,22 +316,18 @@ static int sample_input_lte_native_i_stereo(
313 while (s < send); 316 while (s < send);
314 317
315 src[0] = (char *)s; 318 src[0] = (char *)s;
316
317 return count;
318} 319}
319 320
320/* convert count 16-bit noninterleaved stereo to 32-bit noninterleaved */ 321/* convert count 16-bit noninterleaved stereo to 32-bit noninterleaved */
321static int sample_input_lte_native_ni_stereo( 322static void sample_input_lte_native_ni_stereo(
322 int count, const char *src[], int32_t *dst[]) 323 int count, const char *src[], int32_t *dst[])
323{ 324{
324 count = MIN(SAMPLE_BUF_COUNT/2, count);
325
326 const int16_t *sl = (int16_t *) src[0]; 325 const int16_t *sl = (int16_t *) src[0];
327 const int16_t *sr = (int16_t *) src[1]; 326 const int16_t *sr = (int16_t *) src[1];
328 const int16_t * const slend = sl + count; 327 const int16_t * const slend = sl + count;
329 int32_t *dl = dst[0] = sample_buf; 328 int32_t *dl = dst[0] = &sample_buf[SAMPLE_BUF_LEFT_CHANNEL];
330 int32_t *dr = dst[1] = sample_buf + SAMPLE_BUF_COUNT/2; 329 int32_t *dr = dst[1] = &sample_buf[SAMPLE_BUF_RIGHT_CHANNEL];
331 const int scale = WORD_SHIFT; 330 int scale = WORD_SHIFT;
332 331
333 do 332 do
334 { 333 {
@@ -339,35 +338,24 @@ static int sample_input_lte_native_ni_stereo(
339 338
340 src[0] = (char *)sl; 339 src[0] = (char *)sl;
341 src[1] = (char *)sr; 340 src[1] = (char *)sr;
342
343 return count;
344} 341}
345 342
346/* convert count 32-bit mono to 32-bit mono */ 343/* convert count 32-bit mono to 32-bit mono */
347static int sample_input_gt_native_mono( 344static void sample_input_gt_native_mono(
348 int count, const char *src[], int32_t *dst[]) 345 int count, const char *src[], int32_t *dst[])
349{ 346{
350 count = MIN(SAMPLE_BUF_COUNT/2, count);
351
352 dst[0] = dst[1] = (int32_t *)src[0]; 347 dst[0] = dst[1] = (int32_t *)src[0];
353 src[0] = (char *)(dst[0] + count); 348 src[0] = (char *)(dst[0] + count);
354
355 return count;
356} 349}
357 350
358/* convert count 32-bit interleaved stereo to 32-bit noninterleaved stereo */ 351/* convert count 32-bit interleaved stereo to 32-bit noninterleaved stereo */
359static int sample_input_gt_native_i_stereo( 352static void sample_input_gt_native_i_stereo(
360 int count, const char *src[], int32_t *dst[]) 353 int count, const char *src[], int32_t *dst[])
361{ 354{
362 count = MIN(SAMPLE_BUF_COUNT/2, count);
363
364 const int32_t *s = (int32_t *)src[0]; 355 const int32_t *s = (int32_t *)src[0];
365 const int32_t * const send = s + 2*count; 356 const int32_t * const send = s + 2*count;
366 int32_t *dl = sample_buf; 357 int32_t *dl = dst[0] = &sample_buf[SAMPLE_BUF_LEFT_CHANNEL];
367 int32_t *dr = sample_buf + SAMPLE_BUF_COUNT/2; 358 int32_t *dr = dst[1] = &sample_buf[SAMPLE_BUF_RIGHT_CHANNEL];
368
369 dst[0] = dl;
370 dst[1] = dr;
371 359
372 do 360 do
373 { 361 {
@@ -377,22 +365,16 @@ static int sample_input_gt_native_i_stereo(
377 while (s < send); 365 while (s < send);
378 366
379 src[0] = (char *)send; 367 src[0] = (char *)send;
380
381 return count;
382} 368}
383 369
384/* convert 32 bit-noninterleaved stereo to 32-bit noninterleaved stereo */ 370/* convert 32 bit-noninterleaved stereo to 32-bit noninterleaved stereo */
385static int sample_input_gt_native_ni_stereo( 371static void sample_input_gt_native_ni_stereo(
386 int count, const char *src[], int32_t *dst[]) 372 int count, const char *src[], int32_t *dst[])
387{ 373{
388 count = MIN(SAMPLE_BUF_COUNT/2, count);
389
390 dst[0] = (int32_t *)src[0]; 374 dst[0] = (int32_t *)src[0];
391 dst[1] = (int32_t *)src[1]; 375 dst[1] = (int32_t *)src[1];
392 src[0] = (char *)(dst[0] + count); 376 src[0] = (char *)(dst[0] + count);
393 src[1] = (char *)(dst[1] + count); 377 src[1] = (char *)(dst[1] + count);
394
395 return count;
396} 378}
397 379
398/** 380/**
@@ -573,12 +555,6 @@ static void sample_output_new_format(void)
573 dsp->output_samples = sample_output_functions[out]; 555 dsp->output_samples = sample_output_functions[out];
574} 556}
575 557
576static void resampler_set_delta(int frequency)
577{
578 dsp->data.resample_data.delta = (unsigned long)
579 frequency * 65536LL / NATIVE_FREQUENCY;
580}
581
582/** 558/**
583 * Linear interpolation resampling that introduces a one sample delay because 559 * Linear interpolation resampling that introduces a one sample delay because
584 * of our inability to look into the future at the end of a frame. 560 * of our inability to look into the future at the end of a frame.
@@ -587,9 +563,9 @@ static void resampler_set_delta(int frequency)
587static int dsp_downsample(int count, struct dsp_data *data, 563static int dsp_downsample(int count, struct dsp_data *data,
588 int32_t *src[], int32_t *dst[]) 564 int32_t *src[], int32_t *dst[])
589{ 565{
590 int ch = data->num_channels - 1; 566 int ch = data->num_channels - 1;
591 long delta = data->resample_data.delta; 567 uint32_t delta = data->resample_data.delta;
592 long phase, pos; 568 uint32_t phase, pos;
593 int32_t *d; 569 int32_t *d;
594 570
595 /* Rolled channel loop actually showed slightly faster. */ 571 /* Rolled channel loop actually showed slightly faster. */
@@ -610,7 +586,7 @@ static int dsp_downsample(int count, struct dsp_data *data,
610 if (pos > 0) 586 if (pos > 0)
611 last = s[pos - 1]; 587 last = s[pos - 1];
612 588
613 while (pos < count) 589 while (pos < (uint32_t)count)
614 { 590 {
615 *d++ = last + FRACMUL((phase & 0xffff) << 15, s[pos] - last); 591 *d++ = last + FRACMUL((phase & 0xffff) << 15, s[pos] - last);
616 phase += delta; 592 phase += delta;
@@ -625,12 +601,12 @@ static int dsp_downsample(int count, struct dsp_data *data,
625 return d - dst[0]; 601 return d - dst[0];
626} 602}
627 603
628static int dsp_upsample(int count, struct dsp_data *data, 604static int dsp_upsample(int count, struct dsp_data *data,
629 int32_t *src[], int32_t *dst[]) 605 int32_t *src[], int32_t *dst[])
630{ 606{
631 int ch = data->num_channels - 1; 607 int ch = data->num_channels - 1;
632 long delta = data->resample_data.delta; 608 uint32_t delta = data->resample_data.delta;
633 long phase, pos; 609 uint32_t phase, pos;
634 int32_t *d; 610 int32_t *d;
635 611
636 /* Rolled channel loop actually showed slightly faster. */ 612 /* Rolled channel loop actually showed slightly faster. */
@@ -653,7 +629,7 @@ static int dsp_upsample(int count, struct dsp_data *data,
653 pos = phase >> 16; 629 pos = phase >> 16;
654 } 630 }
655 631
656 while (pos < count) 632 while (pos < (uint32_t)count)
657 { 633 {
658 last = s[pos - 1]; 634 last = s[pos - 1];
659 *d++ = last + FRACMUL((phase & 0xffff) << 15, s[pos] - last); 635 *d++ = last + FRACMUL((phase & 0xffff) << 15, s[pos] - last);
@@ -669,24 +645,43 @@ static int dsp_upsample(int count, struct dsp_data *data,
669} 645}
670#endif /* DSP_HAVE_ASM_RESAMPLING */ 646#endif /* DSP_HAVE_ASM_RESAMPLING */
671 647
648static void resampler_new_delta(void)
649{
650 dsp->data.resample_data.delta = (unsigned long)
651 dsp->frequency * 65536LL / NATIVE_FREQUENCY;
652
653 if (dsp->frequency == NATIVE_FREQUENCY)
654 {
655 /* NOTE: If fully glitch-free transistions from no resampling to
656 resampling are desired, last_sample history should be maintained
657 even when not resampling. */
658 dsp->resample = NULL;
659 dsp->data.resample_data.phase = 0;
660 dsp->data.resample_data.last_sample[0] = 0;
661 dsp->data.resample_data.last_sample[1] = 0;
662 }
663 else if (dsp->frequency < NATIVE_FREQUENCY)
664 dsp->resample = dsp_upsample;
665 else
666 dsp->resample = dsp_downsample;
667}
668
672/* Resample count stereo samples. Updates the src array, if resampling is 669/* Resample count stereo samples. Updates the src array, if resampling is
673 * done, to refer to the resampled data. Returns number of stereo samples 670 * done, to refer to the resampled data. Returns number of stereo samples
674 * for further processing. 671 * for further processing.
675 */ 672 */
676static inline int resample(int count, int32_t *src[]) 673static inline int resample(int count, int32_t *src[])
677{ 674{
678 if (dsp->resample) 675 int32_t *dst[2] =
679 { 676 {
680 int32_t *dst[2] = 677 &resample_buf[RESAMPLE_BUF_LEFT_CHANNEL],
681 { 678 &resample_buf[RESAMPLE_BUF_RIGHT_CHANNEL],
682 resample_buf, 679 };
683 resample_buf + RESAMPLE_BUF_COUNT/2,
684 };
685 680
686 count = dsp->resample(count, &dsp->data, src, dst); 681 count = dsp->resample(count, &dsp->data, src, dst);
687 src[0] = dst[0]; 682
688 src[1] = dst[dsp->data.num_channels - 1]; 683 src[0] = dst[0];
689 } 684 src[1] = dst[dsp->data.num_channels - 1];
690 685
691 return count; 686 return count;
692} 687}
@@ -810,30 +805,59 @@ void dsp_set_crossfeed_cross_params(long lf_gain, long hf_gain, long cutoff)
810 c[2] <<= 4; 805 c[2] <<= 4;
811} 806}
812 807
808/* Apply a constant gain to the samples (e.g., for ReplayGain).
809 * Note that this must be called before the resampler.
810 */
811#ifndef DSP_HAVE_ASM_APPLY_GAIN
812static void dsp_apply_gain(int count, struct dsp_data *data, int32_t *buf[])
813{
814 const int32_t gain = data->gain;
815 int ch = data->num_channels - 1;
816
817 do
818 {
819 int32_t *s = buf[ch];
820 int32_t *d = buf[ch];
821 int32_t samp = *s++;
822 int i = 0;
823
824 do
825 {
826 FRACMUL_8_LOOP(samp, gain, s, d);
827 }
828 while (++i < count);
829 }
830 while (--ch >= 0);
831}
832#endif /* DSP_HAVE_ASM_APPLY_GAIN */
833
813/* Combine all gains to a global gain. */ 834/* Combine all gains to a global gain. */
814static void set_gain(struct dsp_config *dsp) 835static void set_gain(struct dsp_config *dsp)
815{ 836{
816 dsp->gain = DEFAULT_GAIN; 837 dsp->data.gain = DEFAULT_GAIN;
817 838
818 /* Replay gain not relevant to voice */ 839 /* Replay gain not relevant to voice */
819 if (dsp == audio_dsp && replaygain) 840 if (dsp == audio_dsp && replaygain)
820 { 841 {
821 dsp->gain = replaygain; 842 dsp->data.gain = replaygain;
822 } 843 }
823 844
824 if (eq_enabled && eq_precut) 845 if (eq_enabled && eq_precut)
825 { 846 {
826 dsp->gain = (long) (((int64_t) dsp->gain * eq_precut) >> 24); 847 dsp->data.gain =
848 (long) (((int64_t) dsp->data.gain * eq_precut) >> 24);
827 } 849 }
828 850
829 if (dsp->gain == DEFAULT_GAIN) 851 if (dsp->data.gain == DEFAULT_GAIN)
830 { 852 {
831 dsp->gain = 0; 853 dsp->data.gain = 0;
832 } 854 }
833 else 855 else
834 { 856 {
835 dsp->gain >>= 1; 857 dsp->data.gain >>= 1;
836 } 858 }
859
860 dsp->apply_gain = dsp->data.gain != 0 ? dsp_apply_gain : NULL;
837} 861}
838 862
839/** 863/**
@@ -927,50 +951,6 @@ static void eq_process(int count, int32_t *buf[])
927 } 951 }
928} 952}
929 953
930/* Apply a constant gain to the samples (e.g., for ReplayGain). May update
931 * the src array if gain was applied.
932 * Note that this must be called before the resampler.
933 */
934static void apply_gain(int count, int32_t *buf[])
935{
936 int32_t *sl, *sr;
937 int32_t s, *d;
938 long gain;
939 int i;
940
941 if (new_gain)
942 {
943 /* Gain has changed */
944 dsp_set_replaygain();
945 if (dsp->gain == 0)
946 return; /* No gain to apply now */
947 }
948
949 sl = buf[0], sr = buf[1];
950 gain = dsp->gain;
951
952 if (sl != sr)
953 {
954 d = &sample_buf[SAMPLE_BUF_COUNT / 2];
955 buf[1] = d;
956 s = *sr++;
957
958 for (i = 0; i < count; i++)
959 FRACMUL_8_LOOP(s, gain, sr, d);
960 }
961 else
962 {
963 buf[1] = &sample_buf[0];
964 }
965
966 d = &sample_buf[0];
967 buf[0] = d;
968 s = *sl++;
969
970 for (i = 0; i < count; i++)
971 FRACMUL_8_LOOP(s, gain, sl, d);
972}
973
974void dsp_set_stereo_width(int value) 954void dsp_set_stereo_width(int value)
975{ 955{
976 long width, straight, cross; 956 long width, straight, cross;
@@ -993,35 +973,6 @@ void dsp_set_stereo_width(int value)
993 dsp_sw_cross = cross << 8; 973 dsp_sw_cross = cross << 8;
994} 974}
995 975
996/**
997 * Implements the different channel configurations and stereo width.
998 */
999
1000/* SOUND_CHAN_STEREO mode is a noop so has no function - just outline one for
1001 * completeness. */
1002#if 0
1003static void channels_process_sound_chan_stereo(int count, int32_t *buf[])
1004{
1005 /* The channels are each just themselves */
1006 (void)count; (void)buf;
1007}
1008#endif
1009
1010#ifndef DSP_HAVE_ASM_SOUND_CHAN_MONO
1011static void channels_process_sound_chan_mono(int count, int32_t *buf[])
1012{
1013 int32_t *sl = buf[0], *sr = buf[1];
1014
1015 do
1016 {
1017 int32_t lr = *sl/2 + *sr/2;
1018 *sl++ = lr;
1019 *sr++ = lr;
1020 }
1021 while (--count > 0);
1022}
1023#endif /* DSP_HAVE_ASM_SOUND_CHAN_MONO */
1024
1025#if CONFIG_CODEC == SWCODEC 976#if CONFIG_CODEC == SWCODEC
1026 977
1027#ifdef HAVE_SW_TONE_CONTROLS 978#ifdef HAVE_SW_TONE_CONTROLS
@@ -1063,6 +1014,35 @@ int dsp_callback(int msg, intptr_t param)
1063} 1014}
1064#endif 1015#endif
1065 1016
1017/**
1018 * Implements the different channel configurations and stereo width.
1019 */
1020
1021/* SOUND_CHAN_STEREO mode is a noop so has no function - just outline one for
1022 * completeness. */
1023#if 0
1024static void channels_process_sound_chan_stereo(int count, int32_t *buf[])
1025{
1026 /* The channels are each just themselves */
1027 (void)count; (void)buf;
1028}
1029#endif
1030
1031#ifndef DSP_HAVE_ASM_SOUND_CHAN_MONO
1032static void channels_process_sound_chan_mono(int count, int32_t *buf[])
1033{
1034 int32_t *sl = buf[0], *sr = buf[1];
1035
1036 do
1037 {
1038 int32_t lr = *sl/2 + *sr/2;
1039 *sl++ = lr;
1040 *sr++ = lr;
1041 }
1042 while (--count > 0);
1043}
1044#endif /* DSP_HAVE_ASM_SOUND_CHAN_MONO */
1045
1066#ifndef DSP_HAVE_ASM_SOUND_CHAN_CUSTOM 1046#ifndef DSP_HAVE_ASM_SOUND_CHAN_CUSTOM
1067static void channels_process_sound_chan_custom(int count, int32_t *buf[]) 1047static void channels_process_sound_chan_custom(int count, int32_t *buf[])
1068{ 1048{
@@ -1151,30 +1131,47 @@ int dsp_process(char *dst, const char *src[], int count)
1151 coldfire_set_macsr(EMAC_FRACTIONAL | EMAC_SATURATE); 1131 coldfire_set_macsr(EMAC_FRACTIONAL | EMAC_SATURATE);
1152#endif 1132#endif
1153 1133
1134 if (new_gain)
1135 dsp_set_replaygain(); /* Gain has changed */
1136
1137 /* Testing function pointers for NULL is preferred since the pointer
1138 will be preloaded to be used for the call if not. */
1154 while (count > 0) 1139 while (count > 0)
1155 { 1140 {
1156 samples = dsp->input_samples(count, src, tmp); 1141 samples = MIN(SAMPLE_BUF_COUNT/2, count);
1157 count -= samples; 1142 count -= samples;
1158 if (dsp->gain != 0) 1143
1159 apply_gain(samples, tmp); 1144 dsp->input_samples(samples, src, tmp);
1160 if ((samples = resample(samples, tmp)) <= 0) 1145
1146 if (dsp->apply_gain)
1147 dsp->apply_gain(samples, &dsp->data, tmp);
1148
1149 if (dsp->resample && (samples = resample(samples, tmp)) <= 0)
1161 break; /* I'm pretty sure we're downsampling here */ 1150 break; /* I'm pretty sure we're downsampling here */
1151
1162 if (dsp->apply_crossfeed) 1152 if (dsp->apply_crossfeed)
1163 dsp->apply_crossfeed(samples, tmp); 1153 dsp->apply_crossfeed(samples, tmp);
1154
1164 /* TODO: EQ and tone controls need separate structs for audio and voice 1155 /* TODO: EQ and tone controls need separate structs for audio and voice
1165 * DSP processing thanks to filter history. isn't really audible now, but 1156 * DSP processing thanks to filter history. isn't really audible now, but
1166 * might be the day we start handling voice more delicately. 1157 * might be the day we start handling voice more delicately. Planned
1158 * changes may well run all relevent channels through the same EQ so
1159 * perhaps not.
1167 */ 1160 */
1168 if (eq_enabled) 1161 if (eq_enabled)
1169 eq_process(samples, tmp); 1162 eq_process(samples, tmp);
1163
1170#ifdef HAVE_SW_TONE_CONTROLS 1164#ifdef HAVE_SW_TONE_CONTROLS
1171 if ((bass | treble) != 0) 1165 if ((bass | treble) != 0)
1172 eq_filter(tmp, &tone_filter, samples, dsp->data.num_channels, 1166 eq_filter(tmp, &tone_filter, samples, dsp->data.num_channels,
1173 FILTER_BISHELF_SHIFT); 1167 FILTER_BISHELF_SHIFT);
1174#endif 1168#endif
1169
1175 if (dsp->channels_process) 1170 if (dsp->channels_process)
1176 dsp->channels_process(samples, tmp); 1171 dsp->channels_process(samples, tmp);
1172
1177 dsp->output_samples(samples, &dsp->data, tmp, (int16_t *)dst); 1173 dsp->output_samples(samples, &dsp->data, tmp, (int16_t *)dst);
1174
1178 written += samples; 1175 written += samples;
1179 dst += samples * sizeof (int16_t) * 2; 1176 dst += samples * sizeof (int16_t) * 2;
1180 yield(); 1177 yield();
@@ -1245,9 +1242,6 @@ bool dsp_configure(int setting, intptr_t value)
1245 if (dsp == audio_dsp) 1242 if (dsp == audio_dsp)
1246 { 1243 {
1247 *var = value; 1244 *var = value;
1248 /* In case current gain is zero, force at least one call
1249 to apply_gain or apply_gain won't pick up on new_gain */
1250 audio_dsp->gain = -1;
1251 new_gain = true; 1245 new_gain = true;
1252 } 1246 }
1253 } 1247 }
@@ -1282,15 +1276,7 @@ bool dsp_configure(int setting, intptr_t value)
1282 else 1276 else
1283 dsp->frequency = dsp->codec_frequency; 1277 dsp->frequency = dsp->codec_frequency;
1284 1278
1285 resampler_set_delta(dsp->frequency); 1279 resampler_new_delta();
1286
1287 if (dsp->frequency == NATIVE_FREQUENCY)
1288 dsp->resample = NULL;
1289 else if (dsp->frequency < NATIVE_FREQUENCY)
1290 dsp->resample = dsp_upsample;
1291 else
1292 dsp->resample = dsp_downsample;
1293
1294 break; 1280 break;
1295 1281
1296 case DSP_SET_SAMPLE_DEPTH: 1282 case DSP_SET_SAMPLE_DEPTH:
@@ -1348,7 +1334,7 @@ bool dsp_configure(int setting, intptr_t value)
1348 case DSP_FLUSH: 1334 case DSP_FLUSH:
1349 memset(&dsp->data.resample_data, 0, 1335 memset(&dsp->data.resample_data, 0,
1350 sizeof (dsp->data.resample_data)); 1336 sizeof (dsp->data.resample_data));
1351 resampler_set_delta(dsp->frequency); 1337 resampler_new_delta();
1352 dither_init(); 1338 dither_init();
1353 break; 1339 break;
1354 1340