diff -u -r ./rockbox-20070513-original/apps/menus/recording_menu.c ./rockbox-20070513/apps/menus/recording_menu.c --- ./rockbox-20070513-original/apps/menus/recording_menu.c 2007-04-15 18:20:01.000000000 -0400 +++ ./rockbox-20070513/apps/menus/recording_menu.c 2007-05-18 00:08:25.000000000 -0400 @@ -42,6 +42,7 @@ #include "sound.h" #ifdef HAVE_RECORDING #include "audio.h" +#include "recorder/recording.h" #if CONFIG_TUNER #include "radio.h" #endif @@ -316,13 +317,7 @@ MENUITEM_SETTING(rec_prerecord_time, &global_settings.rec_prerecord_time, NULL); static int recdirectory_func(void) { - static const struct opt_items names[] = { - { rec_base_directory, -1 }, - { STR(LANG_RECORD_CURRENT_DIR) } - }; - return set_option(str(LANG_RECORD_DIRECTORY), - &global_settings.rec_directory, INT, - names, 2, NULL ); + return recording_directory_menu(); } MENUITEM_FUNCTION(recdirectory, 0, ID2P(LANG_RECORD_DIRECTORY), recdirectory_func, NULL, NULL, Icon_Menu_setting); diff -u -r ./rockbox-20070513-original/apps/onplay.c ./rockbox-20070513/apps/onplay.c --- ./rockbox-20070513-original/apps/onplay.c 2007-05-02 21:20:01.000000000 -0400 +++ ./rockbox-20070513/apps/onplay.c 2007-05-17 16:16:00.000000000 -0400 @@ -64,6 +64,9 @@ #ifdef HAVE_TAGCACHE #include "tagtree.h" #endif +#ifdef HAVE_RECORDING +#include "recorder/recording.h" +#endif #if (LCD_DEPTH > 1) || (defined(HAVE_LCD_REMOTE) && (LCD_REMOTE_DEPTH > 1)) #include "backdrop.h" @@ -872,6 +875,14 @@ return true; } +#ifdef HAVE_RECORDING +static bool add_as_rec_dir(void) +{ + rec_path_insert(selected_file); + return true; +} +#endif + static int onplaymenu_callback(int action,const struct menu_item_ex *this_item) { (void)this_item; @@ -957,6 +968,10 @@ properties, NULL, clipboard_callback, Icon_NOICON); MENUITEM_FUNCTION(create_dir_item, 0, ID2P(LANG_CREATE_DIR), create_dir, NULL, clipboard_callback, Icon_NOICON); +#ifdef HAVE_RECORDING +MENUITEM_FUNCTION(add_as_rec_dir_item, 0, "Add as Rec Dir", + add_as_rec_dir, NULL, clipboard_callback, Icon_NOICON); +#endif MENUITEM_FUNCTION(list_viewers_item, 0, ID2P(LANG_ONPLAY_OPEN_WITH), list_viewers, NULL, clipboard_callback, Icon_NOICON); #if LCD_DEPTH > 1 @@ -1010,6 +1025,11 @@ if ((this_item == &delete_dir_item) ) return action; +#ifdef HAVE_RECORDING + if ((this_item == &add_as_rec_dir_item) + ) + return action; +#endif } else if (selected_file #ifdef HAVE_MULTIVOLUME @@ -1055,7 +1075,11 @@ #if LCD_DEPTH > 1 &set_backdrop_item, #endif - &list_viewers_item, &create_dir_item, &properties_item + &list_viewers_item, &create_dir_item, +#ifdef HAVE_RECORDING + &add_as_rec_dir_item, +#endif + &properties_item ); int onplay(char* file, int attr, int from) { diff -u -r ./rockbox-20070513-original/apps/recorder/recording.c ./rockbox-20070513/apps/recorder/recording.c --- ./rockbox-20070513-original/apps/recorder/recording.c 2007-05-04 11:20:02.000000000 -0400 +++ ./rockbox-20070513/apps/recorder/recording.c 2007-05-18 00:10:25.000000000 -0400 @@ -68,6 +68,7 @@ #include "screen_access.h" #include "action.h" #include "radio.h" +#include "plugin.h" #ifdef HAVE_RECORDING static bool in_screen = false; @@ -114,6 +115,11 @@ /* path for current file */ static char path_buffer[MAX_PATH]; +/* For displaying current recording path */ +#define MAX_PATH_DISPLAY 20 +static char path_buffer_display[MAX_PATH_DISPLAY] = ""; +static size_t path_length = 0; + /** Automatic Gain Control (AGC) **/ #ifdef HAVE_AGC /* Timing counters: @@ -470,15 +476,15 @@ switch(global_settings.rec_source) { case AUDIO_SRC_MIC: - if(cursor == 2) - cursor = 4; - else if(cursor == 3) - cursor = 1; + if(cursor == 3) + cursor = 5; + else if(cursor == 4) + cursor = 2; case AUDIO_SRC_LINEIN: #ifdef HAVE_FMRADIO_IN case AUDIO_SRC_FMRADIO: #endif - max_cursor = 5; + max_cursor = 6; break; default: max_cursor = 0; @@ -488,13 +494,13 @@ switch(global_settings.rec_source) { case AUDIO_SRC_MIC: - max_cursor = 1; + max_cursor = 2; break; case AUDIO_SRC_LINEIN: #ifdef HAVE_FMRADIO_IN case AUDIO_SRC_FMRADIO: #endif - max_cursor = 3; + max_cursor = 4; break; default: max_cursor = 0; @@ -506,14 +512,15 @@ cursor = max_cursor; } +/* buffer should already contain the path. */ char *rec_create_filename(char *buffer) { char ext[16]; + char *dir_name; - if(global_settings.rec_directory) - getcwd(buffer, MAX_PATH); - else - strncpy(buffer, rec_base_directory, MAX_PATH); + /* The buffer may contain the full file name from the previous recording, + remove the file name. */ + buffer[path_length] = '\0'; snprintf(ext, sizeof(ext), ".%s", REC_FILE_ENDING(global_settings.rec_format)); @@ -528,19 +535,25 @@ #endif } +/* path_buffer should already contain the path. */ int rec_create_directory(void) { int rc; /* Try to create the base directory if needed */ - if(global_settings.rec_directory == 0) + if(global_settings.rec_directory != 1) { - rc = mkdir(rec_base_directory); + + /* The path_buffer may contain the full file name from the previous + recording. Remove the file name. */ + path_buffer[path_length] = '\0'; + + rc = mkdir(path_buffer); if(rc < 0 && errno != EEXIST) { gui_syncsplash(HZ * 2, "Can't create the %s directory. Error code %d.", - rec_base_directory, rc); + path_buffer, rc); return -1; } else @@ -745,6 +758,525 @@ } } +#define REC_PATH_FILE ROCKBOX_DIR "/.rec_path" +#define MAX_NUM_USER_REC_PATH 15 + +unsigned int num_user_rec_dir = 0; +bool user_rec_path_in_ram = false; +bool rec_path_buffer_dirty = false; + +/* + .rec_path file contains the names of the user-defined recording paths. It + contains two different data types. + + Its zeroth element is an unsigned int indicating the number of paths contained + in the file. The first through the (MAX_NUM_USER_REC_PATH)th elements + are unsigned integers indicating the starting position of the path names + in the char block mentioned below. + + The (MAX_NUM_USER_REC_PATH + 2)th element through the end of file is a char + block containing the actual path name of the user-defined recording directories. + Each path name contains the null terminator in the end. + + The (num_user_rec_dir + 1)th element in the index portion of the buffer contain the + total number of characters in the char block. + + The max number of the paths contained in .rec_path is MAX_NUM_USER_REC_PATH. + + rec_path_buffer contains an exact replica of the .rec_path file. + + For fetching, viewing, and removing directory names, current implementation + temporarily loads the REC_PATH_FILE into the plugin buffer. Currently, + there is no mechanism to cope with the case in which the size of the content + of the file is bigger than the available plugin buffer. (This can be solved + with loading only the portion of the file into the buffer, as in the playlist + viewer implementation). + Thus, MAX_NUM_USER_REC_PATH should be kept relatively small under the current + implementation. +*/ + +/* Call once when the player initializes */ +void rec_path_init(void) +{ + int rec_path_fd; + ssize_t nread; + bool create_new_rec_path_file = false; + int i; + + rec_path_fd = open(REC_PATH_FILE, O_RDONLY); + + if( rec_path_fd != - 1) + { + nread = read(rec_path_fd, &num_user_rec_dir, sizeof(unsigned int)); + + if( (nread != (ssize_t)sizeof(unsigned int)) || + (num_user_rec_dir > MAX_NUM_USER_REC_PATH) ) + { + /* The file is corrupt. Create a new file. */ + create_new_rec_path_file = true; + num_user_rec_dir = 0; + } + + if( global_settings.rec_directory - 2 > (int)num_user_rec_dir ) + { + /* This should never happen. */ + /* Set the player to use the default directory */ + global_settings.rec_directory = 0; + } + + close(rec_path_fd); + } + else + { + create_new_rec_path_file = true; + } + + if( create_new_rec_path_file ) + { + if( global_settings.rec_directory > 1 ) + { + /* Set the player to use the default directory */ + global_settings.rec_directory = 0; + } + + rec_path_fd = open(REC_PATH_FILE, + O_CREAT|O_RDWR|O_TRUNC); + + if( rec_path_fd < 0 ) + { + if (check_rockboxdir()) + { + gui_syncsplash(HZ*2, (unsigned char *)"%s (%d)", + str(LANG_PLAYLIST_DIRECTORY_ACCESS_ERROR), + rec_path_fd); + } + return; + } + else + { + /* Initialize the file. Write the header. */ + for( i = 0; i < MAX_NUM_USER_REC_PATH + 2; i++ ) + { + write(rec_path_fd, &num_user_rec_dir, sizeof(unsigned int)); + } + + close(rec_path_fd); + } + } /* End if( create_new_rec_path_file ) */ +} + +/* For writing rec_path_buffer onto .rec_path file */ +bool rec_path_save(void* rec_path_buffer) +{ + int rec_path_fd; + unsigned int *indices; + unsigned int num_path_chars; + size_t buffer_size; + + if(rec_path_buffer == NULL) return false; + + rec_path_fd = open(REC_PATH_FILE, O_WRONLY); + + if( rec_path_fd < 0 ) + { + if (check_rockboxdir()) + { + gui_syncsplash(HZ*2, (unsigned char *)"%s (%d)", + str(LANG_PLAYLIST_DIRECTORY_ACCESS_ERROR), + rec_path_fd); + } + return false; + } + + indices = (unsigned int*)rec_path_buffer; + indices++; + + num_path_chars = indices[num_user_rec_dir]; + + buffer_size = sizeof(unsigned int) * (MAX_NUM_USER_REC_PATH + 2) + + sizeof(char) * (size_t)num_path_chars; + + write(rec_path_fd, rec_path_buffer, buffer_size ); + + close(rec_path_fd); + + return true; +} + +/* For reading .rec_path file into rec_path_buffer */ +bool rec_path_load(void* rec_path_buffer, size_t path_buffer_size) +{ + int rec_path_fd; + unsigned int num_path_chars; + size_t buffer_size; + ssize_t num_of_bytes_read; + unsigned int *indices; + size_t char_block_size; + + if(rec_path_buffer == NULL) return false; + + if( num_user_rec_dir == 0 ) + { + indices = (unsigned int*)rec_path_buffer; + indices[0] = 0; + indices[1] = 0; + return true; + } + + rec_path_fd = open(REC_PATH_FILE, O_RDONLY); + + if( rec_path_fd < 0 ) + { + if (check_rockboxdir()) + { + gui_syncsplash(HZ*2, (unsigned char *)"%s (%d)", + str(LANG_PLAYLIST_DIRECTORY_ACCESS_ERROR), + rec_path_fd); + } + return false; + } + + /* First, read the index block. */ + buffer_size = sizeof(unsigned int) * (MAX_NUM_USER_REC_PATH + 2); + + if( buffer_size > path_buffer_size ) goto exit; + + num_of_bytes_read = read(rec_path_fd, rec_path_buffer, buffer_size ); + + if( num_of_bytes_read != (ssize_t)num_of_bytes_read ) goto exit; + + indices = (unsigned int*)rec_path_buffer; + + /* Get the number of characters in the char block. */ + num_path_chars = indices[num_user_rec_dir + 1]; + + /* Read the char block. */ + char_block_size = sizeof(char) * (size_t)num_path_chars; + if( buffer_size + char_block_size > path_buffer_size ) goto exit; + num_of_bytes_read = read(rec_path_fd, + (void*)(indices + MAX_NUM_USER_REC_PATH + 2), + char_block_size); + + close(rec_path_fd); + + if( num_of_bytes_read != (ssize_t)char_block_size ) + return false; + else + return true; + +exit: + close(rec_path_fd); + return false; +} + +/* For removing a directory in rec_path_buffer. idx is zero-based. */ +void rec_path_remove(void* rec_path_buffer, unsigned int idx) +{ + unsigned int *index_array; + char *char_array; + unsigned int num_path_chars; + unsigned int i; + unsigned int starting_pos; + unsigned int next_starting_pos; + unsigned int string_length; + + if(rec_path_buffer == NULL) return; + + if( idx >= num_user_rec_dir ) return; + + index_array = (unsigned int*)rec_path_buffer; + index_array++; + + char_array = (char*)(index_array + MAX_NUM_USER_REC_PATH + 1); + + starting_pos = index_array[idx]; + next_starting_pos = index_array[idx + 1]; + + string_length = next_starting_pos - starting_pos; + + /* Remove the path in the index array. */ + for( i = idx; i < num_user_rec_dir; i++ ) + { + index_array[i] = index_array[i+1] - string_length; + } + + /* Adjust the number of characters. */ + num_user_rec_dir--; + num_path_chars = index_array[num_user_rec_dir]; + + /* Remove the path in the character array. */ + for( i = starting_pos; i < num_path_chars; i++ ) + { + char_array[i] = char_array[i+string_length]; + } + + index_array[-1] = num_user_rec_dir; +} + +void rec_path_remove_all(void* rec_path_buffer) +{ + unsigned int *indices; + + if(rec_path_buffer == NULL) return; + + indices = (unsigned int*)rec_path_buffer; + indices[0] = 0; + indices[1] = 0; + + num_user_rec_dir = 0; + + return; +} + +/* idx==0 for the default directory. + idx==1 for the current directory. + idx >= 2 for the user defined directories. +*/ +char* rec_path_get(void* rec_path_buffer, int idx) +{ + + unsigned int *index_array; + char *char_array; + size_t string_length; + char *dir_name; + + if( rec_path_buffer == NULL || idx > (int)num_user_rec_dir + 1 ) + idx = 0; + + if( idx == 0 ) + { + strncpy(path_buffer, rec_base_directory, MAX_PATH); + } + else if( idx == 1 ) + { + getcwd(path_buffer, MAX_PATH); + } + else + { + idx -= 2; + + index_array = (unsigned int*)rec_path_buffer; + index_array++; + string_length = index_array[idx+1] - index_array[idx]; + + char_array = (char*)(index_array + MAX_NUM_USER_REC_PATH + 1); + + strncpy(path_buffer, &char_array[index_array[idx]], string_length); + } + + /* Get the recording directory name for display. */ + dir_name = strrchr(path_buffer, '/'); + if( dir_name ) + { + strncpy(path_buffer_display, dir_name, MAX_PATH_DISPLAY); + } + else + { + path_buffer_display[0] = '\0'; + } + + path_length = strlen(path_buffer); + return path_buffer; + +} + +/* This API directly writes onto REC_PATH_FILE. */ +bool rec_path_insert(char* path) +{ + int rec_path_fd; + unsigned int num_path_chars; + size_t num_of_bytes; + ssize_t num_of_bytes_ret; + size_t pathlen; + + if( path == NULL ) return false; + + if( num_user_rec_dir == 0 ) rec_path_init(); + + rec_path_fd = open(REC_PATH_FILE, O_RDWR); + + if( rec_path_fd < 0 ) + { + if (check_rockboxdir()) + { + gui_syncsplash(HZ*2, (unsigned char *)"%s (%d)", + str(LANG_PLAYLIST_DIRECTORY_ACCESS_ERROR), + rec_path_fd); + } + return false; + } + + pathlen = strlen(path); + pathlen++; + + /* Get the current number of characters in the char block. */ + lseek( rec_path_fd, + (off_t)(sizeof(unsigned int) * ((size_t)num_user_rec_dir + 1)), + SEEK_SET ); + num_of_bytes = sizeof(unsigned int); + num_of_bytes_ret = read(rec_path_fd, &num_path_chars, num_of_bytes); + + if( num_of_bytes_ret != (ssize_t)num_of_bytes ) goto exit; + + /* Update number of characters in the char block. */ + num_path_chars += (unsigned int)pathlen; + num_of_bytes = sizeof(unsigned int); + num_of_bytes_ret = write(rec_path_fd, &num_path_chars, num_of_bytes ); + + if( num_of_bytes_ret != (ssize_t)num_of_bytes ) goto exit; + + /* Write the path string. */ + lseek( rec_path_fd, + (off_t)(sizeof(unsigned int) * (MAX_NUM_USER_REC_PATH+2) + + sizeof(char)*(size_t)(num_path_chars-pathlen)), SEEK_SET ); + num_of_bytes = sizeof(char) * pathlen; + num_of_bytes_ret = write(rec_path_fd, (void*)path, num_of_bytes); + + if( num_of_bytes_ret != (ssize_t)num_of_bytes ) goto exit; + + /* Update the number of paths */ + num_user_rec_dir++; + lseek( rec_path_fd, 0, SEEK_SET ); + num_of_bytes = sizeof(unsigned int); + num_of_bytes_ret = write(rec_path_fd, &num_user_rec_dir, num_of_bytes); + + if( num_of_bytes_ret != (ssize_t)num_of_bytes ) goto exit; + + close(rec_path_fd); + return true; + +exit: + close(rec_path_fd); + return false; +} + +static char *rec_path_callback_name(int selected_item, void *data, char *buffer) +{ + + char* str; + + if( selected_item == 0 ) + { + str = str(LANG_REMOVE); + snprintf(buffer, strlen(str)+1, "%s", str); + } + else if( selected_item == 1 ) + { + strncpy(buffer, rec_base_directory, MAX_PATH); + } + else if( selected_item == 2 ) + { + str = str(LANG_RECORD_CURRENT_DIR); + snprintf(buffer, strlen(str)+1, "%s", str); + } + else + { + str = rec_path_get( data, selected_item - 1 ); + snprintf(buffer, strlen(str)+1, "%s", str ); + } + + return(buffer); +} + +/* Recording-directory menuitem function. */ +bool recording_directory_menu(void) +{ + bool ret = false; /* return value */ + bool exit=false; /* exit viewer */ + int button; + struct gui_synclist rec_path_lists; + void* rec_path_buffer; + size_t buffer_size; + int idx; + + rec_path_buffer = plugin_get_buffer(&buffer_size); + if(!rec_path_buffer) goto exit; + + rec_path_init(); + if(!rec_path_load(rec_path_buffer, buffer_size)) rec_path_remove_all(rec_path_buffer); + + gui_synclist_init(&rec_path_lists, rec_path_callback_name, rec_path_buffer, false, 1); + gui_synclist_set_nb_items(&rec_path_lists, (int)(num_user_rec_dir + 3)); + gui_synclist_select_item(&rec_path_lists, global_settings.rec_directory+1); + gui_synclist_set_title(&rec_path_lists, str(LANG_RECORD_DIRECTORY), Icon_NOICON); + gui_synclist_draw(&rec_path_lists); + action_signalscreenchange(); + while (!exit) + { + /* Timeout so we can determine if play status has changed */ + button = get_action(CONTEXT_TREE,HZ/2); + idx=gui_synclist_get_sel_pos(&rec_path_lists); + if( idx != 0 ) global_settings.rec_directory = idx - 1; + else global_settings.rec_directory = 0; + + int list_action; + if( (list_action=gui_synclist_do_button(&rec_path_lists, button,LIST_WRAP_UNLESS_HELD))!=0 ) + { + } + switch (button) + { + case ACTION_TREE_WPS: + case ACTION_STD_CANCEL: + rec_path_get(rec_path_buffer, global_settings.rec_directory); + /* Upon exit, save the recording directory list onto the disk if modified */ + if(rec_path_buffer_dirty) + { + rec_path_save(rec_path_buffer); + rec_path_buffer_dirty = false; + } + exit = true; + break; + case ACTION_STD_OK: + { + /* If "Remove All" is selected, remove all user-defined recording directories. */ + if( idx == 0 ) + { + rec_path_buffer_dirty = true; + rec_path_remove_all( rec_path_buffer ); + gui_synclist_set_nb_items(&rec_path_lists, (int)(num_user_rec_dir + 3)); + global_settings.rec_directory = 0; + gui_synclist_draw(&rec_path_lists); + } + break; + } + case ACTION_STD_CONTEXT: + { + /* Currently, no contenxt-menu feature for the "Recording Options:Directory" menu item.*/ + /* ON+PLAY menu */ + break; + } + case ACTION_STD_MENU: + /* If a user-defined recording directory, remove from the list. + Currently, there's no submenu inside the "Recording Options:Directory" menu. + It could be added in a later version. */ + if(idx > 2) + { + rec_path_buffer_dirty = true; + rec_path_remove( rec_path_buffer, (unsigned int)idx - 3 ); + gui_synclist_del_item(&rec_path_lists); + gui_synclist_draw(&rec_path_lists); + } + break; + + case ACTION_NONE: + gui_syncstatusbar_draw(&statusbars, false); + break; + + default: + if(default_event_handler(button) == SYS_USB_CONNECTED) + { + ret = true; + goto exit; + } + break; + } + } + +exit: + action_signalscreenchange(); + return ret; +} + bool recording_start_automatic = false; bool recording_screen(bool no_source) @@ -793,6 +1325,8 @@ int trig_xpos[NB_SCREENS]; int trig_ypos[NB_SCREENS]; int trig_width[NB_SCREENS]; + void* rec_path_buffer; + size_t buffer_size; static const unsigned char *byte_units[] = { ID2P(LANG_BYTE), @@ -834,6 +1368,16 @@ set_gain(); settings_apply_trigger(); + rec_path_init(); + rec_path_buffer = plugin_get_buffer(&buffer_size); + if(!rec_path_buffer || + !rec_path_load(rec_path_buffer, buffer_size)) + { + num_user_rec_dir = 0; + if( global_settings.rec_directory > 2 ) + global_settings.rec_directory = 0; + } + #ifdef HAVE_AGC agc_preset_str[0] = str(LANG_SYSFONT_OFF); agc_preset_str[1] = str(LANG_SYSFONT_AGC_SAFETY); @@ -860,6 +1404,7 @@ pm_y[i] = 8 + h * (2 + filename_offset[i]); } + rec_path_get( rec_path_buffer, global_settings.rec_directory); if(rec_create_directory() > 0) have_recorded = true; #ifdef HAVE_REMOTE_LCD @@ -1059,12 +1604,31 @@ switch(cursor) { case 0: + if(!((audio_stat & AUDIO_STATUS_RECORD) || + (audio_stat & AUDIO_STATUS_PAUSE))) + { + if( global_settings.rec_directory < + (int)(num_user_rec_dir + 1) ) + global_settings.rec_directory++; + + rec_path_get(rec_path_buffer, + global_settings.rec_directory ); + + if(rec_create_directory()) + { + global_settings.rec_directory = 0; + rec_path_get(rec_path_buffer, + global_settings.rec_directory ); + } + } + break; + case 1: if(global_settings.volume < sound_max(SOUND_VOLUME)) global_settings.volume++; sound_set_volume(global_settings.volume); break; - case 1: + case 2: if(global_settings.rec_source == AUDIO_SRC_MIC) { if(global_settings.rec_mic_gain < @@ -1081,18 +1645,18 @@ global_settings.rec_right_gain++; } break; - case 2: + case 3: if(global_settings.rec_left_gain < sound_max(SOUND_LEFT_GAIN)) global_settings.rec_left_gain++; break; - case 3: + case 4: if(global_settings.rec_right_gain < sound_max(SOUND_RIGHT_GAIN)) global_settings.rec_right_gain++; break; #ifdef HAVE_AGC - case 4: + case 5: agc_preset = MIN(agc_preset + 1, AGC_MODE_SIZE); agc_enable = (agc_preset != 0); if (global_settings.rec_source == AUDIO_SRC_MIC) { @@ -1103,7 +1667,7 @@ agc_maxgain = global_settings.rec_agc_maxgain_line; } break; - case 5: + case 6: if (global_settings.rec_source == AUDIO_SRC_MIC) { agc_maxgain = MIN(agc_maxgain + 1, @@ -1127,12 +1691,30 @@ switch(cursor) { case 0: + if(!((audio_stat & AUDIO_STATUS_RECORD) || + (audio_stat & AUDIO_STATUS_PAUSE))) + { + if( global_settings.rec_directory > 0 ) + global_settings.rec_directory--; + + rec_path_get(rec_path_buffer, + global_settings.rec_directory ); + + if(rec_create_directory()) + { + global_settings.rec_directory = 0; + rec_path_get(rec_path_buffer, + global_settings.rec_directory ); + } + } + break; + case 1: if(global_settings.volume > sound_min(SOUND_VOLUME)) global_settings.volume--; sound_set_volume(global_settings.volume); break; - case 1: + case 2: if(global_settings.rec_source == AUDIO_SRC_MIC) { if(global_settings.rec_mic_gain > @@ -1149,18 +1731,18 @@ global_settings.rec_right_gain--; } break; - case 2: + case 3: if(global_settings.rec_left_gain > sound_min(SOUND_LEFT_GAIN)) global_settings.rec_left_gain--; break; - case 3: + case 4: if(global_settings.rec_right_gain > sound_min(SOUND_RIGHT_GAIN)) global_settings.rec_right_gain--; break; #ifdef HAVE_AGC - case 4: + case 5: agc_preset = MAX(agc_preset - 1, 0); agc_enable = (agc_preset != 0); if (global_settings.rec_source == AUDIO_SRC_MIC) { @@ -1171,7 +1753,7 @@ agc_maxgain = global_settings.rec_agc_maxgain_line; } break; - case 5: + case 6: if (global_settings.rec_source == AUDIO_SRC_MIC) { agc_maxgain = MAX(agc_maxgain - 1, @@ -1458,21 +2040,37 @@ update_countdown = 1; } + /* Display the line for the Directory option */ + snprintf(buf, sizeof(buf), "%s: %s", str(LANG_RECORD_DIRECTORY), + path_buffer_display); + + if (global_settings.invert_cursor && (pos++ == cursor)) + { + for(i = 0; i < screen_update; i++) + screens[i].puts_style_offset(0, filename_offset[i] + + PM_HEIGHT + 2, buf, STYLE_INVERT,0); + } + else + { + for(i = 0; i < screen_update; i++) + screens[i].puts(0, filename_offset[i] + PM_HEIGHT + 2, buf); + } + snprintf(buf, sizeof(buf), "%s: %s", str(LANG_SYSFONT_VOLUME), fmt_gain(SOUND_VOLUME, global_settings.volume, buf2, sizeof(buf2))); - if (global_settings.invert_cursor && (pos++ == cursor)) + if (global_settings.invert_cursor && (1==cursor)) { for(i = 0; i < screen_update; i++) screens[i].puts_style_offset(0, filename_offset[i] + - PM_HEIGHT + 2, buf, STYLE_INVERT,0); + PM_HEIGHT + 3, buf, STYLE_INVERT,0); } else { for(i = 0; i < screen_update; i++) - screens[i].puts(0, filename_offset[i] + PM_HEIGHT + 2, buf); + screens[i].puts(0, filename_offset[i] + PM_HEIGHT + 3, buf); } if(global_settings.rec_source == AUDIO_SRC_MIC) @@ -1482,17 +2080,17 @@ fmt_gain(SOUND_MIC_GAIN, global_settings.rec_mic_gain, buf2, sizeof(buf2))); - if(global_settings.invert_cursor && ((1==cursor)||(2==cursor))) + if(global_settings.invert_cursor && ((2==cursor)||(3==cursor))) { for(i = 0; i < screen_update; i++) screens[i].puts_style_offset(0, filename_offset[i] + - PM_HEIGHT + 3, buf, STYLE_INVERT,0); + PM_HEIGHT + 4, buf, STYLE_INVERT,0); } else { for(i = 0; i < screen_update; i++) screens[i].puts(0, filename_offset[i] + - PM_HEIGHT + 3, buf); + PM_HEIGHT + 4, buf); } } else if(global_settings.rec_source == AUDIO_SRC_LINEIN @@ -1507,17 +2105,17 @@ fmt_gain(SOUND_LEFT_GAIN, global_settings.rec_left_gain, buf2, sizeof(buf2))); - if(global_settings.invert_cursor && ((1==cursor)||(2==cursor))) + if(global_settings.invert_cursor && ((2==cursor)||(3==cursor))) { for(i = 0; i < screen_update; i++) screens[i].puts_style_offset(0, filename_offset[i] + - PM_HEIGHT + 3, buf, STYLE_INVERT,0); + PM_HEIGHT + 4, buf, STYLE_INVERT,0); } else { for(i = 0; i < screen_update; i++) screens[i].puts(0, filename_offset[i] + - PM_HEIGHT + 3, buf); + PM_HEIGHT + 4, buf); } snprintf(buf, sizeof(buf), "%s:%s", @@ -1525,17 +2123,17 @@ fmt_gain(SOUND_RIGHT_GAIN, global_settings.rec_right_gain, buf2, sizeof(buf2))); - if(global_settings.invert_cursor && ((1==cursor)||(3==cursor))) + if(global_settings.invert_cursor && ((2==cursor)||(4==cursor))) { for(i = 0; i < screen_update; i++) screens[i].puts_style_offset(0, filename_offset[i] + - PM_HEIGHT + 4, buf, STYLE_INVERT,0); + PM_HEIGHT + 5, buf, STYLE_INVERT,0); } else { for(i = 0; i < screen_update; i++) screens[i].puts(0, filename_offset[i] + - PM_HEIGHT + 4, buf); + PM_HEIGHT + 5, buf); } } @@ -1547,18 +2145,18 @@ #ifdef HAVE_FMRADIO_IN case AUDIO_SRC_FMRADIO: #endif - line[i] = 5; + line[i] = 6; break; case AUDIO_SRC_MIC: - line[i] = 4; + line[i] = 5; break; #ifdef HAVE_SPDIF_IN case AUDIO_SRC_SPDIF: - line[i] = 3; + line[i] = 4; break; #endif default: - line[i] = 5; /* to prevent uninitialisation + line[i] = 6; /* to prevent uninitialisation warnings for line[0] */ break; } /* end switch */ @@ -1571,7 +2169,7 @@ else display_agc[i] = true; - if ((cursor==4) || (cursor==5)) + if ((cursor==5) || (cursor==6)) display_agc[i] = true; } @@ -1584,7 +2182,7 @@ lcd_putsxy(LCD_WIDTH/2 + 3, LCD_HEIGHT - 8, buf); ***********************************************/ - if (cursor == 5) + if (cursor == 6) snprintf(buf, sizeof(buf), "%s: %s", str(LANG_SYSFONT_RECORDING_AGC_MAXGAIN), fmt_gain(SOUND_LEFT_GAIN, @@ -1611,7 +2209,7 @@ global_settings.rec_right_gain)/2, buf2, sizeof(buf2))); - if(global_settings.invert_cursor && ((cursor==4) || (cursor==5))) + if(global_settings.invert_cursor && ((cursor==5) || (cursor==6))) { for(i = 0; i < screen_update; i++) screens[i].puts_style_offset(0, filename_offset[i] + @@ -1656,30 +2254,36 @@ screen_put_cursorxy(&screens[i], 0, filename_offset[i] + PM_HEIGHT + 3, true); + break; + case 2: + for(i = 0; i < screen_update; i++) + screen_put_cursorxy(&screens[i], 0, + filename_offset[i] + + PM_HEIGHT + 4, true); if(global_settings.rec_source != AUDIO_SRC_MIC) { for(i = 0; i < screen_update; i++) screen_put_cursorxy(&screens[i], 0, filename_offset[i] + - PM_HEIGHT + 4, true); + PM_HEIGHT + 5, true); } break; - case 2: + case 3: for(i = 0; i < screen_update; i++) screen_put_cursorxy(&screens[i], 0, filename_offset[i] + - PM_HEIGHT + 3, true); + PM_HEIGHT + 4, true); break; - case 3: + case 4: for(i = 0; i < screen_update; i++) screen_put_cursorxy(&screens[i], 0, filename_offset[i] + - PM_HEIGHT + 4, true); + PM_HEIGHT + 5, true); break; #ifdef HAVE_AGC - case 4: case 5: + case 6: for(i = 0; i < screen_update; i++) screen_put_cursorxy(&screens[i], 0, filename_offset[i] + diff -u -r ./rockbox-20070513-original/apps/recorder/recording.h ./rockbox-20070513/apps/recorder/recording.h --- ./rockbox-20070513-original/apps/recorder/recording.h 2007-04-15 18:20:01.000000000 -0400 +++ ./rockbox-20070513/apps/recorder/recording.h 2007-05-18 00:07:13.000000000 -0400 @@ -47,4 +47,7 @@ /* creates unique filename and starts recording */ void rec_new_file(void); +/* APIs for managing the user-defined recording directories */ +bool rec_path_insert(char* path); +bool recording_directory_menu(void); #endif diff -u -r ./rockbox-20070513-original/apps/settings.h ./rockbox-20070513/apps/settings.h --- ./rockbox-20070513-original/apps/settings.h 2007-05-08 02:50:01.000000000 -0400 +++ ./rockbox-20070513/apps/settings.h 2007-05-14 15:20:16.000000000 -0400 @@ -364,7 +364,8 @@ int rec_split_method; /* time/filesize */ int rec_prerecord_time; /* In seconds, 0-30, 0 means OFF */ - int rec_directory; /* 0=base dir, 1=current dir */ + int rec_directory; /* 0=base dir, 1=current dir, + 2 and above=user-specified dir's */ int cliplight; /* 0 = off 1 = main lcd 2 = main and remote lcd