summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/dsp.c69
-rw-r--r--apps/dsp.h3
-rw-r--r--apps/settings.c5
-rw-r--r--apps/sound_menu.c13
-rw-r--r--firmware/sound.c16
5 files changed, 105 insertions, 1 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;
diff --git a/apps/dsp.h b/apps/dsp.h
index c20def03b7..8b8b164d6e 100644
--- a/apps/dsp.h
+++ b/apps/dsp.h
@@ -57,4 +57,7 @@ void dsp_set_crossfeed(bool enable);
57void dsp_eq_update_data(bool enabled, int band); 57void dsp_eq_update_data(bool enabled, int band);
58void sound_set_pitch(int r); 58void sound_set_pitch(int r);
59int sound_get_pitch(void); 59int sound_get_pitch(void);
60void channels_set(int value);
61void stereo_width_set(int value);
62
60#endif 63#endif
diff --git a/apps/settings.c b/apps/settings.c
index 7329b12a76..f5c0ba7c2d 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -950,8 +950,13 @@ void sound_settings_apply(void)
950 sound_set(SOUND_TREBLE, global_settings.treble); 950 sound_set(SOUND_TREBLE, global_settings.treble);
951 sound_set(SOUND_BALANCE, global_settings.balance); 951 sound_set(SOUND_BALANCE, global_settings.balance);
952 sound_set(SOUND_VOLUME, global_settings.volume); 952 sound_set(SOUND_VOLUME, global_settings.volume);
953#if CONFIG_CODEC == SWCODEC
954 channels_set(global_settings.channel_config);
955 stereo_width_set(global_settings.stereo_width);
956#else
953 sound_set(SOUND_CHANNELS, global_settings.channel_config); 957 sound_set(SOUND_CHANNELS, global_settings.channel_config);
954 sound_set(SOUND_STEREO_WIDTH, global_settings.stereo_width); 958 sound_set(SOUND_STEREO_WIDTH, global_settings.stereo_width);
959#endif
955#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) 960#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
956 sound_set(SOUND_LOUDNESS, global_settings.loudness); 961 sound_set(SOUND_LOUDNESS, global_settings.loudness);
957 sound_set(SOUND_AVC, global_settings.avc); 962 sound_set(SOUND_AVC, global_settings.avc);
diff --git a/apps/sound_menu.c b/apps/sound_menu.c
index 52a8d4e6e1..1c61c6630a 100644
--- a/apps/sound_menu.c
+++ b/apps/sound_menu.c
@@ -83,6 +83,14 @@ bool set_sound(const unsigned char * string,
83 else if (*unit == 'H') 83 else if (*unit == 'H')
84 talkunit = UNIT_HERTZ; 84 talkunit = UNIT_HERTZ;
85 if(!numdec) 85 if(!numdec)
86#if CONFIG_CODEC == SWCODEC
87 /* We need to hijack this one and send it off to apps/dsp.c instead of
88 firmware/sound.c */
89 if (setting == SOUND_STEREO_WIDTH)
90 return set_int(string, unit, talkunit, variable, &stereo_width_set,
91 steps, min, max, NULL );
92 else
93#endif
86 return set_int(string, unit, talkunit, variable, sound_callback, 94 return set_int(string, unit, talkunit, variable, sound_callback,
87 steps, min, max, NULL ); 95 steps, min, max, NULL );
88 else 96 else
@@ -375,8 +383,13 @@ static bool chanconf(void)
375 { STR(LANG_CHANNEL_RIGHT) }, 383 { STR(LANG_CHANNEL_RIGHT) },
376 { STR(LANG_CHANNEL_KARAOKE) } 384 { STR(LANG_CHANNEL_KARAOKE) }
377 }; 385 };
386#if CONFIG_CODEC == SWCODEC
387 return set_option(str(LANG_CHANNEL), &global_settings.channel_config, INT,
388 names, 6, channels_set);
389#else
378 return set_option(str(LANG_CHANNEL), &global_settings.channel_config, INT, 390 return set_option(str(LANG_CHANNEL), &global_settings.channel_config, INT,
379 names, 6, sound_set_channels); 391 names, 6, sound_set_channels);
392#endif
380} 393}
381 394
382static bool stereo_width(void) 395static bool stereo_width(void)
diff --git a/firmware/sound.c b/firmware/sound.c
index 501e01e2d4..a3eb6da8a8 100644
--- a/firmware/sound.c
+++ b/firmware/sound.c
@@ -458,10 +458,14 @@ static void set_prescaled_volume(void)
458#endif /* (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 */ 458#endif /* (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 */
459#endif /* !SIMULATOR */ 459#endif /* !SIMULATOR */
460 460
461#if CONFIG_CODEC != SWCODEC
461int channel_configuration = SOUND_CHAN_STEREO; 462int channel_configuration = SOUND_CHAN_STEREO;
462int stereo_width = 100; 463int stereo_width = 100;
464#endif
463 465
464#ifndef SIMULATOR 466#ifndef SIMULATOR
467
468#if CONFIG_CODEC != SWCODEC
465static void set_channel_config(void) 469static void set_channel_config(void)
466{ 470{
467 /* default values: stereo */ 471 /* default values: stereo */
@@ -540,6 +544,8 @@ static void set_channel_config(void)
540#endif 544#endif
541} 545}
542 546
547#endif /* CONFIG_CODEC != SWCODEC */
548
543#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) 549#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
544unsigned long mdb_shape_shadow = 0; 550unsigned long mdb_shape_shadow = 0;
545unsigned long loudness_shadow = 0; 551unsigned long loudness_shadow = 0;
@@ -631,19 +637,27 @@ void sound_set_treble(int value)
631 637
632void sound_set_channels(int value) 638void sound_set_channels(int value)
633{ 639{
640#if CONFIG_CODEC == SWCODEC
641 (void)value;
642#else
634 if(!audio_is_initialized) 643 if(!audio_is_initialized)
635 return; 644 return;
636 channel_configuration = value; 645 channel_configuration = value;
637 set_channel_config(); 646 set_channel_config();
647#endif
638} 648}
639 649
640void sound_set_stereo_width(int value) 650void sound_set_stereo_width(int value)
641{ 651{
652#if CONFIG_CODEC == SWCODEC
653 (void)value;
654#else
642 if(!audio_is_initialized) 655 if(!audio_is_initialized)
643 return; 656 return;
644 stereo_width = value; 657 stereo_width = value;
645 if (channel_configuration == SOUND_CHAN_CUSTOM) 658 if (channel_configuration == SOUND_CHAN_CUSTOM)
646 set_channel_config(); 659 set_channel_config();
660#endif
647} 661}
648 662
649#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) 663#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)