diff options
Diffstat (limited to 'apps/dsp.c')
-rw-r--r-- | apps/dsp.c | 130 |
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 | ||
47 | struct dsp_config | 47 | struct 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 | ||
119 | static int32_t sample_buf[SAMPLE_BUF_SIZE] IBSS_ATTR; | 119 | static int32_t sample_buf[SAMPLE_BUF_COUNT] IBSS_ATTR; |
120 | static int32_t resample_buf[RESAMPLE_BUF_SIZE] IBSS_ATTR; | 120 | static int32_t resample_buf[RESAMPLE_BUF_COUNT] IBSS_ATTR; |
121 | 121 | ||
122 | int sound_get_pitch(void) | 122 | int sound_get_pitch(void) |
123 | { | 123 | { |
@@ -139,14 +139,14 @@ void sound_set_pitch(int permille) | |||
139 | */ | 139 | */ |
140 | static int convert_to_internal(const char* src[], int count, int32_t* dst[]) | 140 | static 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. */ |
234 | static long downsample(int32_t **dst, int32_t **src, int count, | 234 | static 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 | */ |
746 | long dsp_process(char* dst, const char* src[], long size) | 749 | int 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 */ |
797 | long dsp_output_size(long size) | 798 | int 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 | */ |
833 | long dsp_input_size(long size) | 822 | int 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 | ||
864 | int dsp_stereo_mode(void) | 840 | int dsp_stereo_mode(void) |