summaryrefslogtreecommitdiff
path: root/apps/dsp.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2007-02-07 00:51:50 +0000
committerMichael Sevakis <jethead71@rockbox.org>2007-02-07 00:51:50 +0000
commitaba6ca0881d1481b4047b2d7834d70ca2eb5c64b (patch)
tree6635b98840dcf4936b3c1ca641c00c32ea1b3e7f /apps/dsp.c
parentdd50c863e60488662dee8f28f7292389ade42bac (diff)
downloadrockbox-aba6ca0881d1481b4047b2d7834d70ca2eb5c64b.tar.gz
rockbox-aba6ca0881d1481b4047b2d7834d70ca2eb5c64b.zip
Fix resampling clicking as much as possible at the moment. 1) Upsampling clicked because of size inaccuracies returned by DSP. Fix by simplifying audio system to use per-channel sample count from codec to pcm buffer. 2) Downsampling affected by 1) and was often starting passed the end of the data when not enough was available to generate an output sample. Fix by clamping input range to last sample in buffer and using the last sample value in the buffer. A perfect fix will require a double buffering scheme on the resampler to sufficient data during small data transients on both ends at all times of the down ratio on input and the up ratio on output.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12218 a1c6a512-1295-4272-9138-f99709370657
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)