diff --git a/apps/misc.c b/apps/misc.c index 2f3251431b..4ea8568018 100644 --- a/apps/misc.c +++ b/apps/misc.c @@ -578,6 +578,9 @@ static bool clean_shutdown(void (*callback)(void *), void *parameter) if(!charger_inserted()) #endif { + bool batt_crit = battery_level_critical(); + int audio_stat = audio_status(); + FOR_NB_SCREENS(i) screens[i].clear_display(); #ifdef X5_BACKLIGHT_SHUTDOWN @@ -604,11 +607,23 @@ static bool clean_shutdown(void (*callback)(void *), void *parameter) } if (global_settings.fade_on_stop - && (audio_status() & AUDIO_STATUS_PLAY)) + && (audio_stat & AUDIO_STATUS_PLAY)) { fade(0); } - + +#if defined(HAVE_RECORDING) && CONFIG_CODEC == SWCODEC + if (!batt_crit && (audio_stat & AUDIO_STATUS_RECORD)) + { + audio_stop_recording(); + while(audio_status() & AUDIO_STATUS_RECORD) + sleep(1); + } + + audio_close_recording(); +#endif + /* audio_stop_recording == audio_stop for HWCODEC */ + audio_stop(); while (audio_status()) sleep(1); @@ -616,7 +631,7 @@ static bool clean_shutdown(void (*callback)(void *), void *parameter) if (callback != NULL) callback(parameter); - if (!battery_level_critical()) /* do not save on critical battery */ + if (!batt_crit) /* do not save on critical battery */ system_flush(); #ifdef HAVE_EEPROM_SETTINGS if (firmware_settings.initialized) diff --git a/firmware/pcm_record.c b/firmware/pcm_record.c index a72641baa6..93a6e067b1 100644 --- a/firmware/pcm_record.c +++ b/firmware/pcm_record.c @@ -244,6 +244,14 @@ static int pcm_rec_have_more(int status) return 0; } /* pcm_rec_have_more */ +static void reset_hardware(void) +{ + /* reset pcm to defaults (playback only) */ + pcm_set_frequency(HW_SAMPR_DEFAULT); + audio_set_output_source(AUDIO_SRC_PLAYBACK); + pcm_apply_settings(true); +} + /** pcm_rec_* group **/ void pcm_rec_error_clear(void) { @@ -328,10 +336,7 @@ void audio_close_recording(void) { pcm_thread_wait_for_stop(); pcm_thread_sync_post(PCMREC_CLOSE, NULL); - /* reset pcm to defaults (playback only) */ - pcm_set_frequency(HW_SAMPR_DEFAULT); - audio_set_output_source(AUDIO_SRC_PLAYBACK); - pcm_apply_settings(true); + reset_hardware(); audio_remove_encoder(); } /* audio_close_recording */ @@ -460,10 +465,6 @@ void audio_stop_recording(void) logf("audio_stop_recording"); pcm_thread_wait_for_stop(); - - if (is_recording) - dma_lock = true; /* fix DMA write ptr at current position */ - pcm_thread_sync_post(PCMREC_STOP, NULL); logf("audio_stop_recording done"); @@ -474,11 +475,8 @@ void audio_pause_recording(void) logf("audio_pause_recording"); pcm_thread_wait_for_stop(); - - if (is_recording) - dma_lock = true; /* fix DMA write ptr at current position */ - pcm_thread_sync_post(PCMREC_PAUSE, NULL); + logf("audio_pause_recording done"); } /* audio_pause_recording */ @@ -1006,6 +1004,8 @@ static void pcmrec_new_stream(const char *filename, /* next file name */ /* PCMREC_INIT */ static void pcmrec_init(void) { + unsigned char *buffer; + rec_fdata.rec_file = -1; /* pcm FIFO */ @@ -1035,11 +1035,13 @@ static void pcmrec_init(void) is_stopping = false; is_error = false; - pcm_buffer = audio_get_recording_buffer(&rec_buffer_size); + buffer = audio_get_recording_buffer(&rec_buffer_size); /* Line align pcm_buffer 2^4=16 bytes */ - pcm_buffer = (unsigned char *)ALIGN_UP_P2((unsigned)pcm_buffer, 4); + pcm_buffer = (unsigned char *)ALIGN_UP_P2((unsigned long)buffer, 4); enc_buffer = pcm_buffer + ALIGN_UP_P2(PCM_NUM_CHUNKS*PCM_CHUNK_SIZE + PCM_MAX_FEED_SIZE, 2); + /* Adjust available buffer for possible align advancement */ + rec_buffer_size -= pcm_buffer - buffer; pcm_init_recording(); pcm_thread_signal_event(PCMREC_INIT); @@ -1132,8 +1134,8 @@ static void pcmrec_start(const char *filename) pcmrec_fnq_set_empty(); } - dma_lock = false; - is_paused = false; + dma_lock = false; + is_paused = false; is_recording = true; pcmrec_new_stream(filename, @@ -1187,11 +1189,8 @@ static void pcmrec_finish_stop(void) pcmrec_flush(-1); /* wait for encoder to finish remaining data */ - if (!is_error) - { - while (!wav_queue_empty) - yield(); - } + while (!is_error && !wav_queue_empty) + yield(); /* end stream at last data */ pcmrec_new_stream(NULL, CHUNKF_END_FILE, 0); @@ -1307,7 +1306,7 @@ static void pcmrec_thread(void) while(1) { - if (is_recording) + if (is_recording && !is_stopping) { /* Poll periodically to flush data */ queue_wait_w_tmo(&pcmrec_queue, &ev, HZ/5); @@ -1363,12 +1362,12 @@ static void pcmrec_thread(void) break; case SYS_USB_CONNECTED: - if (!is_recording) - { - pcmrec_close(); - usb_acknowledge(SYS_USB_CONNECTED_ACK); - usb_wait_for_disconnect(&pcmrec_queue); - } + if (is_recording) + break; + pcmrec_close(); + reset_hardware(); + usb_acknowledge(SYS_USB_CONNECTED_ACK); + usb_wait_for_disconnect(&pcmrec_queue); break; } /* end switch */ } /* end while */ @@ -1554,7 +1553,8 @@ void enc_finish_chunk(void) int enc_pcm_buf_near_empty(void) { /* less than 1sec raw data? => unboost encoder */ - size_t avail = (dma_wr_pos - pcm_rd_pos) & PCM_CHUNK_MASK; + int wp = dma_wr_pos; + size_t avail = (wp - pcm_rd_pos) & PCM_CHUNK_MASK; return avail < (sample_rate << 2) ? 1 : 0; } /* enc_pcm_buf_near_empty */ @@ -1562,7 +1562,8 @@ int enc_pcm_buf_near_empty(void) /* TODO: this really should give the actual size returned */ unsigned char * enc_get_pcm_data(size_t size) { - size_t avail = (dma_wr_pos - pcm_rd_pos) & PCM_CHUNK_MASK; + int wp = dma_wr_pos; + size_t avail = (wp - pcm_rd_pos) & PCM_CHUNK_MASK; /* limit the requested pcm data size */ if (size > PCM_MAX_FEED_SIZE) diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c index e59e2d50b9..458745f0d9 100644 --- a/firmware/powermgmt.c +++ b/firmware/powermgmt.c @@ -1266,16 +1266,17 @@ void sys_poweroff(void) { logf("sys_poweroff()"); /* If the main thread fails to shut down the system, we will force a - power off after an 20 second timeout */ - shutdown_timeout = HZ*20; -#if defined(HAVE_RECORDING) - int audio_stat = audio_status(); - if (audio_stat & AUDIO_STATUS_RECORD) { - audio_stop_recording(); - shutdown_timeout += 8*HZ; - } + power off after an 20 second timeout - 28 seconds if recording */ +#if defined(IAUDIO_X5) && !defined (SIMULATOR) + if (shutdown_timeout == 0) + pcf50606_reset_timeout(); /* Reset timer on first attempt only */ #endif - +#ifdef HAVE_RECORDING + if (audio_status() & AUDIO_STATUS_RECORD) + shutdown_timeout += HZ*8; +#endif + + shutdown_timeout = HZ*20; queue_post(&button_queue, SYS_POWEROFF, NULL); }