diff --git a/apps/plugins/fft/fft.c b/apps/plugins/fft/fft.c index e62c919..9f84c2c 100644 --- a/apps/plugins/fft/fft.c +++ b/apps/plugins/fft/fft.c @@ -228,6 +228,14 @@ GREY_INFO_STRUCT #include "_kiss_fft_guts.h" /* sizeof(struct kiss_fft_state) */ #include "const.h" +#if (REC_SAMPR_CAPS & SAMPR_CAP_44) +#define SAMPLE_RATE SAMPR_44 +#elif (REC_SAMPR_CAPS & SAMPR_CAP_22) +#define SAMPLE_RATE SAMPR_22 +#elif (REC_SAMPR_CAPS & SAMPR_CAP_11) +#define SAMPLE_RATE SAMPR_11 +#endif + #if (LCD_WIDTH < LCD_HEIGHT) #define LCD_SIZE LCD_HEIGHT #else @@ -1072,14 +1080,59 @@ void input_thread_entry(void) } } +#ifdef HAVE_RECORDING +static int recording_entry(int status) +{ + if (status >= 0) + input_thread_has_data = true; + else + input_thread_has_data = false; + + rb->logf("FFT: More data available, status: %d", status); + return -1; +} + +void recording_init(void) +{ + rb->audio_set_output_source(AUDIO_SRC_PLAYBACK); + rb->audio_set_input_source(rb->global_settings->rec_source, SRCF_RECORDING); + + /* set to maximum gain */ + if (rb->global_settings->rec_source == AUDIO_SRC_MIC) + rb->audio_set_recording_gain(rb->global_settings->rec_mic_gain, + rb->global_settings->rec_mic_gain, + AUDIO_GAIN_MIC); + else + rb->audio_set_recording_gain(rb->global_settings->rec_left_gain, + rb->global_settings->rec_right_gain, + AUDIO_GAIN_LINEIN); + + rb->pcm_set_frequency(SAMPLE_RATE); + rb->pcm_apply_settings(); + + rb->pcm_init_recording(); + rb->logf("FFT: Recording initialized"); +} +#endif + enum plugin_status plugin_start(const void* parameter) { (void) parameter; + +#ifdef HAVE_RECORDING + bool recording_mode = false; +#endif if ((rb->audio_status() & AUDIO_STATUS_PLAY) == 0) { +#ifdef HAVE_RECORDING + rb->splash(HZ * 2, "No track playing. Recording mode."); + recording_mode = true; + recording_init(); +#else rb->splash(HZ * 2, "No track playing. Exiting.."); return PLUGIN_OK; +#endif } #ifndef HAVE_LCD_COLOR unsigned char *gbuf; @@ -1127,25 +1180,53 @@ enum plugin_status plugin_start(const void* parameter) if (state == 0) { - DEBUGF("needed data: %i", (int) size); + DEBUGF("needed data: %l", (int) size); return PLUGIN_ERROR; } + unsigned int input_thread = 0; +#ifdef HAVE_RECORDING + if (recording_mode) + rb->pcm_record_data(recording_entry, (void *) input, + (size_t) ARRAYSIZE_IN * sizeof(kiss_fft_scalar)); + else +#endif + input_thread = rb->create_thread(&input_thread_entry, thread_stack, sizeof(thread_stack), 0, "fft input thread" IF_PRIO(, PRIORITY_BACKGROUND) IF_COP(, CPU)); - unsigned int input_thread = rb->create_thread(&input_thread_entry, thread_stack, sizeof(thread_stack), 0, "fft input thread" IF_PRIO(, PRIORITY_BACKGROUND) IF_COP(, CPU)); rb->yield(); while (run) { + if(!recording_mode) rb->mutex_lock(&input_mutex); if(!input_thread_has_data) { /* Make sure the input thread has started before doing anything else */ + if(!recording_mode) rb->mutex_unlock(&input_mutex); + else + { + rb->lcd_clear_display(); + rb->splash(HZ*2, "Waiting for recorded data"); + if(rb->button_get(false) == FFT_QUIT) + { + rb->logf("Aborting wait-for-data cycle"); + run = false; + break; + } + } + rb->yield(); continue; } apply_window_func(graph_settings.window_func); FFT_FFT(state, input, output); + /* We're done with the input */ + if(recording_mode) + { + rb->logf("FFT: call pcm_record_more"); + rb->pcm_record_more((void *) input, (size_t) ARRAYSIZE_IN * sizeof(kiss_fft_scalar)); + } + if(changed_window) { draw(window_text[graph_settings.window_func]); @@ -1155,6 +1236,7 @@ enum plugin_status plugin_start(const void* parameter) draw(0); input_thread_has_data = false; + if(!recording_mode) rb->mutex_unlock(&input_mutex); rb->yield(); @@ -1203,11 +1285,21 @@ enum plugin_status plugin_start(const void* parameter) } } +#ifdef HAVE_RECORDING + if (recording_mode) + { + rb->pcm_stop_recording(); + rb->pcm_close_recording(); + } + else +#endif + { /* Handle our input thread. We haven't yield()'d since our last mutex_unlock, so we know we have the mutex */ rb->mutex_lock(&input_mutex); input_thread_run = false; rb->mutex_unlock(&input_mutex); rb->thread_wait(input_thread); + } #ifdef HAVE_ADJUSTABLE_CPU_FREQ rb->cpu_boost(false);