summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/codec_thread.c56
-rw-r--r--apps/codecs.c2
-rw-r--r--apps/gui/bitmap/list-skinned.c2
-rw-r--r--apps/gui/bitmap/list.c2
-rw-r--r--apps/gui/option_select.c1
-rw-r--r--apps/main.c7
-rw-r--r--apps/menus/eq_menu.c12
-rw-r--r--apps/pcmbuf.c40
-rw-r--r--apps/plugin.c12
-rw-r--r--apps/plugin.h22
-rw-r--r--apps/plugins/SOURCES1
-rw-r--r--apps/plugins/mpegplayer/audio_thread.c56
-rw-r--r--apps/plugins/mpegplayer/mpeg_settings.c8
-rw-r--r--apps/plugins/test_codec.c51
-rw-r--r--apps/settings.c11
-rw-r--r--apps/settings.h18
-rw-r--r--apps/settings_list.c2
-rw-r--r--apps/voice_thread.c37
18 files changed, 181 insertions, 159 deletions
diff --git a/apps/codec_thread.c b/apps/codec_thread.c
index 39db741054..17ca980e41 100644
--- a/apps/codec_thread.c
+++ b/apps/codec_thread.c
@@ -213,49 +213,41 @@ void codec_thread_do_callback(void (*fn)(void), unsigned int *id)
static void codec_pcmbuf_insert_callback(
const void *ch1, const void *ch2, int count)
{
- const char *src[2] = { ch1, ch2 };
+ struct dsp_buffer src;
- while (count > 0)
+ src.remcount = count;
+ src.pin[0] = ch1;
+ src.pin[1] = ch2;
+ src.proc_mask = 0;
+
+ while (1)
{
- int out_count = dsp_output_count(ci.dsp, count);
- int inp_count;
- char *dest;
+ struct dsp_buffer dst;
+ dst.remcount = 0;
+ dst.bufcount = MAX(src.remcount, 1024); /* Arbitrary min request */
- while (1)
+ while ((dst.p16out = pcmbuf_request_buffer(&dst.bufcount)) == NULL)
{
- if ((dest = pcmbuf_request_buffer(&out_count)) != NULL)
- break;
-
cancel_cpu_boost();
- /* It will be awhile before space is available but we want
+ /* It may be awhile before space is available but we want
"instant" response to any message */
queue_wait_w_tmo(&codec_queue, NULL, HZ/20);
if (!queue_empty(&codec_queue) &&
codec_check_queue__have_msg() < 0)
+ {
+ dsp_configure(ci.dsp, DSP_FLUSH, 0); /* Discontinuity */
return;
+ }
}
- /* Get the real input_size for output_size bytes, guarding
- * against resampling buffer overflows. */
- inp_count = dsp_input_count(ci.dsp, out_count);
-
- if (inp_count <= 0)
- return;
-
- /* Input size has grown, no error, just don't write more than length */
- if (inp_count > count)
- inp_count = count;
+ dsp_process(ci.dsp, &src, &dst);
- out_count = dsp_process(ci.dsp, dest, src, inp_count);
-
- if (out_count <= 0)
- return;
-
- pcmbuf_write_complete(out_count, ci.id3->elapsed, ci.id3->offset);
-
- count -= inp_count;
+ if (dst.remcount > 0)
+ pcmbuf_write_complete(dst.remcount, ci.id3->elapsed, ci.id3->offset);
+ else if (src.remcount <= 0)
+ break; /* No input remains and DSP purged */
}
}
@@ -352,10 +344,7 @@ static void codec_seek_complete_callback(void)
static void codec_configure_callback(int setting, intptr_t value)
{
- if (!dsp_configure(ci.dsp, setting, value))
- {
- logf("Illegal key: %d", setting);
- }
+ dsp_configure(ci.dsp, setting, value);
}
static enum codec_command_action
@@ -611,8 +600,7 @@ static void NORETURN_ATTR codec_thread(void)
void codec_thread_init(void)
{
/* Init API */
- ci.dsp = (struct dsp_config *)dsp_configure(NULL, DSP_MYDSP,
- CODEC_IDX_AUDIO);
+ ci.dsp = dsp_get_config(CODEC_IDX_AUDIO);
ci.codec_get_buffer = codec_get_buffer_callback;
ci.pcmbuf_insert = codec_pcmbuf_insert_callback;
ci.set_elapsed = audio_codec_update_elapsed;
diff --git a/apps/codecs.c b/apps/codecs.c
index fafe4ac7a3..69204b7c4f 100644
--- a/apps/codecs.c
+++ b/apps/codecs.c
@@ -118,6 +118,7 @@ struct codec_api ci = {
commit_dcache,
commit_discard_dcache,
+ commit_discard_idcache,
/* strings and memory */
strcpy,
@@ -166,7 +167,6 @@ struct codec_api ci = {
/* new stuff at the end, sort into place next time
the API gets incompatible */
- commit_discard_idcache,
};
void codec_get_full_path(char *path, const char *codec_root_fn)
diff --git a/apps/gui/bitmap/list-skinned.c b/apps/gui/bitmap/list-skinned.c
index 95430ae278..7d3620ed81 100644
--- a/apps/gui/bitmap/list-skinned.c
+++ b/apps/gui/bitmap/list-skinned.c
@@ -20,13 +20,13 @@
****************************************************************************/
#include "config.h"
+#include "system.h"
#include "lcd.h"
#include "font.h"
#include "button.h"
#include "string.h"
#include "settings.h"
#include "kernel.h"
-#include "system.h"
#include "file.h"
#include "action.h"
diff --git a/apps/gui/bitmap/list.c b/apps/gui/bitmap/list.c
index 0581050091..49479c1cb3 100644
--- a/apps/gui/bitmap/list.c
+++ b/apps/gui/bitmap/list.c
@@ -22,13 +22,13 @@
/* This file contains the code to draw the list widget on BITMAP LCDs. */
#include "config.h"
+#include "system.h"
#include "lcd.h"
#include "font.h"
#include "button.h"
#include "string.h"
#include "settings.h"
#include "kernel.h"
-#include "system.h"
#include "file.h"
#include "action.h"
diff --git a/apps/gui/option_select.c b/apps/gui/option_select.c
index 7c3d34f024..ca206b86da 100644
--- a/apps/gui/option_select.c
+++ b/apps/gui/option_select.c
@@ -22,6 +22,7 @@
#include <stdlib.h>
#include "string-extra.h"
#include "config.h"
+#include "system.h"
#include "option_select.h"
#include "kernel.h"
#include "lang.h"
diff --git a/apps/main.c b/apps/main.c
index 631236852e..0fff0846a6 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -384,6 +384,9 @@ static void init(void)
viewportmanager_init();
storage_init();
+#if CONFIG_CODEC == SWCODEC
+ dsp_init();
+#endif
settings_reset();
settings_load(SETTINGS_ALL);
settings_apply(true);
@@ -632,6 +635,10 @@ static void init(void)
}
}
+#if CONFIG_CODEC == SWCODEC
+ dsp_init();
+#endif
+
#if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \
(CONFIG_KEYPAD == IRIVER_H10_PAD)
#ifdef SETTINGS_RESET
diff --git a/apps/menus/eq_menu.c b/apps/menus/eq_menu.c
index 2cfb80f76a..60b2687050 100644
--- a/apps/menus/eq_menu.c
+++ b/apps/menus/eq_menu.c
@@ -70,13 +70,11 @@ const char* eq_precut_format(char* buffer, size_t buffer_size, int value, const
*/
static void eq_apply(void)
{
- dsp_set_eq(global_settings.eq_enabled);
+ dsp_eq_enable(global_settings.eq_enabled);
dsp_set_eq_precut(global_settings.eq_precut);
/* Update all bands */
- for(int i = 0; i < 5; i++) {
- dsp_set_eq_coefs(i, global_settings.eq_band_settings[i].cutoff,
- global_settings.eq_band_settings[i].q,
- global_settings.eq_band_settings[i].gain);
+ for(int i = 0; i < EQ_NUM_BANDS; i++) {
+ dsp_set_eq_coefs(i, &global_settings.eq_band_settings[i]);
}
}
@@ -580,9 +578,7 @@ bool eq_menu_graphical(void)
/* Update the filter if the user changed something */
if (has_changed) {
dsp_set_eq_coefs(current_band,
- global_settings.eq_band_settings[current_band].cutoff,
- global_settings.eq_band_settings[current_band].q,
- global_settings.eq_band_settings[current_band].gain);
+ &global_settings.eq_band_settings[current_band]);
has_changed = false;
}
}
diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c
index d36883fc5b..9cedae0b67 100644
--- a/apps/pcmbuf.c
+++ b/apps/pcmbuf.c
@@ -47,16 +47,23 @@
smaller math - must be < 65536 bytes */
#define PCMBUF_CHUNK_SIZE 8192u
-/* Massive size is a nasty temp fix */
-#define PCMBUF_GUARD_SIZE (1024u*12*((NATIVE_FREQUENCY+7999)/8000))
+/* Small guard buf to give decent space near end */
+#define PCMBUF_GUARD_SIZE (PCMBUF_CHUNK_SIZE / 8)
/* Mnemonics for common data commit thresholds */
#define COMMIT_CHUNKS PCMBUF_CHUNK_SIZE
#define COMMIT_ALL_DATA 1u
- /* Size of the crossfade buffer where codec data is written to be faded
- on commit */
-#define CROSSFADE_BUFSIZE 8192u
+/* Size of the crossfade buffer where codec data is written to be faded
+ on commit */
+#define CROSSFADE_BUFSIZE PCMBUF_CHUNK_SIZE
+
+/* Maximum contiguous space that PCM buffer will allow (to avoid excessive
+ draining between inserts and observe low-latency mode) */
+#define PCMBUF_MAX_BUFFER (PCMBUF_CHUNK_SIZE * 4)
+
+/* Forced buffer insert constraint can thus be from 1KB to 32KB using 8KB
+ chunks */
/* Return data level in 1/4-second increments */
#define DATA_LEVEL(quarter_secs) (NATIVE_FREQUENCY * (quarter_secs))
@@ -383,7 +390,11 @@ void * pcmbuf_request_buffer(int *count)
/* If crossfade has begun, put the new track samples in crossfade_buffer */
if (crossfade_status != CROSSFADE_INACTIVE && size > CROSSFADE_BUFSIZE)
size = CROSSFADE_BUFSIZE;
-#endif
+ else
+#endif /* HAVE_CROSSFADE */
+
+ if (size > PCMBUF_MAX_BUFFER)
+ size = PCMBUF_MAX_BUFFER; /* constrain */
enum channel_status status = mixer_channel_status(PCM_MIXER_CHAN_PLAYBACK);
size_t remaining = pcmbuf_unplayed_bytes();
@@ -432,11 +443,22 @@ void * pcmbuf_request_buffer(int *count)
pcmbuf_play_start();
}
- void *buf =
+ void *buf;
+
#ifdef HAVE_CROSSFADE
- crossfade_status != CROSSFADE_INACTIVE ? crossfade_buffer :
+ if (crossfade_status != CROSSFADE_INACTIVE)
+ {
+ buf = crossfade_buffer; /* always CROSSFADE_BUFSIZE */
+ }
+ else
#endif
- get_write_buffer(&size);
+ {
+ /* Give the maximum amount available if there's more */
+ if (size + PCMBUF_CHUNK_SIZE < freespace)
+ size = freespace - PCMBUF_CHUNK_SIZE;
+
+ buf = get_write_buffer(&size);
+ }
*count = size / 4;
return buf;
diff --git a/apps/plugin.c b/apps/plugin.c
index 5406610e23..129fd6954e 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -565,13 +565,15 @@ static const struct plugin_api rockbox_api = {
audio_set_output_source,
audio_set_input_source,
#endif
- dsp_set_crossfeed,
- dsp_set_eq,
+ dsp_crossfeed_enable,
+ dsp_eq_enable,
dsp_dither_enable,
+#ifdef HAVE_PITCHSCREEN
+ dsp_set_timestretch,
+#endif
dsp_configure,
+ dsp_get_config,
dsp_process,
- dsp_input_count,
- dsp_output_count,
mixer_channel_status,
mixer_channel_get_buffer,
@@ -584,7 +586,7 @@ static const struct plugin_api rockbox_api = {
system_sound_play,
keyclick_click,
-#endif
+#endif /* CONFIG_CODEC == SWCODEC */
/* playback control */
playlist_amount,
playlist_resume,
diff --git a/apps/plugin.h b/apps/plugin.h
index 8123414ff0..3820c7ede6 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -153,12 +153,12 @@ void* plugin_get_buffer(size_t *buffer_size);
#define PLUGIN_MAGIC 0x526F634B /* RocK */
/* increase this every time the api struct changes */
-#define PLUGIN_API_VERSION 218
+#define PLUGIN_API_VERSION 219
/* update this to latest version if a change to the api struct breaks
backwards compatibility (and please take the opportunity to sort in any
new function which are "waiting" at the end of the function table) */
-#define PLUGIN_MIN_API_VERSION 218
+#define PLUGIN_MIN_API_VERSION 219
/* plugin return codes */
/* internal returns start at 0x100 to make exit(1..255) work */
@@ -680,15 +680,17 @@ struct plugin_api {
void (*audio_set_output_source)(int monitor);
void (*audio_set_input_source)(int source, unsigned flags);
#endif
- void (*dsp_set_crossfeed)(bool enable);
- void (*dsp_set_eq)(bool enable);
+ void (*dsp_crossfeed_enable)(bool enable);
+ void (*dsp_eq_enable)(bool enable);
void (*dsp_dither_enable)(bool enable);
- intptr_t (*dsp_configure)(struct dsp_config *dsp, int setting,
- intptr_t value);
- int (*dsp_process)(struct dsp_config *dsp, char *dest,
- const char *src[], int count);
- int (*dsp_input_count)(struct dsp_config *dsp, int count);
- int (*dsp_output_count)(struct dsp_config *dsp, int count);
+#ifdef HAVE_PITCHSCREEN
+ void (*dsp_set_timestretch)(int32_t percent);
+#endif
+ intptr_t (*dsp_configure)(struct dsp_config *dsp,
+ unsigned int setting, intptr_t value);
+ struct dsp_config * (*dsp_get_config)(enum dsp_ids id);
+ void (*dsp_process)(struct dsp_config *dsp, struct dsp_buffer *src,
+ struct dsp_buffer *dst);
enum channel_status (*mixer_channel_status)(enum pcm_mixer_channel channel);
const void * (*mixer_channel_get_buffer)(enum pcm_mixer_channel channel,
diff --git a/apps/plugins/SOURCES b/apps/plugins/SOURCES
index db690a638a..e5f026c5b4 100644
--- a/apps/plugins/SOURCES
+++ b/apps/plugins/SOURCES
@@ -33,6 +33,7 @@ flipit.c
shopper.c
resistor.c
+test_codec.c
#ifdef USB_ENABLE_HID
remote_control.c
diff --git a/apps/plugins/mpegplayer/audio_thread.c b/apps/plugins/mpegplayer/audio_thread.c
index f976fd6007..b06727f759 100644
--- a/apps/plugins/mpegplayer/audio_thread.c
+++ b/apps/plugins/mpegplayer/audio_thread.c
@@ -36,6 +36,7 @@ struct audio_thread_data
unsigned samplerate; /* Current stream sample rate */
int nchannels; /* Number of audio channels */
struct dsp_config *dsp; /* The DSP we're using */
+ struct dsp_buffer src; /* Current audio data for DSP processing */
};
/* The audio thread is stolen from the core codec thread */
@@ -479,12 +480,13 @@ static void audio_thread(void)
/* We need this here to init the EMAC for Coldfire targets */
init_mad();
- td.dsp = (struct dsp_config *)rb->dsp_configure(NULL, DSP_MYDSP,
- CODEC_IDX_AUDIO);
+ td.dsp = rb->dsp_get_config(CODEC_IDX_AUDIO);
#ifdef HAVE_PITCHSCREEN
rb->sound_set_pitch(PITCH_SPEED_100);
+ rb->dsp_set_timestretch(PITCH_SPEED_100);
#endif
rb->dsp_configure(td.dsp, DSP_RESET, 0);
+ rb->dsp_configure(td.dsp, DSP_FLUSH, 0);
rb->dsp_configure(td.dsp, DSP_SET_SAMPLE_DEPTH, MAD_F_FRACBITS);
goto message_wait;
@@ -631,43 +633,53 @@ static void audio_thread(void)
STEREO_MONO : STEREO_NONINTERLEAVED);
}
+ td.src.remcount = synth.pcm.length;
+ td.src.pin[0] = synth.pcm.samples[0];
+ td.src.pin[1] = synth.pcm.samples[1];
+ td.src.proc_mask = 0;
+
td.state = TSTATE_RENDER_WAIT;
/* Add a frame of audio to the pcm buffer. Maximum is 1152 samples. */
render_wait:
- if (synth.pcm.length > 0)
+ rb->yield();
+
+ while (1)
{
- const char *src[2] =
- { (char *)synth.pcm.samples[0], (char *)synth.pcm.samples[1] };
- int out_count = (synth.pcm.length * CLOCK_RATE
- + (td.samplerate - 1)) / td.samplerate;
- unsigned char *out_buf;
- ssize_t size = out_count*4;
+ struct dsp_buffer dst;
+ dst.remcount = 0;
+ dst.bufcount = MAX(td.src.remcount, 1024);
+
+ ssize_t size = dst.bufcount * 2 * sizeof(int16_t);
/* Wait for required amount of free buffer space */
- while ((out_buf = pcm_output_get_buffer(&size)) == NULL)
+ while ((dst.p16out = pcm_output_get_buffer(&size)) == NULL)
{
/* Wait one frame */
- int timeout = out_count*HZ / td.samplerate;
+ int timeout = dst.bufcount*HZ / td.samplerate;
str_get_msg_w_tmo(&audio_str, &td.ev, MAX(timeout, 1));
if (td.ev.id != SYS_TIMEOUT)
goto message_process;
}
- out_count = rb->dsp_process(td.dsp, out_buf, src, synth.pcm.length);
+ dst.bufcount = size / (2 * sizeof (int16_t));
+ rb->dsp_process(td.dsp, &td.src, &dst);
- if (out_count <= 0)
- break;
-
- /* Make this data available to DMA */
- pcm_output_commit_data(out_count*4, audio_queue.curr->time);
+ if (dst.remcount > 0)
+ {
+ /* Make this data available to DMA */
+ pcm_output_commit_data(dst.remcount * 2 * sizeof(int16_t),
+ audio_queue.curr->time);
- /* As long as we're on this timestamp, the time is just
- incremented by the number of samples */
- audio_queue.curr->time += out_count;
+ /* As long as we're on this timestamp, the time is just
+ incremented by the number of samples */
+ audio_queue.curr->time += dst.remcount;
+ }
+ else if (td.src.remcount <= 0)
+ {
+ break;
+ }
}
-
- rb->yield();
} /* end decoding loop */
}
diff --git a/apps/plugins/mpegplayer/mpeg_settings.c b/apps/plugins/mpegplayer/mpeg_settings.c
index 1c3f3c0b92..7f92fb7c69 100644
--- a/apps/plugins/mpegplayer/mpeg_settings.c
+++ b/apps/plugins/mpegplayer/mpeg_settings.c
@@ -457,13 +457,13 @@ static void sync_audio_setting(int setting, bool global)
break;
case MPEG_AUDIO_CROSSFEED:
- rb->dsp_set_crossfeed((global || settings.crossfeed) ?
- rb->global_settings->crossfeed : false);
+ rb->dsp_crossfeed_enable((global || settings.crossfeed) ?
+ rb->global_settings->crossfeed : false);
break;
case MPEG_AUDIO_EQUALIZER:
- rb->dsp_set_eq((global || settings.equalizer) ?
- rb->global_settings->eq_enabled : false);
+ rb->dsp_eq_enable((global || settings.equalizer) ?
+ rb->global_settings->eq_enabled : false);
break;
case MPEG_AUDIO_DITHERING:
diff --git a/apps/plugins/test_codec.c b/apps/plugins/test_codec.c
index dafcf35710..920be54d56 100644
--- a/apps/plugins/test_codec.c
+++ b/apps/plugins/test_codec.c
@@ -164,6 +164,7 @@ static inline void int2le16(unsigned char* buf, int16_t x)
static unsigned char *wavbuffer;
static unsigned char *dspbuffer;
+static int dspbuffer_count;
void init_wav(char* filename)
{
@@ -215,34 +216,31 @@ static void* codec_get_buffer(size_t *size)
static int process_dsp(const void *ch1, const void *ch2, int count)
{
- const char *src[2] = { ch1, ch2 };
- int written_count = 0;
- char *dest = dspbuffer;
-
- while (count > 0)
+ struct dsp_buffer src;
+ src.remcount = count;
+ src.pin[0] = ch1;
+ src.pin[1] = ch2;
+ src.proc_mask = 0;
+
+ struct dsp_buffer dst;
+ dst.remcount = 0;
+ dst.p16out = (int16_t *)dspbuffer;
+ dst.bufcount = dspbuffer_count;
+
+ while (1)
{
- int out_count = rb->dsp_output_count(ci.dsp, count);
-
- int inp_count = rb->dsp_input_count(ci.dsp, out_count);
-
- if (inp_count <= 0)
- break;
-
- if (inp_count > count)
- inp_count = count;
-
- out_count = rb->dsp_process(ci.dsp, dest, src, inp_count);
+ int old_remcount = dst.remcount;
+ rb->dsp_process(ci.dsp, &src, &dst);
- if (out_count <= 0)
+ if (dst.bufcount <= 0 ||
+ (src.remcount <= 0 && dst.remcount <= old_remcount))
+ {
+ /* Dest is full or no input left and DSP purged */
break;
-
- written_count += out_count;
- dest += out_count * 4;
-
- count -= inp_count;
+ }
}
- return written_count;
+ return dst.remcount;
}
/* Null output */
@@ -502,7 +500,6 @@ static void configure(int setting, intptr_t value)
rb->dsp_configure(ci.dsp, setting, value);
switch(setting)
{
- case DSP_SWITCH_FREQUENCY:
case DSP_SET_FREQUENCY:
DEBUGF("samplerate=%d\n",(int)value);
wavinfo.samplerate = use_dsp ? NATIVE_FREQUENCY : (int)value;
@@ -525,9 +522,7 @@ static void init_ci(void)
{
/* --- Our "fake" implementations of the codec API functions. --- */
- ci.dsp = (struct dsp_config *)rb->dsp_configure(NULL, DSP_MYDSP,
- CODEC_IDX_AUDIO);
-
+ ci.dsp = rb->dsp_get_config(CODEC_IDX_AUDIO);
ci.codec_get_buffer = codec_get_buffer;
if (wavinfo.fd >= 0 || checksum) {
@@ -849,6 +844,8 @@ enum plugin_status plugin_start(const void* parameter)
wavbuffer = rb->plugin_get_buffer(&buffer_size);
dspbuffer = wavbuffer + buffer_size / 2;
+ dspbuffer_count = (buffer_size - (dspbuffer - wavbuffer)) /
+ (2 * sizeof (int16_t));
codec_mallocbuf = rb->plugin_get_audio_buffer(&audiosize);
/* Align codec_mallocbuf to pointer size, tlsf wants that */
diff --git a/apps/settings.c b/apps/settings.c
index acc38c2388..49d239a2c1 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -979,20 +979,17 @@ void settings_apply(bool read_disk)
audio_set_crossfade(global_settings.crossfade);
#endif
dsp_set_replaygain();
- dsp_set_crossfeed(global_settings.crossfeed);
+ dsp_crossfeed_enable(global_settings.crossfeed);
dsp_set_crossfeed_direct_gain(global_settings.crossfeed_direct_gain);
dsp_set_crossfeed_cross_params(global_settings.crossfeed_cross_gain,
global_settings.crossfeed_hf_attenuation,
global_settings.crossfeed_hf_cutoff);
/* Configure software equalizer, hardware eq is handled in audio_init() */
- dsp_set_eq(global_settings.eq_enabled);
+ dsp_eq_enable(global_settings.eq_enabled);
dsp_set_eq_precut(global_settings.eq_precut);
-
- for(int i = 0; i < 5; i++) {
- dsp_set_eq_coefs(i, global_settings.eq_band_settings[i].cutoff,
- global_settings.eq_band_settings[i].q,
- global_settings.eq_band_settings[i].gain);
+ for(int i = 0; i < EQ_NUM_BANDS; i++) {
+ dsp_set_eq_coefs(i, &global_settings.eq_band_settings[i]);
}
dsp_dither_enable(global_settings.dithering_enabled);
diff --git a/apps/settings.h b/apps/settings.h
index b312c1e784..4d94ca8ba8 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -32,6 +32,7 @@
#include "button.h"
#if CONFIG_CODEC == SWCODEC
#include "audio.h"
+#include "dsp.h"
#endif
#include "rbpaths.h"
@@ -339,13 +340,7 @@ struct user_settings
/* EQ */
bool eq_enabled; /* Enable equalizer */
unsigned int eq_precut; /* dB */
-
- struct eq_band_setting
- {
- int cutoff; /* Hz */
- int q;
- int gain; /* +/- dB */
- } eq_band_settings[5];
+ struct eq_band_setting eq_band_settings[EQ_NUM_BANDS]; /* for each band */
/* Misc. swcodec */
int beep; /* system beep volume when changing tracks etc. */
@@ -772,14 +767,7 @@ struct user_settings
#endif
#if CONFIG_CODEC == SWCODEC
- struct compressor_settings
- {
- int threshold;
- int makeup_gain;
- int ratio;
- int knee;
- int release_time;
- } compressor_settings;
+ struct compressor_settings compressor_settings;
#endif
int sleeptimer_duration; /* In minutes; 0=off */
diff --git a/apps/settings_list.c b/apps/settings_list.c
index af48d11c85..82cccd891f 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -1398,7 +1398,7 @@ const struct settings_list settings[] = {
/* crossfeed */
OFFON_SETTING(F_SOUNDSETTING, crossfeed, LANG_CROSSFEED, false,
- "crossfeed", dsp_set_crossfeed),
+ "crossfeed", dsp_crossfeed_enable),
INT_SETTING_NOWRAP(F_SOUNDSETTING, crossfeed_direct_gain,
LANG_CROSSFEED_DIRECT_GAIN, -15,
"crossfeed direct gain", UNIT_DB, -60, 0, 5,
diff --git a/apps/voice_thread.c b/apps/voice_thread.c
index 07a67256c4..cff703adfa 100644
--- a/apps/voice_thread.c
+++ b/apps/voice_thread.c
@@ -133,9 +133,8 @@ struct voice_thread_data
SpeexBits bits; /* Bit cursor */
struct dsp_config *dsp; /* DSP used for voice output */
struct voice_info vi; /* Copy of clip data */
- const char *src[2]; /* Current output buffer pointers */
int lookahead; /* Number of samples to drop at start of clip */
- int count; /* Count of samples remaining to send to PCM */
+ struct dsp_buffer src; /* Speex output buffer/input to DSP */
};
/* Functions called in their repective state that return the next state to
@@ -264,9 +263,7 @@ void voice_wait(void)
* setup the DSP parameters */
static void voice_data_init(struct voice_thread_data *td)
{
- td->dsp = (struct dsp_config *)dsp_configure(NULL, DSP_MYDSP,
- CODEC_IDX_VOICE);
-
+ td->dsp = dsp_get_config(CODEC_IDX_VOICE);
dsp_configure(td->dsp, DSP_RESET, 0);
dsp_configure(td->dsp, DSP_SET_FREQUENCY, VOICE_SAMPLE_RATE);
dsp_configure(td->dsp, DSP_SET_SAMPLE_DEPTH, VOICE_SAMPLE_DEPTH);
@@ -378,7 +375,8 @@ static enum voice_state voice_decode(struct voice_thread_data *td)
else
{
/* If all clips are done and not playing, force pcm playback. */
- voice_start_playback();
+ if (voice_unplayed_frames() > 0)
+ voice_start_playback();
return VOICE_STATE_MESSAGE;
}
}
@@ -387,12 +385,14 @@ static enum voice_state voice_decode(struct voice_thread_data *td)
yield();
/* Output the decoded frame */
- td->count = VOICE_FRAME_COUNT - td->lookahead;
- td->src[0] = (const char *)&voice_output_buf[td->lookahead];
- td->src[1] = NULL;
+ td->src.remcount = VOICE_FRAME_COUNT - td->lookahead;
+ td->src.pin[0] = &voice_output_buf[td->lookahead];
+ td->src.pin[1] = NULL;
+ td->src.proc_mask = 0;
+
td->lookahead -= MIN(VOICE_FRAME_COUNT, td->lookahead);
- if (td->count > 0)
+ if (td->src.remcount > 0)
return VOICE_STATE_BUFFER_INSERT;
}
@@ -405,12 +405,21 @@ static enum voice_state voice_buffer_insert(struct voice_thread_data *td)
if (!queue_empty(&voice_queue))
return VOICE_STATE_MESSAGE;
- char *dest = (char *)voice_buf_get();
+ struct dsp_buffer dst;
- if (dest != NULL)
+ if ((dst.p16out = voice_buf_get()) != NULL)
{
- voice_buf_commit(dsp_process(td->dsp, dest, td->src, td->count));
- return VOICE_STATE_DECODE;
+ dst.remcount = 0;
+ dst.bufcount = VOICE_PCM_FRAME_COUNT;
+
+ dsp_process(td->dsp, &td->src, &dst);
+
+ voice_buf_commit(dst.remcount);
+
+ /* Unless other effects are introduced to voice that have delays,
+ all output should have been purged to dst in one call */
+ return td->src.remcount > 0 ?
+ VOICE_STATE_BUFFER_INSERT : VOICE_STATE_DECODE;
}
sleep(0);