Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

[Feature] Persist pitch settings through reboots part deux

Revisit this after discussion with chris_s on IRC and forum

Pitch menu now changes icon when pitch has been changed

uses NVRAM to save the pitch settings unconditionally

Manual updated

Change-Id: Idcb4c2b7fe42f7a203dc4bfc46285657f370d0fd

authored by

William Wilgus and committed by
William Wilgus
4e271642 3e57ca15

+62 -103
-40
apps/audio_thread.c
··· 38 38 #include "talk.h" 39 39 #include "settings.h" 40 40 41 - #if defined(HAVE_PITCHCONTROL) 42 - #include "pitchscreen.h" 43 - #include "misc.h" 44 - #include "strcasecmp.h" 45 - #endif 46 41 /* Macros to enable logf for queues 47 42 logging on SYS_TIMEOUT can be disabled */ 48 43 #ifdef SIMULATOR ··· 190 185 audio_is_initialized = true; 191 186 192 187 sound_settings_apply(); 193 - 194 - #if defined(HAVE_PITCHCONTROL) 195 - int fd; 196 - char line[64]; 197 - char* name; 198 - char* value; 199 - int32_t num; 200 - if (file_exists(PITCH_CFG_FILE)) 201 - { 202 - fd = open_utf8(PITCH_CFG_FILE, O_RDONLY); 203 - if (fd >= 0) 204 - { 205 - while (read_line(fd, line, sizeof line) > 0) 206 - { 207 - if (!settings_parseline(line, &name, &value)) 208 - continue; 209 - if (strcasecmp(name, "pitch") == 0) 210 - { 211 - num = atoi(value); 212 - if (num != PITCH_SPEED_100) 213 - sound_set_pitch(num); 214 - } 215 - if (strcasecmp(name, "stretch") == 0) 216 - { 217 - num = atoi(value); 218 - if (num != PITCH_SPEED_100) 219 - dsp_set_timestretch(num); 220 - } 221 - } 222 - close(fd); 223 - } 224 - } 225 - #endif 226 - 227 - 228 188 }
-1
apps/gui/pitchscreen.c
··· 30 30 { 31 31 sound_set_pitch(PITCH_SPEED_100); 32 32 dsp_set_timestretch(PITCH_SPEED_100); 33 - remove(PITCH_CFG_FILE); 34 33 return 0; 35 34 }
-1
apps/gui/pitchscreen.h
··· 22 22 #ifndef _PITCHSCREEN_H_ 23 23 #define _PITCHSCREEN_H_ 24 24 25 - #define PITCH_CFG_FILE ROCKBOX_DIR "/pitch.cfg" 26 25 int gui_syncpitchscreen_run(void); 27 26 int reset_pitch(void); 28 27
+29 -11
apps/onplay.c
··· 708 708 /* CONTEXT_WPS items */ 709 709 MENUITEM_FUNCTION(browse_id3_item, MENU_FUNC_CHECK_RETVAL, ID2P(LANG_MENU_SHOW_ID3_INFO), 710 710 browse_id3_wrapper, NULL, Icon_NOICON); 711 + 711 712 #ifdef HAVE_PITCHCONTROL 712 713 MENUITEM_FUNCTION(pitch_screen_item, 0, ID2P(LANG_PITCH), 713 714 gui_syncpitchscreen_run, NULL, Icon_Audio); ··· 716 717 717 718 static int pitch_callback(int action, 718 719 const struct menu_item_ex *this_item, 720 + struct gui_synclist *this_list); 721 + 722 + /* need special handling so we can toggle the icon */ 723 + #define MAKE_PITCHMENU( name, str, callback, icon, ... ) \ 724 + static const struct menu_item_ex *name##_[] = {__VA_ARGS__}; \ 725 + struct menu_callback_with_desc name##__ = {callback,str,icon}; \ 726 + static const struct menu_item_ex name = \ 727 + {MT_MENU|MENU_HAS_DESC|MENU_EXITAFTERTHISMENU| \ 728 + MENU_ITEM_COUNT(sizeof( name##_)/sizeof(*name##_)), \ 729 + { (void*)name##_},{.callback_and_desc = & name##__}}; 730 + 731 + MAKE_PITCHMENU(pitch_menu, ID2P(LANG_PITCH), 732 + pitch_callback, Icon_Audio, 733 + &pitch_screen_item, 734 + &pitch_reset_item); 735 + 736 + static int pitch_callback(int action, 737 + const struct menu_item_ex *this_item, 719 738 struct gui_synclist *this_list) 720 739 { 721 - if (action == ACTION_ENTER_MENUITEM) 740 + if (action == ACTION_ENTER_MENUITEM || action == ACTION_REQUEST_MENUITEM) 722 741 { 742 + pitch_menu__.icon_id = Icon_Submenu; /* if setting changed show + */ 723 743 int32_t ts = dsp_get_timestretch(); 724 744 if (sound_get_pitch() == PITCH_SPEED_100 && ts == PITCH_SPEED_100) 725 - { /* if default then run pitch screen directly */ 726 - gui_syncpitchscreen_run(); 727 - action = ACTION_EXIT_MENUITEM; 745 + { 746 + pitch_menu__.icon_id = Icon_Audio; 747 + if (action == ACTION_ENTER_MENUITEM) 748 + { /* if default then run pitch screen directly */ 749 + gui_syncpitchscreen_run(); 750 + action = ACTION_EXIT_MENUITEM; 751 + } 728 752 } 729 753 } 730 754 return action; ··· 732 756 (void)this_item; 733 757 (void)this_list; 734 758 } 735 - 736 - /* pitch submenu */ 737 - MAKE_ONPLAYMENU(pitch_menu, ID2P(LANG_PITCH), 738 - pitch_callback, Icon_Audio, 739 - &pitch_screen_item, 740 - &pitch_reset_item); 759 + #endif /*def HAVE_PITCHCONTROL*/ 741 760 742 - #endif /*def HAVE_PITCHCONTROL*/ 743 761 #ifdef HAVE_ALBUMART 744 762 MENUITEM_FUNCTION(view_album_art_item, 0, ID2P(LANG_VIEW_ALBUMART), 745 763 view_album_art, NULL, Icon_NOICON);
+2 -40
apps/plugins/pitch_screen.c
··· 22 22 #include "plugin.h" 23 23 #include "lib/icon_helper.h" 24 24 #include "lib/arg_helper.h" 25 - #include "lib/configfile.h" 26 - #include "../gui/pitchscreen.h" /*PITCH_CFG_FILE*/ 27 - 28 - #define CFG_FILE PITCH_CFG_FILE 29 - #define CFG_VER 1 30 25 31 26 #define ICON_BORDER 12 /* icons are currently 7x8, so add ~2 pixels */ 32 27 /* on both sides when drawing */ ··· 53 48 int32_t flags; 54 49 }; 55 50 static struct pvars pitch_vars; 56 - 57 - static struct configdata pitchcfg[] = 58 - { 59 - {TYPE_INT, PITCH_MIN, PITCH_MAX, { .int32_p = &pitch_vars.pitch }, "pitch", NULL}, 60 - {TYPE_INT, STRETCH_MIN, STRETCH_MAX, { .int32_p = &pitch_vars.stretch }, "stretch", NULL}, 61 - }; 62 51 63 52 enum 64 53 { ··· 1229 1218 bool gui = false; 1230 1219 rb->pcmbuf_set_low_latency(true); 1231 1220 1232 - struct pvars cur; 1233 - fill_pitchvars(&cur); 1234 - 1235 1221 /* Figure out whether to be in timestretch mode */ 1236 1222 if (parameter == NULL) /* gui mode */ 1237 1223 { ··· 1241 1227 rb->settings_save(); 1242 1228 } 1243 1229 gui = true; 1244 - if (rb->file_exists(CFG_FILE)) 1245 - { 1246 - if (configfile_load(CFG_FILE, pitchcfg, 2, CFG_VER) >= 0) 1247 - { 1248 - if (pitch_vars.pitch != cur.pitch || pitch_vars.stretch != cur.stretch) 1249 - { 1250 - if (rb->yesno_pop(ID2P(LANG_REVERT_TO_DEFAULT_SETTINGS))) 1251 - { 1252 - rb->sound_set_pitch(pitch_vars.pitch); 1253 - rb->dsp_set_timestretch(pitch_vars.stretch); 1254 - } 1255 - } 1256 - } 1257 - } 1258 - 1259 1230 } 1260 1231 else 1261 1232 { 1233 + struct pvars cur; 1234 + fill_pitchvars(&cur); 1262 1235 fill_pitchvars(&pitch_vars); 1263 1236 argparse((const char*) parameter, -1, NULL, &arg_callback); 1264 1237 if (pitch_vars.pitch != cur.pitch) ··· 1302 1275 1303 1276 if (gui && gui_syncpitchscreen_run() == 1) 1304 1277 return PLUGIN_USB_CONNECTED; 1305 - 1306 - if (gui) 1307 - { 1308 - fill_pitchvars(&pitch_vars); 1309 - 1310 - if (pitch_vars.pitch != cur.pitch || pitch_vars.stretch != cur.stretch) 1311 - { 1312 - if (configfile_save(CFG_FILE, pitchcfg, 2, CFG_VER) < 0) 1313 - rb->splash(HZ, ID2P(LANG_ERROR_WRITING_CONFIG)); 1314 - } 1315 - } 1316 1278 rb->pcmbuf_set_low_latency(false); 1317 1279 return PLUGIN_OK; 1318 1280 }
+11 -1
apps/root_menu.c
··· 321 321 static int wpsscrn(void* param) 322 322 { 323 323 int ret_val = GO_TO_PREVIOUS; 324 + int audstatus = audio_status(); 324 325 (void)param; 325 326 push_current_activity(ACTIVITY_WPS); 326 - if (audio_status()) 327 + 328 + #ifdef HAVE_PITCHCONTROL 329 + if (!audstatus) 330 + { 331 + sound_set_pitch(global_status.resume_pitch); 332 + dsp_set_timestretch(global_status.resume_speed); 333 + } 334 + #endif 335 + 336 + if (audstatus) 327 337 { 328 338 talk_shutup(); 329 339 ret_val = gui_wps_show();
+4
apps/settings.h
··· 326 326 uint32_t resume_crc32; /* crc32 of the name of the file */ 327 327 uint32_t resume_elapsed; /* elapsed time in last file */ 328 328 uint32_t resume_offset; /* byte offset in mp3 file */ 329 + #ifdef HAVE_PITCHCONTROL 330 + int32_t resume_pitch; 331 + int32_t resume_speed; 332 + #endif 329 333 int runtime; /* current runtime since last charge */ 330 334 int topruntime; /* top known runtime */ 331 335 #ifdef HAVE_DIRCACHE
+4
apps/settings_list.c
··· 977 977 SYSTEM_SETTING(NVRAM(4), resume_elapsed, -1), 978 978 SYSTEM_SETTING(NVRAM(4), resume_offset, -1), 979 979 SYSTEM_SETTING(NVRAM(4), resume_modified, false), 980 + #ifdef HAVE_PITCHCONTROL 981 + SYSTEM_SETTING(NVRAM(4), resume_pitch, PITCH_SPEED_100), 982 + SYSTEM_SETTING(NVRAM(4), resume_speed, PITCH_SPEED_100), 983 + #endif 980 984 CHOICE_SETTING(F_CB_ON_SELECT_ONLY|F_CB_ONLY_IF_CHANGED, repeat_mode, 981 985 LANG_REPEAT, REPEAT_OFF, "repeat", "off,all,one,shuffle" 982 986 #ifdef AB_REPEAT_ENABLE
+1 -1
apps/settings_list.h
··· 161 161 162 162 #define F_NVRAM_BYTES_MASK 0xE0000 /*0-4 bytes can be stored */ 163 163 #define F_NVRAM_MASK_SHIFT 17 164 - #define NVRAM_CONFIG_VERSION 8 164 + #define NVRAM_CONFIG_VERSION 9 165 165 /* Above define should be bumped if 166 166 - a new NVRAM setting is added between 2 other NVRAM settings 167 167 - number of bytes for a NVRAM setting is changed
+2
firmware/sound.c
··· 636 636 return; 637 637 638 638 audiohw_set_pitch(pitch); 639 + /* filter out invalid by grabbing the value actually set */ 640 + global_status.resume_pitch = dsp_get_pitch(); 639 641 } 640 642 641 643 int32_t sound_get_pitch(void)
+6
lib/rbcodec/dsp/tdspeed.c
··· 27 27 #include "dsp-util.h" 28 28 #include "dsp_proc_entry.h" 29 29 #include "tdspeed.h" 30 + #ifdef ROCKBOX 31 + #include "settings.h" 32 + #endif 30 33 31 34 #ifndef assert 32 35 #define assert(cond) ··· 402 405 403 406 struct dsp_config *dsp = dsp_get_config(CODEC_IDX_AUDIO); 404 407 dsp_configure(dsp, TIMESTRETCH_SET_FACTOR, percent); 408 + #ifdef ROCKBOX /* filter out invalid by grabbing the value actually set */ 409 + global_status.resume_speed = st->factor; 410 + #endif 405 411 } 406 412 407 413 /* Return the timestretch ratio */
+3 -8
manual/rockbox_interface/wps.tex
··· 288 288 289 289 The value of the rate, pitch and speed 290 290 is persistent, i.e. when the \dap\ is turned on it will 291 - always be set to your last value set by \setting{Pitch Screen}. 291 + always be set to the last value set by \setting{Pitch Screen} or Bookmarks. 292 292 Selecting \setting{Pitch} again will now display a menu with 293 293 \setting{Pitch} and \setting{Reset Setting}. 294 294 Selecting \setting{Reset Setting} will reset the pitch to 100\% now and at next boot. 295 - However the rate, pitch and speed information will be stored in any bookmarks 295 + However the rate, pitch and speed information is stored in any bookmarks 296 296 you may create (see \reference{ref:Bookmarkconfigactual}) 297 - while the pitch is altered and will be restored upon 298 - playing back those bookmarks. 299 - 300 - \note{ If a bookmark has changed pitch, settings will remain till 301 - changed again or the \dap{} is restarted and your (default) settings will then be 302 - restored} 297 + and will be restored upon playing back those bookmarks. 303 298 304 299 \begin{btnmap} 305 300 \ActionPsToggleMode