1
0
Fork 0
forked from len0rd/rockbox

[Feature] Persist pitch settings through reboots

saves the pitch setting across reboots

adds option 'Reset Setting'

Change-Id: I75d88f9653883a256c6cca0f7adcdccb2dd51406
This commit is contained in:
William Wilgus 2025-01-17 03:01:53 -05:00 committed by William Wilgus
parent 5e8d3fec66
commit 13c3214d9c
7 changed files with 126 additions and 10 deletions

View file

@ -38,6 +38,11 @@
#include "talk.h" #include "talk.h"
#include "settings.h" #include "settings.h"
#if defined(HAVE_PITCHCONTROL)
#include "pitchscreen.h"
#include "misc.h"
#include "strcasecmp.h"
#endif
/* Macros to enable logf for queues /* Macros to enable logf for queues
logging on SYS_TIMEOUT can be disabled */ logging on SYS_TIMEOUT can be disabled */
#ifdef SIMULATOR #ifdef SIMULATOR
@ -185,4 +190,36 @@ void INIT_ATTR audio_init(void)
audio_is_initialized = true; audio_is_initialized = true;
sound_settings_apply(); sound_settings_apply();
#if defined(HAVE_PITCHCONTROL)
int fd;
char line[64];
char* name;
char* value;
int32_t num;
fd = open_utf8(PITCH_CFG_FILE, O_RDONLY);
if (fd >= 0)
{
while (read_line(fd, line, sizeof line) > 0)
{
if (!settings_parseline(line, &name, &value))
continue;
if (strcasecmp(name, "pitch") == 0)
{
num = atoi(value);
if (num != PITCH_SPEED_100)
sound_set_pitch(num);
}
if (strcasecmp(name, "stretch") == 0)
{
num = atoi(value);
if (num != PITCH_SPEED_100)
dsp_set_timestretch(num);
}
}
}
#endif
} }

View file

@ -19,7 +19,17 @@
* *
****************************************************************************/ ****************************************************************************/
#include "plugin.h" #include "plugin.h"
#include "pitchscreen.h"
int gui_syncpitchscreen_run(void) int gui_syncpitchscreen_run(void)
{ {
return (plugin_load(VIEWERS_DIR"/pitch_screen.rock", NULL) == PLUGIN_USB_CONNECTED); return (plugin_load(VIEWERS_DIR"/pitch_screen.rock", NULL) == PLUGIN_USB_CONNECTED);
} }
int reset_pitch(void)
{
sound_set_pitch(PITCH_SPEED_100);
dsp_set_timestretch(PITCH_SPEED_100);
remove(PITCH_CFG_FILE);
return 0;
}

View file

@ -22,6 +22,8 @@
#ifndef _PITCHSCREEN_H_ #ifndef _PITCHSCREEN_H_
#define _PITCHSCREEN_H_ #define _PITCHSCREEN_H_
#define PITCH_CFG_FILE ROCKBOX_DIR "/pitch.cfg"
int gui_syncpitchscreen_run(void); int gui_syncpitchscreen_run(void);
int reset_pitch(void);
#endif /* _PITCHSCREEN_H_ */ #endif /* _PITCHSCREEN_H_ */

View file

@ -711,7 +711,35 @@ MENUITEM_FUNCTION(browse_id3_item, MENU_FUNC_CHECK_RETVAL, ID2P(LANG_MENU_SHOW_I
#ifdef HAVE_PITCHCONTROL #ifdef HAVE_PITCHCONTROL
MENUITEM_FUNCTION(pitch_screen_item, 0, ID2P(LANG_PITCH), MENUITEM_FUNCTION(pitch_screen_item, 0, ID2P(LANG_PITCH),
gui_syncpitchscreen_run, NULL, Icon_Audio); gui_syncpitchscreen_run, NULL, Icon_Audio);
#endif MENUITEM_FUNCTION(pitch_reset_item, 0, ID2P(LANG_RESET_SETTING),
reset_pitch, NULL, Icon_Submenu_Entered);
static int pitch_callback(int action,
const struct menu_item_ex *this_item,
struct gui_synclist *this_list)
{
if (action == ACTION_ENTER_MENUITEM)
{
int32_t ts = dsp_get_timestretch();
if (sound_get_pitch() == PITCH_SPEED_100 && ts == PITCH_SPEED_100)
{ /* if default then run pitch screen directly */
gui_syncpitchscreen_run();
action = ACTION_EXIT_MENUITEM;
}
}
return action;
(void)this_item;
(void)this_list;
}
/* pitch submenu */
MAKE_ONPLAYMENU(pitch_menu, ID2P(LANG_PITCH),
pitch_callback, Icon_Audio,
&pitch_screen_item,
&pitch_reset_item);
#endif /*def HAVE_PITCHCONTROL*/
#ifdef HAVE_ALBUMART #ifdef HAVE_ALBUMART
MENUITEM_FUNCTION(view_album_art_item, 0, ID2P(LANG_VIEW_ALBUMART), MENUITEM_FUNCTION(view_album_art_item, 0, ID2P(LANG_VIEW_ALBUMART),
view_album_art, NULL, Icon_NOICON); view_album_art, NULL, Icon_NOICON);
@ -1037,7 +1065,7 @@ MAKE_ONPLAYMENU( wps_onplay_menu, ID2P(LANG_ONPLAY_MENU_TITLE),
&browse_id3_item, &list_viewers_item, &browse_id3_item, &list_viewers_item,
&delete_file_item, &view_cue_item, &delete_file_item, &view_cue_item,
#ifdef HAVE_PITCHCONTROL #ifdef HAVE_PITCHCONTROL
&pitch_screen_item, &pitch_menu,
#endif #endif
#ifdef HAVE_ALBUMART #ifdef HAVE_ALBUMART
&view_album_art_item, &view_album_art_item,

View file

@ -49,8 +49,15 @@ int configfile_save(const char *filename, const struct configdata *cfg,
int i; int i;
char buf[MAX_PATH]; char buf[MAX_PATH];
if (rb->strncmp(filename, ROCKBOX_DIR, sizeof(ROCKBOX_DIR) - 1) != 0)
{
get_cfg_filename(buf, MAX_PATH, filename); get_cfg_filename(buf, MAX_PATH, filename);
fd = rb->creat(buf, 0666); fd = rb->creat(buf, 0666);
}
else /* allow saving to the rockbox directory */
fd = rb->creat(filename, 0666);
if(fd < 0) if(fd < 0)
return fd*10 - 1; return fd*10 - 1;

View file

@ -22,6 +22,11 @@
#include "plugin.h" #include "plugin.h"
#include "lib/icon_helper.h" #include "lib/icon_helper.h"
#include "lib/arg_helper.h" #include "lib/arg_helper.h"
#include "lib/configfile.h"
#include "../gui/pitchscreen.h" /*PITCH_CFG_FILE*/
#define CFG_FILE PITCH_CFG_FILE
#define CFG_VER 1
#define ICON_BORDER 12 /* icons are currently 7x8, so add ~2 pixels */ #define ICON_BORDER 12 /* icons are currently 7x8, so add ~2 pixels */
/* on both sides when drawing */ /* on both sides when drawing */
@ -49,6 +54,12 @@ struct pvars
}; };
static struct pvars pitch_vars; static struct pvars pitch_vars;
static struct configdata pitchcfg[] =
{
{TYPE_INT, PITCH_MIN, PITCH_MAX, { .int_p = &pitch_vars.pitch }, "pitch", NULL},
{TYPE_INT, STRETCH_MIN, STRETCH_MAX, { .int_p = &pitch_vars.stretch }, "stretch", NULL},
};
enum enum
{ {
PITCH_TOP = 0, PITCH_TOP = 0,
@ -1218,6 +1229,9 @@ enum plugin_status plugin_start(const void* parameter)
bool gui = false; bool gui = false;
rb->pcmbuf_set_low_latency(true); rb->pcmbuf_set_low_latency(true);
struct pvars cur;
fill_pitchvars(&cur);
/* Figure out whether to be in timestretch mode */ /* Figure out whether to be in timestretch mode */
if (parameter == NULL) /* gui mode */ if (parameter == NULL) /* gui mode */
{ {
@ -1230,8 +1244,6 @@ enum plugin_status plugin_start(const void* parameter)
} }
else else
{ {
struct pvars cur;
fill_pitchvars(&cur);
fill_pitchvars(&pitch_vars); fill_pitchvars(&pitch_vars);
argparse((const char*) parameter, -1, NULL, &arg_callback); argparse((const char*) parameter, -1, NULL, &arg_callback);
if (pitch_vars.pitch != cur.pitch) if (pitch_vars.pitch != cur.pitch)
@ -1275,6 +1287,19 @@ enum plugin_status plugin_start(const void* parameter)
if (gui && gui_syncpitchscreen_run() == 1) if (gui && gui_syncpitchscreen_run() == 1)
return PLUGIN_USB_CONNECTED; return PLUGIN_USB_CONNECTED;
if (gui)
{
fill_pitchvars(&pitch_vars);
if (pitch_vars.pitch != cur.pitch || pitch_vars.stretch != cur.stretch)
{
if (configfile_save(CFG_FILE, pitchcfg, 2, CFG_VER) >= 0)
rb->splash(HZ, ID2P(LANG_SETTINGS_SAVED));
else
rb->splash(HZ, ID2P(LANG_ERROR_WRITING_CONFIG));
}
}
rb->pcmbuf_set_low_latency(false); rb->pcmbuf_set_low_latency(false);
return PLUGIN_OK; return PLUGIN_OK;
} }

View file

@ -287,12 +287,19 @@ This may even be the whole track.
same ratio as well as remain between 50\% and 200\%. same ratio as well as remain between 50\% and 200\%.
The value of the rate, pitch and speed The value of the rate, pitch and speed
is not persistent, i.e. after the \dap\ is turned on it will is persistent, i.e. when the \dap\ is turned on it will
always be set to 100\%. However, the rate, pitch and speed always be set to your last value. Selecting \setting{Pitch} again
information will be stored in any bookmarks you may create will now display a menu with \setting{Pitch} and \setting{Reset Setting}.
(see \reference{ref:Bookmarkconfigactual}) and will be restored upon Selecting \setting{Reset Setting} will reset the pitch to 100\% now and at next boot.
However the rate, pitch and speed information will be stored in any bookmarks
you may create (see \reference{ref:Bookmarkconfigactual})
while the pitch is altered and will be restored upon
playing back those bookmarks. playing back those bookmarks.
\note{ If a bookmark has changed pitch, settings will remain till
the \dap{} is restarted and your (possibly different or default)
persistent settings will then be restored.}
\begin{btnmap} \begin{btnmap}
\ActionPsToggleMode \ActionPsToggleMode
\opt{HAVEREMOTEKEYMAP}{& \ActionRCPsToggleMode} \opt{HAVEREMOTEKEYMAP}{& \ActionRCPsToggleMode}