Make DSP's replaygain independent of global_settings.
Moves replaygain definitions to lib/rbcodec/dsp/dsp_misc.h. Intermediate functions in misc.c handle any adjustment and calling the rbcodec APIs. Change-Id: I9f03561bca9aedd13760cf19c4e19aa3c68e7024 Reviewed-on: http://gerrit.rockbox.org/140 Reviewed-by: Michael Sevakis <jethead71@rockbox.org>
This commit is contained in:
parent
a32cbf3346
commit
57a20d2d63
11 changed files with 129 additions and 80 deletions
|
@ -419,9 +419,7 @@ bool quick_screen_quick(int button_enter)
|
|||
if (oldshuffle != global_settings.playlist_shuffle
|
||||
&& audio_status() & AUDIO_STATUS_PLAY)
|
||||
{
|
||||
#if CONFIG_CODEC == SWCODEC
|
||||
dsp_set_replaygain();
|
||||
#endif
|
||||
replaygain_update();
|
||||
if (global_settings.playlist_shuffle)
|
||||
playlist_randomise(NULL, current_tick, true);
|
||||
else
|
||||
|
|
|
@ -1420,25 +1420,22 @@ const char *get_token_value(struct gui_wps *gwps,
|
|||
|
||||
case SKIN_TOKEN_REPLAYGAIN:
|
||||
{
|
||||
int globtype = global_settings.replaygain_settings.type;
|
||||
int val;
|
||||
|
||||
if (global_settings.replaygain_type == REPLAYGAIN_OFF)
|
||||
|
||||
if (globtype == REPLAYGAIN_OFF)
|
||||
val = 1; /* off */
|
||||
else
|
||||
{
|
||||
int type;
|
||||
if (LIKELY(id3))
|
||||
type = get_replaygain_mode(id3->track_gain != 0,
|
||||
id3->album_gain != 0);
|
||||
else
|
||||
type = -1;
|
||||
int type = id3_get_replaygain_mode(id3);
|
||||
|
||||
if (type < 0)
|
||||
val = 6; /* no tag */
|
||||
else
|
||||
val = type + 2;
|
||||
|
||||
if (global_settings.replaygain_type == REPLAYGAIN_SHUFFLE)
|
||||
if (globtype == REPLAYGAIN_SHUFFLE)
|
||||
val += 2;
|
||||
}
|
||||
|
||||
|
|
|
@ -266,9 +266,7 @@ int skin_get_touchaction(struct wps_data *data, int* edge_offset,
|
|||
{
|
||||
global_settings.playlist_shuffle =
|
||||
!global_settings.playlist_shuffle;
|
||||
#if CONFIG_CODEC == SWCODEC
|
||||
dsp_set_replaygain();
|
||||
#endif
|
||||
replaygain_update();
|
||||
if (global_settings.playlist_shuffle)
|
||||
playlist_randomise(NULL, current_tick, true);
|
||||
else
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "scrobbler.h"
|
||||
#include "audio.h"
|
||||
#include "cuesheet.h"
|
||||
#include "misc.h"
|
||||
#if CONFIG_CODEC == SWCODEC
|
||||
#include "playback.h"
|
||||
#endif
|
||||
|
@ -116,14 +117,20 @@ static int replaygain_callback(int action,const struct menu_item_ex *this_item)
|
|||
switch (action)
|
||||
{
|
||||
case ACTION_EXIT_MENUITEM: /* on exit */
|
||||
dsp_set_replaygain();
|
||||
replaygain_update();
|
||||
break;
|
||||
}
|
||||
return action;
|
||||
}
|
||||
MENUITEM_SETTING(replaygain_noclip, &global_settings.replaygain_noclip ,replaygain_callback);
|
||||
MENUITEM_SETTING(replaygain_type, &global_settings.replaygain_type ,replaygain_callback);
|
||||
MENUITEM_SETTING(replaygain_preamp, &global_settings.replaygain_preamp ,replaygain_callback);
|
||||
MENUITEM_SETTING(replaygain_noclip,
|
||||
&global_settings.replaygain_settings.noclip,
|
||||
replaygain_callback);
|
||||
MENUITEM_SETTING(replaygain_type,
|
||||
&global_settings.replaygain_settings.type,
|
||||
replaygain_callback);
|
||||
MENUITEM_SETTING(replaygain_preamp,
|
||||
&global_settings.replaygain_settings.preamp,
|
||||
replaygain_callback);
|
||||
MAKE_MENU(replaygain_settings_menu,ID2P(LANG_REPLAYGAIN),0, Icon_NOICON,
|
||||
&replaygain_type, &replaygain_noclip, &replaygain_preamp);
|
||||
|
||||
|
@ -244,9 +251,8 @@ static int playback_callback(int action,const struct menu_item_ex *this_item)
|
|||
if (old_shuffle == global_settings.playlist_shuffle)
|
||||
break;
|
||||
|
||||
#if CONFIG_CODEC == SWCODEC
|
||||
dsp_set_replaygain();
|
||||
#endif
|
||||
replaygain_update();
|
||||
|
||||
if (global_settings.playlist_shuffle)
|
||||
{
|
||||
playlist_randomise(NULL, current_tick, true);
|
||||
|
|
39
apps/misc.c
39
apps/misc.c
|
@ -953,6 +953,45 @@ void keyclick_click(bool rawbutton, int action)
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the ReplayGain mode adjusted by other relevant settings */
|
||||
static int replaygain_setting_mode(int type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case REPLAYGAIN_SHUFFLE:
|
||||
type = global_settings.playlist_shuffle ?
|
||||
REPLAYGAIN_TRACK : REPLAYGAIN_ALBUM;
|
||||
case REPLAYGAIN_ALBUM:
|
||||
case REPLAYGAIN_TRACK:
|
||||
case REPLAYGAIN_OFF:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/* Return the ReplayGain mode adjusted for display purposes */
|
||||
int id3_get_replaygain_mode(const struct mp3entry *id3)
|
||||
{
|
||||
if (!id3)
|
||||
return -1;
|
||||
|
||||
int type = global_settings.replaygain_settings.type;
|
||||
type = replaygain_setting_mode(type);
|
||||
|
||||
return (type != REPLAYGAIN_TRACK && id3->album_gain != 0) ?
|
||||
REPLAYGAIN_ALBUM : (id3->track_gain != 0 ? REPLAYGAIN_TRACK : -1);
|
||||
}
|
||||
|
||||
/* Update DSP's replaygain from global settings */
|
||||
void replaygain_update(void)
|
||||
{
|
||||
struct replaygain_settings settings = global_settings.replaygain_settings;
|
||||
settings.type = replaygain_setting_mode(settings.type);
|
||||
dsp_replaygain_set_settings(&settings);
|
||||
}
|
||||
#endif /* CONFIG_CODEC == SWCODEC */
|
||||
|
||||
#endif /* !defined(__PCTOOL__) */
|
||||
|
|
10
apps/misc.h
10
apps/misc.h
|
@ -149,6 +149,16 @@ typedef bool (*keyclick_callback)(int action, void* data);
|
|||
void keyclick_set_callback(keyclick_callback cb, void* data);
|
||||
/* Produce keyclick based upon button and global settings */
|
||||
void keyclick_click(bool rawbutton, int action);
|
||||
|
||||
/* Return current ReplayGain mode a file should have (REPLAYGAIN_TRACK or
|
||||
* REPLAYGAIN_ALBUM) if ReplayGain processing is enabled, or -1 if no
|
||||
* information present.
|
||||
*/
|
||||
struct mp3entry;
|
||||
int id3_get_replaygain_mode(const struct mp3entry *id3);
|
||||
void replaygain_update(void);
|
||||
#else
|
||||
static inline void replaygain_update(void) {}
|
||||
#endif /* CONFIG_CODEC == SWCODEC */
|
||||
|
||||
void push_current_activity(enum current_activity screen);
|
||||
|
|
|
@ -978,7 +978,7 @@ void settings_apply(bool read_disk)
|
|||
#ifdef HAVE_CROSSFADE
|
||||
audio_set_crossfade(global_settings.crossfade);
|
||||
#endif
|
||||
dsp_set_replaygain();
|
||||
replaygain_update();
|
||||
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,
|
||||
|
|
|
@ -117,9 +117,6 @@ enum { SORT_INTERPRET_AS_DIGIT, SORT_INTERPRET_AS_NUMBER };
|
|||
/* recursive dir insert options */
|
||||
enum { RECURSE_OFF, RECURSE_ON, RECURSE_ASK };
|
||||
|
||||
/* replaygain types */
|
||||
enum { REPLAYGAIN_TRACK = 0, REPLAYGAIN_ALBUM, REPLAYGAIN_SHUFFLE, REPLAYGAIN_OFF };
|
||||
|
||||
/* show path types */
|
||||
enum { SHOW_PATH_OFF = 0, SHOW_PATH_CURRENT, SHOW_PATH_FULL };
|
||||
|
||||
|
@ -325,10 +322,7 @@ struct user_settings
|
|||
#endif
|
||||
|
||||
/* Replaygain */
|
||||
bool replaygain_noclip; /* scale to prevent clips */
|
||||
int replaygain_type; /* 0=track gain, 1=album gain, 2=track gain if
|
||||
shuffle is on, album gain otherwise, 4=off */
|
||||
int replaygain_preamp; /* scale replaygained tracks by this */
|
||||
struct replaygain_settings replaygain_settings;
|
||||
|
||||
/* Crossfeed */
|
||||
bool crossfeed; /* enable crossfeed */
|
||||
|
|
|
@ -1353,13 +1353,13 @@ const struct settings_list settings[] = {
|
|||
|
||||
#if CONFIG_CODEC == SWCODEC
|
||||
/* replay gain */
|
||||
CHOICE_SETTING(F_SOUNDSETTING, replaygain_type, LANG_REPLAYGAIN_MODE,
|
||||
REPLAYGAIN_SHUFFLE, "replaygain type",
|
||||
CHOICE_SETTING(F_SOUNDSETTING, replaygain_settings.type,
|
||||
LANG_REPLAYGAIN_MODE, REPLAYGAIN_SHUFFLE, "replaygain type",
|
||||
"track,album,track shuffle,off", NULL, 4, ID2P(LANG_TRACK_GAIN),
|
||||
ID2P(LANG_ALBUM_GAIN), ID2P(LANG_SHUFFLE_GAIN), ID2P(LANG_OFF)),
|
||||
OFFON_SETTING(F_SOUNDSETTING, replaygain_noclip, LANG_REPLAYGAIN_NOCLIP,
|
||||
false, "replaygain noclip", NULL),
|
||||
INT_SETTING_NOWRAP(F_SOUNDSETTING, replaygain_preamp,
|
||||
OFFON_SETTING(F_SOUNDSETTING, replaygain_settings.noclip,
|
||||
LANG_REPLAYGAIN_NOCLIP, false, "replaygain noclip", NULL),
|
||||
INT_SETTING_NOWRAP(F_SOUNDSETTING, replaygain_settings.preamp,
|
||||
LANG_REPLAYGAIN_PREAMP, 0, "replaygain preamp",
|
||||
UNIT_DB, -120, 120, 5, db_format, get_dec_talkid, NULL),
|
||||
|
||||
|
|
|
@ -23,12 +23,16 @@
|
|||
****************************************************************************/
|
||||
#include "config.h"
|
||||
#include "sound.h"
|
||||
#include "settings.h"
|
||||
#include "fixedpoint.h"
|
||||
#include "replaygain.h"
|
||||
#include "dsp_proc_entry.h"
|
||||
#include "dsp_sample_io.h"
|
||||
#include "dsp_misc.h"
|
||||
#include "pga.h"
|
||||
#include "channel_mode.h"
|
||||
#ifdef HAVE_SW_TONE_CONTROLS
|
||||
#include "tone_controls.h"
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
/** Firmware callback interface **/
|
||||
|
@ -77,43 +81,37 @@ int dsp_callback(int msg, intptr_t param)
|
|||
}
|
||||
|
||||
/** Replaygain settings **/
|
||||
static struct dsp_replay_gains current_rpgains;
|
||||
static struct replaygain_settings current_settings;
|
||||
static struct dsp_replay_gains current_gains;
|
||||
|
||||
static void dsp_replaygain_update(const struct dsp_replay_gains *gains)
|
||||
static void dsp_replaygain_update(
|
||||
const struct replaygain_settings *settings,
|
||||
const struct dsp_replay_gains *gains)
|
||||
{
|
||||
if (gains == NULL)
|
||||
{
|
||||
/* Use defaults */
|
||||
memset(¤t_rpgains, 0, sizeof (current_rpgains));
|
||||
gains = ¤t_rpgains;
|
||||
}
|
||||
else
|
||||
{
|
||||
current_rpgains = *gains; /* Stash settings */
|
||||
}
|
||||
if (settings != ¤t_settings)
|
||||
current_settings = *settings; /* Stash settings */
|
||||
|
||||
if (gains != ¤t_gains)
|
||||
current_gains = *gains; /* Stash gains */
|
||||
|
||||
int32_t gain = PGA_UNITY;
|
||||
|
||||
if (global_settings.replaygain_type != REPLAYGAIN_OFF ||
|
||||
global_settings.replaygain_noclip)
|
||||
if (settings->type != REPLAYGAIN_OFF || settings->noclip)
|
||||
{
|
||||
bool track_mode =
|
||||
get_replaygain_mode(gains->track_gain != 0,
|
||||
gains->album_gain != 0) == REPLAYGAIN_TRACK;
|
||||
bool track_mode = settings->type == REPLAYGAIN_TRACK &&
|
||||
gains->track_gain != 0;
|
||||
|
||||
int32_t peak = (track_mode || gains->album_peak == 0) ?
|
||||
gains->track_peak : gains->album_peak;
|
||||
gains->track_peak : gains->album_peak;
|
||||
|
||||
if (global_settings.replaygain_type != REPLAYGAIN_OFF)
|
||||
if (settings->type != REPLAYGAIN_OFF)
|
||||
{
|
||||
gain = (track_mode || gains->album_gain == 0) ?
|
||||
gains->track_gain : gains->album_gain;
|
||||
|
||||
if (global_settings.replaygain_preamp)
|
||||
if (settings->preamp != 0)
|
||||
{
|
||||
int32_t preamp = get_replaygain_int(
|
||||
global_settings.replaygain_preamp * 10);
|
||||
|
||||
int32_t preamp = get_replaygain_int(settings->preamp * 10);
|
||||
gain = fp_mul(gain, preamp, 24);
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +122,7 @@ static void dsp_replaygain_update(const struct dsp_replay_gains *gains)
|
|||
gain = PGA_UNITY;
|
||||
}
|
||||
|
||||
if (global_settings.replaygain_noclip && peak != 0 &&
|
||||
if (settings->noclip && peak != 0 &&
|
||||
fp_mul(gain, peak, 24) >= PGA_UNITY)
|
||||
{
|
||||
gain = fp_div(PGA_UNITY, peak, 24);
|
||||
|
@ -135,28 +133,21 @@ static void dsp_replaygain_update(const struct dsp_replay_gains *gains)
|
|||
pga_enable_gain(PGA_REPLAYGAIN, gain != PGA_UNITY);
|
||||
}
|
||||
|
||||
int get_replaygain_mode(bool have_track_gain, bool have_album_gain)
|
||||
void dsp_replaygain_set_settings(const struct replaygain_settings *settings)
|
||||
{
|
||||
bool track = false;
|
||||
|
||||
switch (global_settings.replaygain_type)
|
||||
{
|
||||
case REPLAYGAIN_TRACK:
|
||||
track = true;
|
||||
break;
|
||||
|
||||
case REPLAYGAIN_SHUFFLE:
|
||||
track = global_settings.playlist_shuffle;
|
||||
break;
|
||||
}
|
||||
|
||||
return (!track && have_album_gain) ?
|
||||
REPLAYGAIN_ALBUM : (have_track_gain ? REPLAYGAIN_TRACK : -1);
|
||||
dsp_replaygain_update(settings, ¤t_gains);
|
||||
}
|
||||
|
||||
void dsp_set_replaygain(void)
|
||||
void dsp_replaygain_set_gains(const struct dsp_replay_gains *gains)
|
||||
{
|
||||
dsp_replaygain_update(¤t_rpgains);
|
||||
if (gains == NULL)
|
||||
{
|
||||
/* Set defaults */
|
||||
gains = ¤t_gains;
|
||||
memset((void *)gains, 0, sizeof (*gains));
|
||||
}
|
||||
|
||||
dsp_replaygain_update(¤t_settings, gains);
|
||||
}
|
||||
|
||||
|
||||
|
@ -217,7 +208,7 @@ static intptr_t misc_handler_configure(struct dsp_proc_entry *this,
|
|||
#endif
|
||||
value = (intptr_t)NULL; /* Default gains */
|
||||
case REPLAYGAIN_SET_GAINS:
|
||||
dsp_replaygain_update((void *)value);
|
||||
dsp_replaygain_set_gains((void *)value);
|
||||
break;
|
||||
|
||||
#ifdef HAVE_PITCHSCREEN
|
||||
|
|
|
@ -26,6 +26,22 @@
|
|||
/* Set the tri-pdf dithered output */
|
||||
void dsp_dither_enable(bool enable); /* in dsp_sample_output.c */
|
||||
|
||||
enum replaygain_types
|
||||
{
|
||||
REPLAYGAIN_TRACK = 0,
|
||||
REPLAYGAIN_ALBUM,
|
||||
REPLAYGAIN_SHUFFLE,
|
||||
REPLAYGAIN_OFF
|
||||
};
|
||||
|
||||
struct replaygain_settings
|
||||
{
|
||||
bool noclip; /* scale to prevent clips */
|
||||
int type; /* 0=track gain, 1=album gain, 2=track gain if
|
||||
shuffle is on, album gain otherwise, 4=off */
|
||||
int preamp; /* scale replaygained tracks by this */
|
||||
};
|
||||
|
||||
/* Structure used with REPLAYGAIN_SET_GAINS message */
|
||||
#define REPLAYGAIN_SET_GAINS (DSP_PROC_SETTING+DSP_PROC_MISC_HANDLER)
|
||||
struct dsp_replay_gains
|
||||
|
@ -36,8 +52,8 @@ struct dsp_replay_gains
|
|||
long album_peak;
|
||||
};
|
||||
|
||||
int get_replaygain_mode(bool have_track_gain, bool have_album_gain);
|
||||
void dsp_set_replaygain(void);
|
||||
void dsp_replaygain_set_settings(const struct replaygain_settings *settings);
|
||||
void dsp_replaygain_set_gains(const struct dsp_replay_gains *gains);
|
||||
|
||||
#ifdef HAVE_PITCHSCREEN
|
||||
void sound_set_pitch(int32_t ratio);
|
||||
|
|
Loading…
Reference in a new issue