diff --git a/apps/recorder/recording.c b/apps/recorder/recording.c index c2f2462a5c..b92c2506b5 100644 --- a/apps/recorder/recording.c +++ b/apps/recorder/recording.c @@ -231,13 +231,22 @@ bool recording_screen(void) mpeg_record(rec_create_filename(path_buffer)); status_set_playmode(STATUS_RECORD); update_countdown = 1; /* Update immediately */ + last_seconds = 0; } else { - mpeg_new_file(rec_create_filename(path_buffer)); + if(mpeg_status() & MPEG_STATUS_PAUSE) + { + mpeg_resume_recording(); + status_set_playmode(STATUS_RECORD); + } + else + { + mpeg_pause_recording(); + status_set_playmode(STATUS_PAUSE); + } update_countdown = 1; /* Update immediately */ } - last_seconds = 0; break; case BUTTON_UP: @@ -373,15 +382,23 @@ bool recording_screen(void) break; case BUTTON_F3: - if(mpeg_status() != MPEG_STATUS_RECORD) + if(mpeg_status() & MPEG_STATUS_RECORD) { - if (f3_rec_screen()) + mpeg_new_file(rec_create_filename(path_buffer)); + last_seconds = 0; + } + else + { + if(mpeg_status() != MPEG_STATUS_RECORD) { - have_recorded = true; - done = true; + if (f3_rec_screen()) + { + have_recorded = true; + done = true; + } + else + update_countdown = 1; /* Update immediately */ } - else - update_countdown = 1; /* Update immediately */ } break; @@ -436,8 +453,9 @@ bool recording_screen(void) is active */ if (global_settings.rec_timesplit) { - /* Display the record timesplit interval rather than - the file size if the record timer is active */ + /* Display the record timesplit interval rather + than the file size if the record timer is + active */ dhours = dseconds / 3600; dminutes = (dseconds - (dhours * 3600)) / 60; snprintf(buf, 32, "%s %02d:%02d", @@ -445,8 +463,10 @@ bool recording_screen(void) dhours, dminutes); } else - snprintf(buf, 32, "%s %s", str(LANG_RECORDING_SIZE), - num2max5(mpeg_num_recorded_bytes(), buf2)); + snprintf(buf, 32, "%s %s", + str(LANG_RECORDING_SIZE), + num2max5(mpeg_num_recorded_bytes(), + buf2)); } lcd_puts(0, 1, buf); diff --git a/firmware/export/mpeg.h b/firmware/export/mpeg.h index 5625b03464..252e509c94 100644 --- a/firmware/export/mpeg.h +++ b/firmware/export/mpeg.h @@ -85,6 +85,8 @@ void mpeg_set_recording_options(int frequency, int quality, void mpeg_set_recording_gain(int left, int right, bool use_mic); unsigned long mpeg_recorded_time(void); unsigned long mpeg_num_recorded_bytes(void); +void mpeg_pause_recording(void); +void mpeg_resume_recording(void); #endif void mpeg_get_debugdata(struct mpeg_debug *dbgdata); void mpeg_set_buffer_margin(int seconds); diff --git a/firmware/mpeg.c b/firmware/mpeg.c index 296ef1440d..4a959b7c82 100644 --- a/firmware/mpeg.c +++ b/firmware/mpeg.c @@ -48,6 +48,8 @@ static void start_prerecording(void); static void start_recording(void); static void stop_recording(void); static int get_unsaved_space(void); +static void pause_recording(void); +static void resume_recording(void); #endif /* #ifdef HAVE_MAS3587F */ #ifndef SIMULATOR @@ -68,6 +70,8 @@ static int get_unswapped_space(void); #define MPEG_INIT_RECORDING 10 #define MPEG_INIT_PLAYBACK 11 #define MPEG_NEW_FILE 12 +#define MPEG_PAUSE_RECORDING 13 +#define MPEG_RESUME_RECORDING 14 #define MPEG_NEED_DATA 100 #define MPEG_TRACK_CHANGE 101 #define MPEG_SAVE_DATA 102 @@ -287,6 +291,8 @@ static bool is_recording; /* We are recording */ static bool stop_pending; unsigned long record_start_time; /* Value of current_tick when recording was started */ +unsigned long pause_start_time; /* Value of current_tick when pause was + started */ static bool saving; /* We are saving the buffer to disk */ static char recording_filename[MAX_PATH]; /* argument to thread */ static char delayed_filename[MAX_PATH]; /* internal copy of above */ @@ -1653,6 +1659,12 @@ static void mpeg_thread(void) } start_recording(); + + /* Wait until at least one frame is encoded and get the + frame header, for later use by the Xing header + generation */ + sleep(HZ/10); + saved_header = get_last_recorded_header(); /* delayed until buffer is saved, don't open yet */ strcpy(delayed_filename, recording_filename); @@ -1663,10 +1675,6 @@ static void mpeg_thread(void) case MPEG_STOP: DEBUGF("MPEG_STOP\n"); - /* Store the last recorded header for later use by the - Xing header generation */ - saved_header = get_last_recorded_header(); - stop_recording(); /* Save the remaining data in the buffer */ @@ -1754,8 +1762,6 @@ static void mpeg_thread(void) if(startpos < 0) startpos += mp3buflen; - saved_header = get_last_recorded_header(); - rc = mem_find_next_frame(startpos, &offset, 1800, saved_header); if(rc) /* Header found? */ @@ -1864,6 +1870,7 @@ static void mpeg_thread(void) DEBUGF("r: %x w: %x\n", mp3buf_read, mp3buf_write); DEBUGF("ats: %x\n", amount_to_save); + /* Save data only if the buffer is getting full, or if we should stop recording */ if(amount_to_save) @@ -1938,7 +1945,15 @@ static void mpeg_thread(void) mp3_play_init(); init_playback_done = true; break; - + + case MPEG_PAUSE_RECORDING: + pause_recording(); + break; + + case MPEG_RESUME_RECORDING: + resume_recording(); + break; + case SYS_USB_CONNECTED: /* We can safely go to USB mode if no recording is taking place */ @@ -2136,6 +2151,16 @@ void mpeg_record(char *filename) queue_post(&mpeg_queue, MPEG_RECORD, NULL); } +void mpeg_pause_recording(void) +{ + queue_post(&mpeg_queue, MPEG_PAUSE_RECORDING, NULL); +} + +void mpeg_resume_recording(void) +{ + queue_post(&mpeg_queue, MPEG_RESUME_RECORDING, NULL); +} + static void start_prerecording(void) { unsigned long val; @@ -2199,13 +2224,16 @@ static void start_recording(void) is_recording = true; stop_pending = false; saving = false; + paused = false; /* Store the current time */ if(prerecording) record_start_time = current_tick - prerecord_count * HZ; else record_start_time = current_tick; - + + pause_start_time = 0; + demand_irq_enable(true); } @@ -2213,6 +2241,8 @@ static void pause_recording(void) { unsigned long val; + pause_start_time = current_tick; + /* Set the pause bit */ shadow_7f9 |= 2; mas_writemem(MAS_BANK_D0, 0x7f9, &shadow_7f9, 1); @@ -2226,12 +2256,16 @@ static void pause_recording(void) { mas_readmem(MAS_BANK_D0, 0x7f1, &val,1); } while(val & 1); + + paused = true; } static void resume_recording(void) { unsigned long val; + paused = false; + /* Clear the pause bit */ shadow_7f9 &= ~2; mas_writemem(MAS_BANK_D0, 0x7f9, &shadow_7f9, 1); @@ -2245,6 +2279,14 @@ static void resume_recording(void) { mas_readmem(MAS_BANK_D0, 0x7f1, &val,1); } while(val & 1); + + /* Compensate for the time we have been paused */ + if(pause_start_time) + { + record_start_time = + current_tick - (pause_start_time - record_start_time); + pause_start_time = 0; + } } static void stop_recording(void) @@ -2252,7 +2294,8 @@ static void stop_recording(void) unsigned long val; /* Let it finish the last frame */ - pause_recording(); + if(!paused) + pause_recording(); sleep(HZ/5); demand_irq_enable(false); @@ -2372,7 +2415,12 @@ unsigned long mpeg_recorded_time(void) return prerecord_count * HZ; if(is_recording) - return current_tick - record_start_time; + { + if(paused) + return pause_start_time - record_start_time; + else + return current_tick - record_start_time; + } return 0; }