summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/SOURCES1
-rw-r--r--apps/dsp.c68
-rw-r--r--apps/dsp.h1
-rw-r--r--apps/lang/english.lang14
-rw-r--r--apps/menus/sound_menu.c4
-rw-r--r--apps/settings.c1
-rw-r--r--apps/settings.h1
-rw-r--r--apps/settings_list.c3
8 files changed, 88 insertions, 5 deletions
diff --git a/apps/SOURCES b/apps/SOURCES
index 419d24d7a8..abf373e77e 100644
--- a/apps/SOURCES
+++ b/apps/SOURCES
@@ -201,3 +201,4 @@ keymaps/keymap-hdd1630.c
#elif CONFIG_KEYPAD == IAUDIO67_PAD
keymaps/keymap-iaudio67.c
#endif
+tdspeed.c
diff --git a/apps/dsp.c b/apps/dsp.c
index cbae49ab69..4c1dc1f4e7 100644
--- a/apps/dsp.c
+++ b/apps/dsp.c
@@ -32,6 +32,7 @@
#include "replaygain.h"
#include "misc.h"
#include "debug.h"
+#include "tdspeed.h"
/* 16-bit samples are scaled based on these constants. The shift should be
* no more than 15.
@@ -41,8 +42,14 @@
#define NATIVE_DEPTH 16
/* If the buffer sizes change, check the assembly code! */
-#define SAMPLE_BUF_COUNT 256
-#define RESAMPLE_BUF_COUNT (256 * 4) /* Enough for 11,025 Hz -> 44,100 Hz*/
+#define SMALL_SAMPLE_BUF_COUNT 256
+#define SMALL_RESAMPLE_BUF_COUNT (256 * 4) /* Enough for 11,025 Hz -> 44,100 Hz*/
+#define BIG_SAMPLE_BUF_COUNT 4096
+#define BIG_RESAMPLE_BUF_COUNT (4096 * 4) /* Enough for 11,025 Hz -> 44,100 Hz*/
+int sample_buf_count;
+int resample_buf_count;
+#define SAMPLE_BUF_COUNT sample_buf_count
+#define RESAMPLE_BUF_COUNT resample_buf_count
#define DEFAULT_GAIN 0x01000000
#define SAMPLE_BUF_LEFT_CHANNEL 0
#define SAMPLE_BUF_RIGHT_CHANNEL (SAMPLE_BUF_COUNT/2)
@@ -163,6 +170,8 @@ struct dsp_config
int sample_depth;
int sample_bytes;
int stereo_mode;
+ bool tdspeed_active;
+ int tdspeed_factor; /* % */
int frac_bits;
#ifdef HAVE_SW_TONE_CONTROLS
/* Filter struct for software bass/treble controls */
@@ -226,8 +235,12 @@ static bool crossfeed_enabled;
* of copying needed is minimized for that case.
*/
-int32_t sample_buf[SAMPLE_BUF_COUNT] IBSS_ATTR;
-static int32_t resample_buf[RESAMPLE_BUF_COUNT] IBSS_ATTR;
+int32_t small_sample_buf[SMALL_SAMPLE_BUF_COUNT] IBSS_ATTR;
+static int32_t small_resample_buf[SMALL_RESAMPLE_BUF_COUNT] IBSS_ATTR;
+int32_t big_sample_buf[BIG_SAMPLE_BUF_COUNT];
+static int32_t big_resample_buf[BIG_RESAMPLE_BUF_COUNT];
+int32_t *sample_buf;
+static int32_t *resample_buf;
#if 0
/* Clip sample to arbitrary limits where range > 0 and min + range = max */
@@ -264,6 +277,30 @@ void sound_set_pitch(int permille)
audio_dsp.codec_frequency);
}
+void tdspeed_setup(struct dsp_config *dspc)
+{
+ if(dspc == &dsp_conf[CODEC_IDX_AUDIO]) {
+#if 0
+ mylog("tdspeed_setup: CODEC_IDX_AUDIO, factor %d, %d, %d\n",
+ dspc->tdspeed_factor, dspc->codec_frequency,
+ dspc->stereo_mode != STEREO_MONO);
+#endif
+ if(dspc->tdspeed_factor == 0 || dspc->tdspeed_factor == 100)
+ dspc->tdspeed_active = false;
+ else dspc->tdspeed_active
+ = tdspeed_init(dspc->codec_frequency == 0 ? NATIVE_FREQUENCY
+ : dspc->codec_frequency,
+ dspc->stereo_mode != STEREO_MONO,
+ dspc->tdspeed_factor);
+ }
+}
+
+void dsp_set_speed(int percent)
+{
+ dsp_conf[CODEC_IDX_AUDIO].tdspeed_factor = percent;
+ tdspeed_setup(&dsp_conf[CODEC_IDX_AUDIO]);
+}
+
/* Convert count samples to the internal format, if needed. Updates src
* to point past the samples "consumed" and dst is set to point to the
* samples to consume. Note that for mono, dst[0] equals dst[1], as there
@@ -1137,6 +1174,9 @@ int dsp_process(struct dsp_config *dsp, char *dst, const char *src[], int count)
dsp->input_samples(samples, src, tmp);
+ if(dsp->tdspeed_active)
+ samples = tdspeed_doit(tmp, samples);
+
if (dsp->apply_gain)
dsp->apply_gain(samples, &dsp->data, tmp);
@@ -1188,6 +1228,19 @@ int dsp_process(struct dsp_config *dsp, char *dst, const char *src[], int count)
/* dsp_input_size MUST be called afterwards */
int dsp_output_count(struct dsp_config *dsp, int count)
{
+ if(!dsp->tdspeed_active) {
+ sample_buf = small_sample_buf;
+ resample_buf = small_resample_buf;
+ sample_buf_count = SMALL_SAMPLE_BUF_COUNT;
+ resample_buf_count = SMALL_RESAMPLE_BUF_COUNT;
+ } else {
+ sample_buf = big_sample_buf;
+ resample_buf = big_resample_buf;
+ sample_buf_count = BIG_SAMPLE_BUF_COUNT;
+ resample_buf_count = BIG_RESAMPLE_BUF_COUNT;
+ }
+ if(dsp->tdspeed_active)
+ count = tdspeed_est_output_size(count);
if (dsp->resample)
{
count = (int)(((unsigned long)count * NATIVE_FREQUENCY
@@ -1221,6 +1274,9 @@ int dsp_input_count(struct dsp_config *dsp, int count)
dsp->data.resample_data.delta) >> 16);
}
+ if(dsp->tdspeed_active)
+ count = tdspeed_est_input_size(count);
+
return count;
}
@@ -1268,6 +1324,7 @@ intptr_t dsp_configure(struct dsp_config *dsp, int setting, intptr_t value)
dsp->frequency = dsp->codec_frequency;
resampler_new_delta(dsp);
+ tdspeed_setup(dsp);
break;
case DSP_SET_SAMPLE_DEPTH:
@@ -1297,6 +1354,7 @@ intptr_t dsp_configure(struct dsp_config *dsp, int setting, intptr_t value)
dsp->stereo_mode = value;
dsp->data.num_channels = value == STEREO_MONO ? 1 : 2;
dsp_update_functions(dsp);
+ tdspeed_setup(dsp);
break;
case DSP_RESET:
@@ -1321,6 +1379,7 @@ intptr_t dsp_configure(struct dsp_config *dsp, int setting, intptr_t value)
dsp_update_functions(dsp);
resampler_new_delta(dsp);
+ tdspeed_setup(dsp);
break;
case DSP_FLUSH:
@@ -1328,6 +1387,7 @@ intptr_t dsp_configure(struct dsp_config *dsp, int setting, intptr_t value)
sizeof (dsp->data.resample_data));
resampler_new_delta(dsp);
dither_init(dsp);
+ tdspeed_setup(dsp);
break;
case DSP_SET_TRACK_GAIN:
diff --git a/apps/dsp.h b/apps/dsp.h
index 1746a5cccc..d12c877d05 100644
--- a/apps/dsp.h
+++ b/apps/dsp.h
@@ -165,5 +165,6 @@ void sound_set_pitch(int r);
int sound_get_pitch(void);
int dsp_callback(int msg, intptr_t param);
void dsp_dither_enable(bool enable);
+void dsp_set_speed(int speed);
#endif
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index ea232df169..2d1c5f2801 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -12037,3 +12037,17 @@
recording: ""
</voice>
</phrase>
+<phrase>
+ id: LANG_SPEED
+ desc: time-domain speed compress/stretch
+ user:
+ <source>
+ *: "Speed"
+ </source>
+ <dest>
+ *: "Speed"
+ </dest>
+ <voice>
+ *: "Speed"
+ </voice>
+</phrase>
diff --git a/apps/menus/sound_menu.c b/apps/menus/sound_menu.c
index d953db93b3..8d80e3862d 100644
--- a/apps/menus/sound_menu.c
+++ b/apps/menus/sound_menu.c
@@ -89,6 +89,8 @@ MENUITEM_SETTING(stereo_width, &global_settings.stereo_width,
MENUITEM_SETTING(dithering_enabled,
&global_settings.dithering_enabled, lowlatency_callback);
+ MENUITEM_SETTING(sound_speed, &global_settings.sound_speed,
+ lowlatency_callback);
#endif
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
@@ -116,7 +118,7 @@ MAKE_MENU(sound_settings, ID2P(LANG_SOUND_SETTINGS), NULL, Icon_Audio,
#endif
&balance,&channel_config,&stereo_width
#if CONFIG_CODEC == SWCODEC
- ,&crossfeed_menu, &equalizer_menu, &dithering_enabled
+ ,&crossfeed_menu, &equalizer_menu, &dithering_enabled, &sound_speed
#endif
#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
,&loudness,&avc,&superbass,&mdb_enable,&mdb_strength
diff --git a/apps/settings.c b/apps/settings.c
index b681471ef1..b13037af61 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -913,6 +913,7 @@ void settings_apply(bool read_disk)
}
dsp_dither_enable(global_settings.dithering_enabled);
+ dsp_set_speed(global_settings.sound_speed);
#endif
#ifdef HAVE_SPDIF_POWER
diff --git a/apps/settings.h b/apps/settings.h
index 9ef8323276..69d476f486 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -633,6 +633,7 @@ struct user_settings
int eq_band4_gain; /* +/- dB */
bool dithering_enabled;
+ int sound_speed;
#endif
diff --git a/apps/settings_list.c b/apps/settings_list.c
index 0addf5ceff..b72be2465a 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -1106,6 +1106,9 @@ const struct settings_list settings[] = {
/* dithering */
OFFON_SETTING(F_SOUNDSETTING, dithering_enabled, LANG_DITHERING, false,
"dithering enabled", dsp_dither_enable),
+ INT_SETTING(0, sound_speed, LANG_SPEED, 100, "speed",
+ UNIT_INT, 35, 250, 5,
+ NULL, NULL, dsp_set_speed),
#endif
#ifdef HAVE_WM8758
SOUND_SETTING(F_NO_WRAP, bass_cutoff, LANG_BASS_CUTOFF,