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:
parent
b683874e98
commit
a604345ae1
4 changed files with 69 additions and 82 deletions
134
apps/dsp.c
134
apps/dsp.c
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue