diff --git a/apps/plugins/fft/fft.c b/apps/plugins/fft/fft.c
index e62c919..8d21ad4 100644
--- a/apps/plugins/fft/fft.c
+++ b/apps/plugins/fft/fft.c
@@ -18,6 +18,18 @@
* KIND, either express or implied.
*
****************************************************************************/
+
+/****************************************************************************
+ * OVERVIEW OF THE PLUGIN
+ *
+ * There are two input modes available:
+ * 1) Playback mode - analyzes the currently playing track
+ * 2) Recording mode (if supported by hardware) - analyzes input from
+ * user-selected source (mic, linein, spdif, taken from Recording Settings)
+ *
+ * Recording mode is triggered if playback is stopped.
+ *
+ ****************************************************************************/
#include "plugin.h"
#include "lib/helper.h"
@@ -228,6 +240,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,15 +1092,65 @@ 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->pcm_stop_recording();
+
+ 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. Input mode.");
+ recording_mode = true;
+ recording_init();
+#else
rb->splash(HZ * 2, "No track playing. Exiting..");
return PLUGIN_OK;
+#endif
}
+
+ rb->lcd_clear_display();
+
#ifndef HAVE_LCD_COLOR
unsigned char *gbuf;
size_t gbuf_size = 0;
@@ -1127,25 +1197,51 @@ 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
+ {
+ 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_data from main loop");
+ rb->pcm_record_data(recording_entry, (void *) input, (size_t) ARRAYSIZE_IN * sizeof(kiss_fft_scalar));
+ }
+
if(changed_window)
{
draw(window_text[graph_settings.window_func]);
@@ -1155,6 +1251,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 +1300,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);