summaryrefslogtreecommitdiff
path: root/apps/dsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/dsp.c')
-rw-r--r--apps/dsp.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/apps/dsp.c b/apps/dsp.c
index de88c97ca6..f735456393 100644
--- a/apps/dsp.c
+++ b/apps/dsp.c
@@ -18,6 +18,7 @@
18 ****************************************************************************/ 18 ****************************************************************************/
19#include <inttypes.h> 19#include <inttypes.h>
20#include <string.h> 20#include <string.h>
21#include <sound.h>
21#include "dsp.h" 22#include "dsp.h"
22#include "eq.h" 23#include "eq.h"
23#include "kernel.h" 24#include "kernel.h"
@@ -224,6 +225,8 @@ struct crossfeed_data crossfeed_data IBSS_ATTR;
224static struct eq_state eq_data; 225static struct eq_state eq_data;
225 226
226static int pitch_ratio = 1000; 227static int pitch_ratio = 1000;
228static int channels_mode = 0;
229static int32_t sw_gain, sw_cross;
227 230
228extern int current_codec; 231extern int current_codec;
229struct dsp_config *dsp; 232struct dsp_config *dsp;
@@ -773,6 +776,70 @@ static void apply_gain(int32_t* _src[], int _count)
773 } 776 }
774} 777}
775 778
779void channels_set(int value)
780{
781 channels_mode = value;
782}
783
784void stereo_width_set(int value)
785{
786 long width, straight, cross;
787
788 width = value*0x7fffff/100;
789 if (value <= 100) {
790 straight = (0x7fffff + width)/2;
791 cross = straight - width;
792 } else {
793 straight = 0x7fffff;
794 cross = 0x7fffff - ((int64_t)(2*width) << 23)/(0x7fffff + width);
795 }
796 sw_gain = straight << 8;
797 sw_cross = cross << 8;
798}
799
800/* Implements the different channel configurations and stereo width.
801 * We might want to combine this with the write_samples stage for efficiency,
802 * but for now we'll just let it stay as a stage of its own.
803 */
804static void channels_process(int32_t **src, int num)
805{
806 int i;
807 int32_t *sl = src[0], *sr = src[1];
808
809 if (channels_mode == SOUND_CHAN_STEREO)
810 return;
811 switch (channels_mode) {
812 case SOUND_CHAN_MONO:
813 for (i = 0; i < num; i++)
814 sl[i] = sr[i] = sl[i]/2 + sr[i]/2;
815 break;
816 case SOUND_CHAN_CUSTOM:
817 for (i = 0; i < num; i++) {
818 int32_t left_sample = sl[i];
819
820 sl[i] = FRACMUL(sl[i], sw_gain) + FRACMUL(sr[i], sw_cross);
821 sr[i] = FRACMUL(sr[i], sw_gain) + FRACMUL(left_sample, sw_cross);
822 }
823 break;
824 case SOUND_CHAN_MONO_LEFT:
825 for (i = 0; i < num; i++)
826 sr[i] = sl[i];
827 break;
828 case SOUND_CHAN_MONO_RIGHT:
829 for (i = 0; i < num; i++)
830 sl[i] = sr[i];
831 break;
832 case SOUND_CHAN_KARAOKE:
833 for (i = 0; i < num; i++) {
834 int32_t left_sample = sl[i];
835
836 sl[i] -= sr[i];
837 sr[i] -= left_sample;
838 }
839 break;
840 }
841}
842
776static void write_samples(short* dst, int32_t* src[], int count) 843static void write_samples(short* dst, int32_t* src[], int count)
777{ 844{
778 int32_t* s0 = src[0]; 845 int32_t* s0 = src[0];
@@ -843,6 +910,8 @@ long dsp_process(char* dst, const char* src[], long size)
843 apply_crossfeed(tmp, samples); 910 apply_crossfeed(tmp, samples);
844 if (dsp->eq_enabled) 911 if (dsp->eq_enabled)
845 eq_process(tmp, samples); 912 eq_process(tmp, samples);
913 if (dsp->stereo_mode != STEREO_MONO)
914 channels_process(tmp, samples);
846 write_samples((short*) dst, tmp, samples); 915 write_samples((short*) dst, tmp, samples);
847 written += samples; 916 written += samples;
848 dst += samples * sizeof(short) * 2; 917 dst += samples * sizeof(short) * 2;