Clean up compressor setting code

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30715 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jeffrey Goode 2011-10-05 04:44:56 +00:00
parent b683874e98
commit a604345ae1
4 changed files with 69 additions and 82 deletions

View file

@ -133,15 +133,6 @@ struct eq_state
/* 10ch */ /* 10ch */
}; };
struct compressor_menu
{
int threshold; /* dB - from menu */
bool auto_gain; /* 0 = off, 1 = auto */
int ratio; /* from menu */
bool soft_knee; /* 0 = hard knee, 1 = soft knee */
int release; /* samples - from menu */
};
/* Include header with defines which functions are implemented in assembly /* Include header with defines which functions are implemented in assembly
code for the target */ code for the target */
#include <dsp_asm.h> #include <dsp_asm.h>
@ -260,13 +251,12 @@ static int resample_buf_count = SMALL_RESAMPLE_BUF_COUNT;
static int32_t *resample_buf[2] = { small_resample_buf[0], small_resample_buf[1] }; static int32_t *resample_buf[2] = { small_resample_buf[0], small_resample_buf[1] };
/* compressor */ /* compressor */
static struct compressor_menu c_menu;
static int32_t comp_rel_slope IBSS_ATTR; /* S7.24 format */ static int32_t comp_rel_slope IBSS_ATTR; /* S7.24 format */
static int32_t comp_makeup_gain IBSS_ATTR; /* S7.24 format */ static int32_t comp_makeup_gain IBSS_ATTR; /* S7.24 format */
static int32_t comp_curve[66] IBSS_ATTR; /* S7.24 format */ static int32_t comp_curve[66] IBSS_ATTR; /* S7.24 format */
static int32_t release_gain IBSS_ATTR; /* S7.24 format */ static int32_t release_gain IBSS_ATTR; /* S7.24 format */
#define UNITY (1L << 24) /* unity gain in S7.24 format */ #define UNITY (1L << 24) /* unity gain in S7.24 format */
static void compressor_process(int count, int32_t *buf[]); static void compressor_process(int count, int32_t *buf[]);
/* Clip sample to signed 16 bit range */ /* Clip sample to signed 16 bit range */
@ -1607,55 +1597,61 @@ void dsp_set_replaygain(void)
/** SET COMPRESSOR /** SET COMPRESSOR
* Called by the menu system to configure the compressor process */ * Called by the menu system to configure the compressor process */
void dsp_set_compressor(int c_threshold, int c_gain, int c_ratio, void dsp_set_compressor(void)
int c_knee, int c_release)
{ {
static int curr_set[5];
int new_set[5] = {
global_settings.compressor_threshold,
global_settings.compressor_makeup_gain,
global_settings.compressor_ratio,
global_settings.compressor_knee,
global_settings.compressor_release_time};
/* make menu values useful */
int threshold = new_set[0];
bool auto_gain = (new_set[1] == 1);
const int comp_ratios[] = {2, 4, 6, 10, 0};
int ratio = comp_ratios[new_set[2]];
bool soft_knee = (new_set[3] == 1);
int release = new_set[4] * NATIVE_FREQUENCY / 1000;
bool changed = false; bool changed = false;
bool active = (c_threshold < 0); bool active = (threshold < 0);
bool new_auto_gain = (c_gain == 1);
const int comp_ratio[] = {2, 4, 6, 10, 0};
int new_ratio = comp_ratio[c_ratio];
bool new_knee = (c_knee == 1);
int new_release = c_release * NATIVE_FREQUENCY / 1000;
if (c_menu.threshold != c_threshold) int i;
for (i = 0; i < 5; i++)
{ {
changed = true; if (curr_set[i] != new_set[i])
c_menu.threshold = c_threshold; {
logf(" Compressor Threshold: %d dB\tEnabled: %s", changed = true;
c_menu.threshold, active ? "Yes" : "No"); curr_set[i] = new_set[i];
}
if (c_menu.auto_gain != new_auto_gain) #if defined(ROCKBOX_HAS_LOGF) && defined(LOGF_ENABLE)
{ switch (i)
changed = true; {
c_menu.auto_gain = new_auto_gain; case 0:
logf(" Compressor Makeup Gain: %s", logf(" Compressor Threshold: %d dB\tEnabled: %s",
c_menu.auto_gain ? "Auto" : "Off"); threshold, active ? "Yes" : "No");
} break;
case 1:
if (c_menu.ratio != new_ratio) logf(" Compressor Makeup Gain: %s",
{ auto_gain ? "Auto" : "Off");
changed = true; break;
c_menu.ratio = new_ratio; case 2:
if (c_menu.ratio) if (ratio)
{ logf(" Compressor Ratio: %d:1", c_menu.ratio); } { logf(" Compressor Ratio: %d:1", ratio); }
else else
{ logf(" Compressor Ratio: Limit"); } { logf(" Compressor Ratio: Limit"); }
} break;
case 3:
if (c_menu.soft_knee != new_knee) logf(" Compressor Knee: %s", soft_knee?"Soft":"Hard");
{ break;
changed = true; case 4:
c_menu.soft_knee = new_knee; logf(" Compressor Release: %d", release);
logf(" Compressor Knee: %s", c_menu.soft_knee==1?"Soft":"Hard"); break;
} }
#endif
if (c_menu.release != new_release) }
{
changed = true;
c_menu.release = new_release;
logf(" Compressor Release: %d", c_menu.release);
} }
if (changed && active) if (changed && active)
@ -1685,17 +1681,17 @@ void dsp_set_compressor(int c_threshold, int c_gain, int c_ratio,
[3] = 0 db input [3] = 0 db input
[4] = ~+12db input (2 bits clipping overhead) */ [4] = ~+12db input (2 bits clipping overhead) */
db_curve[1].db = c_menu.threshold << 16; db_curve[1].db = threshold << 16;
if (c_menu.soft_knee) if (soft_knee)
{ {
/* bottom of knee is 3dB below the threshold for soft knee*/ /* bottom of knee is 3dB below the threshold for soft knee*/
db_curve[0].db = db_curve[1].db - (3 << 16); db_curve[0].db = db_curve[1].db - (3 << 16);
/* top of knee is 3dB above the threshold for soft knee */ /* top of knee is 3dB above the threshold for soft knee */
db_curve[2].db = db_curve[1].db + (3 << 16); db_curve[2].db = db_curve[1].db + (3 << 16);
if (c_menu.ratio) if (ratio)
/* offset = -3db * (ratio - 1) / ratio */ /* offset = -3db * (ratio - 1) / ratio */
db_curve[2].offset = (int32_t)((long long)(-3 << 16) db_curve[2].offset = (int32_t)((long long)(-3 << 16)
* (c_menu.ratio - 1) / c_menu.ratio); * (ratio - 1) / ratio);
else else
/* offset = -3db for hard limit */ /* offset = -3db for hard limit */
db_curve[2].offset = (-3 << 16); db_curve[2].offset = (-3 << 16);
@ -1703,26 +1699,26 @@ void dsp_set_compressor(int c_threshold, int c_gain, int c_ratio,
else else
{ {
/* bottom of knee is at the threshold for hard knee */ /* bottom of knee is at the threshold for hard knee */
db_curve[0].db = c_menu.threshold << 16; db_curve[0].db = threshold << 16;
/* top of knee is at the threshold for hard knee */ /* top of knee is at the threshold for hard knee */
db_curve[2].db = c_menu.threshold << 16; db_curve[2].db = threshold << 16;
db_curve[2].offset = 0; db_curve[2].offset = 0;
} }
/* Calculate 0db and ~+12db offsets */ /* Calculate 0db and ~+12db offsets */
db_curve[4].db = 0xC0A8C; /* db of 2 bits clipping */ db_curve[4].db = 0xC0A8C; /* db of 2 bits clipping */
if (c_menu.ratio) if (ratio)
{ {
/* offset = threshold * (ratio - 1) / ratio */ /* offset = threshold * (ratio - 1) / ratio */
db_curve[3].offset = (int32_t)((long long)(c_menu.threshold << 16) db_curve[3].offset = (int32_t)((long long)(threshold << 16)
* (c_menu.ratio - 1) / c_menu.ratio); * (ratio - 1) / ratio);
db_curve[4].offset = (int32_t)((long long)-db_curve[4].db db_curve[4].offset = (int32_t)((long long)-db_curve[4].db
* (c_menu.ratio - 1) / c_menu.ratio) + db_curve[3].offset; * (ratio - 1) / ratio) + db_curve[3].offset;
} }
else else
{ {
/* offset = threshold for hard limit */ /* offset = threshold for hard limit */
db_curve[3].offset = (c_menu.threshold << 16); db_curve[3].offset = (threshold << 16);
db_curve[4].offset = -db_curve[4].db + db_curve[3].offset; db_curve[4].offset = -db_curve[4].db + db_curve[3].offset;
} }
@ -1744,7 +1740,7 @@ void dsp_set_compressor(int c_threshold, int c_gain, int c_ratio,
/* if soft knee and below top of knee, /* if soft knee and below top of knee,
interpolate along soft knee slope */ interpolate along soft knee slope */
else if (c_menu.soft_knee && (this_db <= db_curve[2].db)) else if (soft_knee && (this_db <= db_curve[2].db))
comp_curve[i] = fp_factor(fp_mul( comp_curve[i] = fp_factor(fp_mul(
((this_db - db_curve[0].db) / 6), ((this_db - db_curve[0].db) / 6),
db_curve[2].offset, 16), 16) << 8; db_curve[2].offset, 16), 16) << 8;
@ -1787,12 +1783,12 @@ void dsp_set_compressor(int c_threshold, int c_gain, int c_ratio,
#endif #endif
/* if using auto peak, then makeup gain is max offset - .1dB headroom */ /* if using auto peak, then makeup gain is max offset - .1dB headroom */
comp_makeup_gain = c_menu.auto_gain ? comp_makeup_gain = auto_gain ?
fp_factor(-(db_curve[3].offset) - 0x199A, 16) << 8 : UNITY; fp_factor(-(db_curve[3].offset) - 0x199A, 16) << 8 : UNITY;
logf("Makeup gain:\t%.6f", (float)comp_makeup_gain / UNITY); logf("Makeup gain:\t%.6f", (float)comp_makeup_gain / UNITY);
/* calculate per-sample gain change a rate of 10db over release time */ /* calculate per-sample gain change a rate of 10db over release time */
comp_rel_slope = 0xAF0BB2 / c_menu.release; comp_rel_slope = 0xAF0BB2 / release;
logf("Release slope:\t%.6f", (float)comp_rel_slope / UNITY); logf("Release slope:\t%.6f", (float)comp_rel_slope / UNITY);
release_gain = UNITY; release_gain = UNITY;

View file

@ -82,7 +82,6 @@ int32_t sound_get_pitch(void);
void dsp_set_timestretch(int32_t percent); void dsp_set_timestretch(int32_t percent);
int32_t dsp_get_timestretch(void); int32_t dsp_get_timestretch(void);
int dsp_callback(int msg, intptr_t param); int dsp_callback(int msg, intptr_t param);
void dsp_set_compressor(int c_threshold, int c_gain, int c_ratio, void dsp_set_compressor(void);
int c_knee, int c_release);
#endif #endif

View file

@ -989,11 +989,7 @@ void settings_apply(bool read_disk)
#ifdef HAVE_PITCHSCREEN #ifdef HAVE_PITCHSCREEN
dsp_timestretch_enable(global_settings.timestretch_enabled); dsp_timestretch_enable(global_settings.timestretch_enabled);
#endif #endif
dsp_set_compressor(global_settings.compressor_threshold, dsp_set_compressor();
global_settings.compressor_makeup_gain,
global_settings.compressor_ratio,
global_settings.compressor_knee,
global_settings.compressor_release_time);
#endif #endif
#ifdef HAVE_SPDIF_POWER #ifdef HAVE_SPDIF_POWER

View file

@ -385,11 +385,7 @@ static void crossfeed_cross_set(int val)
static void compressor_set(int val) static void compressor_set(int val)
{ {
(void)val; (void)val;
dsp_set_compressor(global_settings.compressor_threshold, dsp_set_compressor();
global_settings.compressor_makeup_gain,
global_settings.compressor_ratio,
global_settings.compressor_knee,
global_settings.compressor_release_time);
} }
static const char* db_format(char* buffer, size_t buffer_size, int value, static const char* db_format(char* buffer, size_t buffer_size, int value,