summaryrefslogtreecommitdiff
path: root/apps/dsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/dsp.c')
-rw-r--r--apps/dsp.c130
1 files changed, 53 insertions, 77 deletions
diff --git a/apps/dsp.c b/apps/dsp.c
index c4630ada77..f7eb48ed03 100644
--- a/apps/dsp.c
+++ b/apps/dsp.c
@@ -40,8 +40,8 @@
40#define WORD_FRACBITS 27 40#define WORD_FRACBITS 27
41 41
42#define NATIVE_DEPTH 16 42#define NATIVE_DEPTH 16
43#define SAMPLE_BUF_SIZE 256 43#define SAMPLE_BUF_COUNT 256
44#define RESAMPLE_BUF_SIZE (256 * 4) /* Enough for 11,025 Hz -> 44,100 Hz*/ 44#define RESAMPLE_BUF_COUNT (256 * 4) /* Enough for 11,025 Hz -> 44,100 Hz*/
45#define DEFAULT_GAIN 0x01000000 45#define DEFAULT_GAIN 0x01000000
46 46
47struct dsp_config 47struct dsp_config
@@ -116,8 +116,8 @@ static struct dsp_config *dsp;
116 * of copying needed is minimized for that case. 116 * of copying needed is minimized for that case.
117 */ 117 */
118 118
119static int32_t sample_buf[SAMPLE_BUF_SIZE] IBSS_ATTR; 119static int32_t sample_buf[SAMPLE_BUF_COUNT] IBSS_ATTR;
120static int32_t resample_buf[RESAMPLE_BUF_SIZE] IBSS_ATTR; 120static int32_t resample_buf[RESAMPLE_BUF_COUNT] IBSS_ATTR;
121 121
122int sound_get_pitch(void) 122int sound_get_pitch(void)
123{ 123{
@@ -139,14 +139,14 @@ void sound_set_pitch(int permille)
139 */ 139 */
140static int convert_to_internal(const char* src[], int count, int32_t* dst[]) 140static int convert_to_internal(const char* src[], int count, int32_t* dst[])
141{ 141{
142 count = MIN(SAMPLE_BUF_SIZE / 2, count); 142 count = MIN(SAMPLE_BUF_COUNT / 2, count);
143 143
144 if ((dsp->sample_depth <= NATIVE_DEPTH) 144 if ((dsp->sample_depth <= NATIVE_DEPTH)
145 || (dsp->stereo_mode == STEREO_INTERLEAVED)) 145 || (dsp->stereo_mode == STEREO_INTERLEAVED))
146 { 146 {
147 dst[0] = &sample_buf[0]; 147 dst[0] = &sample_buf[0];
148 dst[1] = (dsp->stereo_mode == STEREO_MONO) 148 dst[1] = (dsp->stereo_mode == STEREO_MONO)
149 ? dst[0] : &sample_buf[SAMPLE_BUF_SIZE / 2]; 149 ? dst[0] : &sample_buf[SAMPLE_BUF_COUNT / 2];
150 } 150 }
151 else 151 else
152 { 152 {
@@ -231,7 +231,7 @@ static void resampler_set_delta(int frequency)
231 231
232/* TODO: we really should have a separate set of resample functions for both 232/* TODO: we really should have a separate set of resample functions for both
233 mono and stereo to avoid all this internal branching and looping. */ 233 mono and stereo to avoid all this internal branching and looping. */
234static long downsample(int32_t **dst, int32_t **src, int count, 234static int downsample(int32_t **dst, int32_t **src, int count,
235 struct resample_data *r) 235 struct resample_data *r)
236{ 236{
237 long phase = r->phase; 237 long phase = r->phase;
@@ -246,11 +246,14 @@ static long downsample(int32_t **dst, int32_t **src, int count,
246 last_sample = r->last_sample[j]; 246 last_sample = r->last_sample[j];
247 /* Do we need last sample of previous frame for interpolation? */ 247 /* Do we need last sample of previous frame for interpolation? */
248 if (pos > 0) 248 if (pos > 0)
249 {
250 last_sample = src[j][pos - 1]; 249 last_sample = src[j][pos - 1];
251 } 250
252 *d[j]++ = last_sample + FRACMUL((phase & 0xffff) << 15, 251 /* Be sure starting position isn't passed the available data */
253 src[j][pos] - last_sample); 252 if (pos < count)
253 *d[j]++ = last_sample + FRACMUL((phase & 0xffff) << 15,
254 src[j][pos] - last_sample);
255 else /* This is kinda nasty but works somewhat well for now */
256 *d[j]++ = src[j][count - 1];
254 } 257 }
255 phase += delta; 258 phase += delta;
256 259
@@ -316,7 +319,7 @@ static inline int resample(int32_t* src[], int count)
316 319
317 if (dsp->frequency != NATIVE_FREQUENCY) 320 if (dsp->frequency != NATIVE_FREQUENCY)
318 { 321 {
319 int32_t* dst[2] = {&resample_buf[0], &resample_buf[RESAMPLE_BUF_SIZE / 2]}; 322 int32_t* dst[2] = {&resample_buf[0], &resample_buf[RESAMPLE_BUF_COUNT / 2]};
320 323
321 if (dsp->frequency < NATIVE_FREQUENCY) 324 if (dsp->frequency < NATIVE_FREQUENCY)
322 { 325 {
@@ -619,7 +622,7 @@ static void apply_gain(int32_t* _src[], int _count)
619 622
620 if (s0 != s1) 623 if (s0 != s1)
621 { 624 {
622 d = &sample_buf[SAMPLE_BUF_SIZE / 2]; 625 d = &sample_buf[SAMPLE_BUF_COUNT / 2];
623 src[1] = d; 626 src[1] = d;
624 s = *s1++; 627 s = *s1++;
625 628
@@ -736,18 +739,17 @@ static void write_samples(short* dst, int32_t* src[], int count)
736} 739}
737 740
738/* Process and convert src audio to dst based on the DSP configuration, 741/* Process and convert src audio to dst based on the DSP configuration,
739 * reading size bytes of audio data. dst is assumed to be large enough; use 742 * reading count number of audio samples. dst is assumed to be large
740 * dst_get_dest_size() to get the required size. src is an array of 743 * enough; use dsp_output_count() to get the required number. src is an
741 * pointers; for mono and interleaved stereo, it contains one pointer to the 744 * array of pointers; for mono and interleaved stereo, it contains one
742 * start of the audio data; for non-interleaved stereo, it contains two 745 * pointer to the start of the audio data and the other is ignored; for
743 * pointers, one for each audio channel. Returns number of bytes written to 746 * non-interleaved stereo, it contains two pointers, one for each audio
744 * dest. 747 * channel. Returns number of bytes written to dst.
745 */ 748 */
746long dsp_process(char* dst, const char* src[], long size) 749int dsp_process(char *dst, const char *src[], int count)
747{ 750{
748 int32_t* tmp[2]; 751 int32_t* tmp[2];
749 long written = 0; 752 int written = 0;
750 long factor;
751 int samples; 753 int samples;
752 754
753 #if defined(CPU_COLDFIRE) && !defined(SIMULATOR) 755 #if defined(CPU_COLDFIRE) && !defined(SIMULATOR)
@@ -759,14 +761,12 @@ long dsp_process(char* dst, const char* src[], long size)
759 761
760 dsp = &dsp_conf[current_codec]; 762 dsp = &dsp_conf[current_codec];
761 763
762 factor = (dsp->stereo_mode != STEREO_MONO) ? 2 : 1;
763 size /= dsp->sample_bytes * factor;
764 dsp_set_replaygain(false); 764 dsp_set_replaygain(false);
765 765
766 while (size > 0) 766 while (count > 0)
767 { 767 {
768 samples = convert_to_internal(src, size, tmp); 768 samples = convert_to_internal(src, count, tmp);
769 size -= samples; 769 count -= samples;
770 apply_gain(tmp, samples); 770 apply_gain(tmp, samples);
771 samples = resample(tmp, samples); 771 samples = resample(tmp, samples);
772 if (dsp->crossfeed_enabled && dsp->stereo_mode != STEREO_MONO) 772 if (dsp->crossfeed_enabled && dsp->stereo_mode != STEREO_MONO)
@@ -780,85 +780,61 @@ long dsp_process(char* dst, const char* src[], long size)
780 dst += samples * sizeof(short) * 2; 780 dst += samples * sizeof(short) * 2;
781 yield(); 781 yield();
782 } 782 }
783
783 #if defined(CPU_COLDFIRE) && !defined(SIMULATOR) 784 #if defined(CPU_COLDFIRE) && !defined(SIMULATOR)
784 /* set old macsr again */ 785 /* set old macsr again */
785 coldfire_set_macsr(old_macsr); 786 coldfire_set_macsr(old_macsr);
786 #endif 787 #endif
787 return written * sizeof(short) * 2; 788 return written;
788} 789}
789 790
790/* Given size bytes of input data, calculate the maximum number of bytes of 791/* Given count number of input samples, calculate the maximum number of
791 * output data that would be generated (the calculation is not entirely 792 * samples of output data that would be generated (the calculation is not
792 * exact and rounds upwards to be on the safe side; during resampling, 793 * entirely exact and rounds upwards to be on the safe side; during
793 * the number of samples generated depends on the current state of the 794 * resampling, the number of samples generated depends on the current state
794 * resampler). 795 * of the resampler).
795 */ 796 */
796/* dsp_input_size MUST be called afterwards */ 797/* dsp_input_size MUST be called afterwards */
797long dsp_output_size(long size) 798int dsp_output_count(int count)
798{ 799{
799 dsp = &dsp_conf[current_codec]; 800 dsp = &dsp_conf[current_codec];
800 801
801 if (dsp->sample_depth > NATIVE_DEPTH)
802 {
803 size /= 2;
804 }
805
806 if (dsp->frequency != NATIVE_FREQUENCY) 802 if (dsp->frequency != NATIVE_FREQUENCY)
807 { 803 {
808 size = (long) ((((unsigned long) size * NATIVE_FREQUENCY) 804 count = (int)(((unsigned long)count * NATIVE_FREQUENCY
809 + (dsp->frequency - 1)) / dsp->frequency); 805 + (dsp->frequency - 1)) / dsp->frequency);
810 }
811
812 /* round to the next multiple of 2 (these are shorts) */
813 size = (size + 1) & ~1;
814
815 if (dsp->stereo_mode == STEREO_MONO)
816 {
817 size *= 2;
818 } 806 }
819 807
820 /* now we have the size in bytes for two resampled channels, 808 /* Now we have the resampled sample count which must not exceed
821 * and the size in (short) must not exceed RESAMPLE_BUF_SIZE to 809 * RESAMPLE_BUF_COUNT/2 to avoid resample buffer overflow. One
822 * avoid resample buffer overflow. One must call dsp_input_size() 810 * must call dsp_input_count() to get the correct input sample
823 * to get the correct input buffer size. */ 811 * count.
824 if (size > RESAMPLE_BUF_SIZE*2) 812 */
825 size = RESAMPLE_BUF_SIZE*2; 813 if (count > RESAMPLE_BUF_COUNT/2)
814 count = RESAMPLE_BUF_COUNT/2;
826 815
827 return size; 816 return count;
828} 817}
829 818
830/* Given size bytes of output buffer, calculate number of bytes of input 819/* Given count output samples, calculate number of input samples
831 * data that would be consumed in order to fill the output buffer. 820 * that would be consumed in order to fill the output buffer.
832 */ 821 */
833long dsp_input_size(long size) 822int dsp_input_count(int count)
834{ 823{
835 dsp = &dsp_conf[current_codec]; 824 dsp = &dsp_conf[current_codec];
836
837 /* convert to number of output stereo samples. */
838 size /= 2;
839 825
840 /* Mono means we need half input samples to fill the output buffer */ 826 /* count is now the number of resampled input samples. Convert to
841 if (dsp->stereo_mode == STEREO_MONO)
842 size /= 2;
843
844 /* size is now the number of resampled input samples. Convert to
845 original input samples. */ 827 original input samples. */
846 if (dsp->frequency != NATIVE_FREQUENCY) 828 if (dsp->frequency != NATIVE_FREQUENCY)
847 { 829 {
848 /* Use the real resampling delta = 830 /* Use the real resampling delta =
849 * (unsigned long) dsp->frequency * 65536 / NATIVE_FREQUENCY, and 831 * dsp->frequency * 65536 / NATIVE_FREQUENCY, and
850 * round towards zero to avoid buffer overflows. */ 832 * round towards zero to avoid buffer overflows. */
851 size = ((unsigned long)size * 833 count = (int)(((unsigned long)count *
852 resample_data[current_codec].delta) >> 16; 834 resample_data[current_codec].delta) >> 16);
853 } 835 }
854 836
855 /* Convert back to bytes. */ 837 return count;
856 if (dsp->sample_depth > NATIVE_DEPTH)
857 size *= 4;
858 else
859 size *= 2;
860
861 return size;
862} 838}
863 839
864int dsp_stereo_mode(void) 840int dsp_stereo_mode(void)