Prevent initial spinup when starting first file when in a stopped state on non-RTC targets. Fix some states that are dangerous on SWCODEC and could result in data loss. Had to make plugin API incopatible since specified numbered filename creation is enabled now on all non-RTC targets with recording; increase version and sort the items that looked like they had a place to go.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13683 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Michael Sevakis 2007-06-22 09:34:57 +00:00
parent 6e21c146f8
commit ea255fbc3a
4 changed files with 110 additions and 87 deletions

View file

@ -38,9 +38,9 @@ char *output_dyn_value(char *buf, int buf_size, int value,
* less than zero to number automatically. The final number used will also * less than zero to number automatically. The final number used will also
* be returned in *num. If *num is >= 0 then *num will be incremented by * be returned in *num. If *num is >= 0 then *num will be incremented by
* one. */ * one. */
#if CONFIG_CODEC == SWCODEC && defined(HAVE_RECORDING) && (CONFIG_RTC == 0) #if defined(HAVE_RECORDING) && (CONFIG_RTC == 0)
/* this feature is needed by SWCODEC recording without a RTC to prevent /* this feature is needed by recording without a RTC to prevent disk access
disk access when changing files */ when changing files */
#define IF_CNFN_NUM_(...) __VA_ARGS__ #define IF_CNFN_NUM_(...) __VA_ARGS__
#define IF_CNFN_NUM #define IF_CNFN_NUM
#else #else

View file

@ -104,6 +104,7 @@ static const struct plugin_api rockbox_api = {
lcd_get_background, lcd_get_background,
lcd_bitmap_part, lcd_bitmap_part,
lcd_bitmap, lcd_bitmap,
lcd_get_backdrop,
lcd_set_backdrop, lcd_set_backdrop,
#endif #endif
#if LCD_DEPTH == 16 #if LCD_DEPTH == 16
@ -217,6 +218,7 @@ static const struct plugin_api rockbox_api = {
#endif #endif
ata_spindown, ata_spindown,
reload_directory, reload_directory,
create_numbered_filename,
/* dir */ /* dir */
PREFIX(opendir), PREFIX(opendir),
@ -241,6 +243,7 @@ static const struct plugin_api rockbox_api = {
&current_tick, &current_tick,
default_event_handler, default_event_handler,
default_event_handler_ex, default_event_handler_ex,
threads,
create_thread, create_thread,
remove_thread, remove_thread,
reset_poweroff_timer, reset_poweroff_timer,
@ -403,8 +406,12 @@ static const struct plugin_api rockbox_api = {
gui_syncstatusbar_draw, gui_syncstatusbar_draw,
/* options */ /* options */
set_option, set_option,
set_bool_options,
set_int, set_int,
set_bool, set_bool,
#ifdef HAVE_LCD_COLOR
set_color,
#endif
/* action handling */ /* action handling */
get_custom_action, get_custom_action,
@ -470,12 +477,6 @@ static const struct plugin_api rockbox_api = {
wheel_status, wheel_status,
wheel_send_events, wheel_send_events,
#endif #endif
#if LCD_DEPTH > 1
lcd_get_backdrop,
#endif
/* new stuff at the end, sort into place next time
the API gets incompatible */
#ifdef IRIVER_H100_SERIES #ifdef IRIVER_H100_SERIES
/* Routines for the iriver_flash -plugin. */ /* Routines for the iriver_flash -plugin. */
@ -483,7 +484,8 @@ static const struct plugin_api rockbox_api = {
detect_flashed_ramimage, detect_flashed_ramimage,
detect_flashed_romimage, detect_flashed_romimage,
#endif #endif
/* new stuff at the end, sort into place next time
the API gets incompatible */
#if NUM_CORES > 1 #if NUM_CORES > 1
spinlock_init, spinlock_init,
spinlock_lock, spinlock_lock,
@ -492,14 +494,8 @@ static const struct plugin_api rockbox_api = {
#if (CONFIG_CODEC == SWCODEC) #if (CONFIG_CODEC == SWCODEC)
codec_load_file, codec_load_file,
get_metadata,
get_codec_filename, get_codec_filename,
#endif get_metadata,
threads,
create_numbered_filename,
set_bool_options,
#ifdef HAVE_LCD_COLOR
set_color,
#endif #endif
}; };

View file

@ -115,12 +115,12 @@
#define PLUGIN_MAGIC 0x526F634B /* RocK */ #define PLUGIN_MAGIC 0x526F634B /* RocK */
/* increase this every time the api struct changes */ /* increase this every time the api struct changes */
#define PLUGIN_API_VERSION 59 #define PLUGIN_API_VERSION 60
/* update this to latest version if a change to the api struct breaks /* update this to latest version if a change to the api struct breaks
backwards compatibility (and please take the opportunity to sort in any backwards compatibility (and please take the opportunity to sort in any
new function which are "waiting" at the end of the function table) */ new function which are "waiting" at the end of the function table) */
#define PLUGIN_MIN_API_VERSION 58 #define PLUGIN_MIN_API_VERSION 60
/* plugin return codes */ /* plugin return codes */
enum plugin_status { enum plugin_status {
@ -179,6 +179,7 @@ struct plugin_api {
int stride, int x, int y, int width, int height); int stride, int x, int y, int width, int height);
void (*lcd_bitmap)(const fb_data *src, int x, int y, int width, void (*lcd_bitmap)(const fb_data *src, int x, int y, int width,
int height); int height);
fb_data* (*lcd_get_backdrop)(void);
void (*lcd_set_backdrop)(fb_data* backdrop); void (*lcd_set_backdrop)(fb_data* backdrop);
#endif #endif
#if LCD_DEPTH == 16 #if LCD_DEPTH == 16
@ -310,6 +311,9 @@ struct plugin_api {
#endif #endif
void (*ata_spindown)(int seconds); void (*ata_spindown)(int seconds);
void (*reload_directory)(void); void (*reload_directory)(void);
char *(*create_numbered_filename)(char *buffer, const char *path,
const char *prefix, const char *suffix,
int numberlen IF_CNFN_NUM_(, int *num));
/* dir */ /* dir */
DIR* (*PREFIX(opendir))(const char* name); DIR* (*PREFIX(opendir))(const char* name);
@ -333,6 +337,7 @@ struct plugin_api {
long* current_tick; long* current_tick;
long (*default_event_handler)(long event); long (*default_event_handler)(long event);
long (*default_event_handler_ex)(long event, void (*callback)(void *), void *parameter); long (*default_event_handler_ex)(long event, void (*callback)(void *), void *parameter);
struct thread_entry* threads;
struct thread_entry* (*create_thread)(void (*function)(void), void* stack, struct thread_entry* (*create_thread)(void (*function)(void), void* stack,
int stack_size, const char *name int stack_size, const char *name
IF_PRIO(, int priority) IF_PRIO(, int priority)
@ -507,11 +512,19 @@ struct plugin_api {
bool (*set_option)(const char* string, void* variable, bool (*set_option)(const char* string, void* variable,
enum optiontype type, const struct opt_items* options, enum optiontype type, const struct opt_items* options,
int numoptions, void (*function)(int)); int numoptions, void (*function)(int));
bool (*set_bool_options)(const char* string, bool* variable,
const char* yes_str, int yes_voice,
const char* no_str, int no_voice,
void (*function)(bool));
bool (*set_int)(const unsigned char* string, const char* unit, int voice_unit, bool (*set_int)(const unsigned char* string, const char* unit, int voice_unit,
int* variable, void (*function)(int), int step, int min, int* variable, void (*function)(int), int step, int min,
int max, void (*formatter)(char*, int, int, const char*) ); int max, void (*formatter)(char*, int, int, const char*) );
bool (*set_bool)(const char* string, bool* variable ); bool (*set_bool)(const char* string, bool* variable );
#ifdef HAVE_LCD_COLOR
bool (*set_color)(struct screen *display, char *title, unsigned *color,
unsigned banned_color);
#endif
/* action handling */ /* action handling */
int (*get_custom_action)(int context,int timeout, int (*get_custom_action)(int context,int timeout,
const struct button_mapping* (*get_context_map)(int)); const struct button_mapping* (*get_context_map)(int));
@ -587,11 +600,6 @@ struct plugin_api {
int (*wheel_status)(void); int (*wheel_status)(void);
void (*wheel_send_events)(bool send); void (*wheel_send_events)(bool send);
#endif #endif
#if LCD_DEPTH > 1
fb_data* (*lcd_get_backdrop)(void);
#endif
/* new stuff at the end, sort into place next time
the API gets incompatible */
#ifdef IRIVER_H100_SERIES #ifdef IRIVER_H100_SERIES
/* Routines for the iriver_flash -plugin. */ /* Routines for the iriver_flash -plugin. */
@ -599,6 +607,8 @@ struct plugin_api {
bool (*detect_flashed_ramimage)(void); bool (*detect_flashed_ramimage)(void);
bool (*detect_flashed_romimage)(void); bool (*detect_flashed_romimage)(void);
#endif #endif
/* new stuff at the end, sort into place next time
the API gets incompatible */
#if NUM_CORES > 1 #if NUM_CORES > 1
void (*spinlock_init)(struct mutex *m); void (*spinlock_init)(struct mutex *m);
@ -608,23 +618,9 @@ struct plugin_api {
#if (CONFIG_CODEC == SWCODEC) #if (CONFIG_CODEC == SWCODEC)
int (*codec_load_file)(const char* codec, struct codec_api *api); int (*codec_load_file)(const char* codec, struct codec_api *api);
const char *(*get_codec_filename)(int cod_spec);
bool (*get_metadata)(struct track_info* track, int fd, const char* trackname, bool (*get_metadata)(struct track_info* track, int fd, const char* trackname,
bool v1first); bool v1first);
const char *(*get_codec_filename)(int cod_spec);
#endif
struct thread_entry* threads;
char *(*create_numbered_filename)(char *buffer, const char *path,
const char *prefix, const char *suffix,
int numberlen IF_CNFN_NUM_(, int *num));
bool (*set_bool_options)(const char* string, bool* variable,
const char* yes_str, int yes_voice,
const char* no_str, int no_voice,
void (*function)(bool));
#ifdef HAVE_LCD_COLOR
bool (*set_color)(struct screen *display, char *title, unsigned *color,
unsigned banned_color);
#endif #endif
}; };

View file

@ -70,11 +70,20 @@
#include "radio.h" #include "radio.h"
#ifdef HAVE_RECORDING #ifdef HAVE_RECORDING
static bool in_screen = false; /* recording screen status flags */
enum rec_status_flags
{
RCSTAT_IN_RECSCREEN = 0x00000001,
RCSTAT_BEEN_IN_USB_MODE = 0x00000002,
RCSTAT_CREATED_DIRECTORY = 0x00000004,
RCSTAT_HAVE_RECORDED = 0x00000008,
};
static int rec_status = 0;
bool in_recording_screen(void) bool in_recording_screen(void)
{ {
return in_screen; return (rec_status & RCSTAT_IN_RECSCREEN) != 0;
} }
#define PM_HEIGHT ((LCD_HEIGHT >= 72) ? 2 : 1) #define PM_HEIGHT ((LCD_HEIGHT >= 72) ? 2 : 1)
@ -92,13 +101,13 @@ static bool remote_display_on = true;
#endif #endif
/** File name creation **/ /** File name creation **/
#if CONFIG_CODEC == SWCODEC #if CONFIG_RTC == 0
#ifdef IF_CNFN_NUM
/* current file number to assist in creating unique numbered filenames /* current file number to assist in creating unique numbered filenames
without actually having to create the file on disk */ without actually having to create the file on disk */
static int file_number = -1; static int file_number = -1;
#endif /* IF_CNFN_NUM */ #endif /* CONFIG_RTC */
#if CONFIG_CODEC == SWCODEC
#define REC_FILE_ENDING(rec_format) \ #define REC_FILE_ENDING(rec_format) \
(audio_formats[rec_format_afmt[rec_format]].ext_list) (audio_formats[rec_format_afmt[rec_format]].ext_list)
@ -511,16 +520,26 @@ char *rec_create_filename(char *buffer)
snprintf(ext, sizeof(ext), ".%s", snprintf(ext, sizeof(ext), ".%s",
REC_FILE_ENDING(global_settings.rec_format)); REC_FILE_ENDING(global_settings.rec_format));
#if CONFIG_RTC #if CONFIG_RTC == 0
return create_numbered_filename(buffer, buffer, "rec_", ext, 4,
&file_number);
#else
/* We'll wait at least up to the start of the next second so no duplicate /* We'll wait at least up to the start of the next second so no duplicate
names are created */ names are created */
return create_datetime_filename(buffer, buffer, "R", ext, true); return create_datetime_filename(buffer, buffer, "R", ext, true);
#else
return create_numbered_filename(buffer, buffer, "rec_", ext, 4
IF_CNFN_NUM_(, &file_number));
#endif #endif
} }
#if CONFIG_RTC == 0
/* Hit disk to get a starting filename for the type */
void rec_init_filename(void)
{
file_number = -1;
rec_create_filename(path_buffer);
file_number--;
}
#endif
int rec_create_directory(void) int rec_create_directory(void)
{ {
int rc; int rc;
@ -594,7 +613,6 @@ void rec_record(void)
#if CONFIG_CODEC != SWCODEC #if CONFIG_CODEC != SWCODEC
talk_buffer_steal(); /* we use the mp3 buffer */ talk_buffer_steal(); /* we use the mp3 buffer */
#endif #endif
IF_CNFN_NUM_(file_number = -1;) /* Hit disk for number */
audio_record(rec_create_filename(path_buffer)); audio_record(rec_create_filename(path_buffer));
} }
@ -617,12 +635,15 @@ static void trigger_listener(int trigger_status)
switch (trigger_status) switch (trigger_status)
{ {
case TRIG_GO: case TRIG_GO:
if((audio_status() & AUDIO_STATUS_RECORD) != AUDIO_STATUS_RECORD) if(!(audio_status() & AUDIO_STATUS_RECORD))
{ {
rec_status |= RCSTAT_HAVE_RECORDED;
rec_record(); rec_record();
#if CONFIG_CODEC != SWCODEC
/* give control to mpeg thread so that it can start /* give control to mpeg thread so that it can start
recording */ recording */
yield(); yield(); yield(); yield(); yield(); yield();
#endif
} }
/* if we're already recording this is a retrigger */ /* if we're already recording this is a retrigger */
@ -648,11 +669,7 @@ static void trigger_listener(int trigger_status)
switch(global_settings.rec_trigger_type) switch(global_settings.rec_trigger_type)
{ {
case 0: /* Stop */ case 0: /* Stop */
#if CONFIG_CODEC == SWCODEC
audio_stop_recording(); audio_stop_recording();
#else
audio_stop();
#endif
break; break;
case 1: /* Pause */ case 1: /* Pause */
@ -686,11 +703,9 @@ bool recording_screen(bool no_source)
char buf2[32]; char buf2[32];
int w, h; int w, h;
int update_countdown = 1; int update_countdown = 1;
bool have_recorded = false;
unsigned int seconds; unsigned int seconds;
int hours, minutes; int hours, minutes;
char filename[13]; char filename[13];
bool been_in_usb_mode = false;
int last_audio_stat = -1; int last_audio_stat = -1;
int audio_stat; int audio_stat;
#if CONFIG_CODEC == SWCODEC #if CONFIG_CODEC == SWCODEC
@ -733,7 +748,7 @@ bool recording_screen(bool no_source)
struct audio_recording_options rec_options; struct audio_recording_options rec_options;
in_screen = true; rec_status = RCSTAT_IN_RECSCREEN;
cursor = 0; cursor = 0;
#if (CONFIG_LED == LED_REAL) && !defined(SIMULATOR) #if (CONFIG_LED == LED_REAL) && !defined(SIMULATOR)
ata_set_led_enabled(false); ata_set_led_enabled(false);
@ -761,6 +776,15 @@ bool recording_screen(bool no_source)
rec_set_recording_options(&rec_options); rec_set_recording_options(&rec_options);
set_gain(); set_gain();
if(rec_create_directory() > 0)
rec_status |= RCSTAT_CREATED_DIRECTORY;
#if CONFIG_RTC == 0
/* Create new filename for recording start */
rec_init_filename();
#endif
settings_apply_trigger(); settings_apply_trigger();
#ifdef HAVE_AGC #ifdef HAVE_AGC
@ -789,8 +813,6 @@ bool recording_screen(bool no_source)
pm_y[i] = 8 + h * (2 + filename_offset[i]); pm_y[i] = 8 + h * (2 + filename_offset[i]);
} }
if(rec_create_directory() > 0)
have_recorded = true;
#ifdef HAVE_REMOTE_LCD #ifdef HAVE_REMOTE_LCD
if (!remote_display_on) if (!remote_display_on)
{ {
@ -859,9 +881,9 @@ bool recording_screen(bool no_source)
if (last_audio_stat != audio_stat) if (last_audio_stat != audio_stat)
{ {
if (audio_stat == AUDIO_STATUS_RECORD) if (audio_stat & AUDIO_STATUS_RECORD)
{ {
have_recorded = true; rec_status |= RCSTAT_HAVE_RECORDED;
} }
last_audio_stat = audio_stat; last_audio_stat = audio_stat;
} }
@ -926,7 +948,7 @@ bool recording_screen(bool no_source)
(peak_meter_trigger_status() != TRIG_OFF)) (peak_meter_trigger_status() != TRIG_OFF))
{ {
/* manual recording */ /* manual recording */
have_recorded = true; rec_status |= RCSTAT_HAVE_RECORDED;
rec_record(); rec_record();
last_seconds = 0; last_seconds = 0;
if (global_settings.talk_menu) if (global_settings.talk_menu)
@ -1119,7 +1141,11 @@ bool recording_screen(bool no_source)
break; break;
case ACTION_STD_MENU: case ACTION_STD_MENU:
#if CONFIG_CODEC == SWCODEC
if(!(audio_stat & AUDIO_STATUS_RECORD))
#else
if(audio_stat != AUDIO_STATUS_RECORD) if(audio_stat != AUDIO_STATUS_RECORD)
#endif
{ {
#ifdef HAVE_FMRADIO_REC #ifdef HAVE_FMRADIO_REC
const int prev_rec_source = global_settings.rec_source; const int prev_rec_source = global_settings.rec_source;
@ -1132,7 +1158,7 @@ bool recording_screen(bool no_source)
if (recording_menu(no_source)) if (recording_menu(no_source))
{ {
done = true; done = true;
been_in_usb_mode = true; rec_status |= RCSTAT_BEEN_IN_USB_MODE;
#ifdef HAVE_FMRADIO_REC #ifdef HAVE_FMRADIO_REC
radio_status = FMRADIO_OFF; radio_status = FMRADIO_OFF;
#endif #endif
@ -1152,11 +1178,18 @@ bool recording_screen(bool no_source)
audio_close_recording(); audio_close_recording();
audio_init_recording(0); audio_init_recording(0);
#endif #endif
rec_init_recording_options(&rec_options); rec_init_recording_options(&rec_options);
rec_set_recording_options(&rec_options); rec_set_recording_options(&rec_options);
if(rec_create_directory() > 0) if(rec_create_directory() > 0)
have_recorded = true; rec_status |= RCSTAT_CREATED_DIRECTORY;
#if CONFIG_CODEC == SWCODEC && CONFIG_RTC == 0
/* If format changed, a new number is required */
rec_init_filename();
#endif
#ifdef HAVE_AGC #ifdef HAVE_AGC
if (global_settings.rec_source == AUDIO_SRC_MIC) { if (global_settings.rec_source == AUDIO_SRC_MIC) {
agc_preset = global_settings.rec_agc_preset_mic; agc_preset = global_settings.rec_agc_preset_mic;
@ -1192,7 +1225,7 @@ bool recording_screen(bool no_source)
#endif #endif
if (f2_rec_screen()) if (f2_rec_screen())
{ {
have_recorded = true; rec_status |= RCSTAT_HAVE_RECORDED;
done = true; done = true;
} }
else else
@ -1208,31 +1241,28 @@ bool recording_screen(bool no_source)
} }
else else
{ {
if(audio_stat != AUDIO_STATUS_RECORD)
{
#if (CONFIG_LED == LED_REAL) #if (CONFIG_LED == LED_REAL)
/* led is restored at begin of loop / end of function */ /* led is restored at begin of loop / end of function */
led(false); led(false);
#endif #endif
if (f3_rec_screen()) if (f3_rec_screen())
{ {
have_recorded = true; rec_status |= RCSTAT_HAVE_RECORDED;
done = true; done = true;
} }
else else
update_countdown = 1; /* Update immediately */ update_countdown = 1; /* Update immediately */
} }
}
break; break;
#endif /* CONFIG_KEYPAD == RECORDER_PAD */ #endif /* CONFIG_KEYPAD == RECORDER_PAD */
case SYS_USB_CONNECTED: case SYS_USB_CONNECTED:
/* Only accept USB connection when not recording */ /* Only accept USB connection when not recording */
if(audio_stat != AUDIO_STATUS_RECORD) if(!(audio_stat & AUDIO_STATUS_RECORD))
{ {
default_event_handler(SYS_USB_CONNECTED); default_event_handler(SYS_USB_CONNECTED);
done = true; done = true;
been_in_usb_mode = true; rec_status |= RCSTAT_BEEN_IN_USB_MODE;
#ifdef HAVE_FMRADIO_REC #ifdef HAVE_FMRADIO_REC
radio_status = FMRADIO_OFF; radio_status = FMRADIO_OFF;
#endif #endif
@ -1467,12 +1497,11 @@ bool recording_screen(bool no_source)
{ {
switch (global_settings.rec_source) switch (global_settings.rec_source)
{ {
#if defined(HAVE_LINE_REC) || defined(HAVE_FMRADIO_REC)
HAVE_LINE_REC_(case AUDIO_SRC_LINEIN:) HAVE_LINE_REC_(case AUDIO_SRC_LINEIN:)
HAVE_FMRADIO_REC_(case AUDIO_SRC_FMRADIO:) HAVE_FMRADIO_REC_(case AUDIO_SRC_FMRADIO:)
line[i] = 5; line[i] = 5;
break; break;
#endif
case AUDIO_SRC_MIC: case AUDIO_SRC_MIC:
line[i] = 4; line[i] = 4;
break; break;
@ -1704,13 +1733,15 @@ bool recording_screen(bool no_source)
peak_meter_trigger(false); peak_meter_trigger(false);
peak_meter_set_trigger_listener(NULL); peak_meter_set_trigger_listener(NULL);
in_screen = false; rec_status &= ~RCSTAT_IN_RECSCREEN;
sound_settings_apply(); sound_settings_apply();
FOR_NB_SCREENS(i) FOR_NB_SCREENS(i)
screens[i].setfont(FONT_UI); screens[i].setfont(FONT_UI);
if (have_recorded) /* if the directory was created or recording happened, make sure the
browser is updated */
if (rec_status & (RCSTAT_CREATED_DIRECTORY | RCSTAT_HAVE_RECORDED))
reload_directory(); reload_directory();
#if (CONFIG_LED == LED_REAL) && !defined(SIMULATOR) #if (CONFIG_LED == LED_REAL) && !defined(SIMULATOR)
@ -1719,7 +1750,7 @@ bool recording_screen(bool no_source)
settings_save(); settings_save();
return been_in_usb_mode; return (rec_status & RCSTAT_BEEN_IN_USB_MODE) != 0;
} /* recording_screen */ } /* recording_screen */
#if CONFIG_KEYPAD == RECORDER_PAD #if CONFIG_KEYPAD == RECORDER_PAD