From 3d1a85695b64029d93de631d0c6fd81c3311d6e7 Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Fri, 14 May 2010 12:35:05 +0000 Subject: [PATCH] Give pitch_detector the IRAMming it deserves. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26018 a1c6a512-1295-4272-9138-f99709370657 --- apps/plugins/pitch_detector.c | 42 +++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/apps/plugins/pitch_detector.c b/apps/plugins/pitch_detector.c index 01dfef25ca..09536a7b18 100644 --- a/apps/plugins/pitch_detector.c +++ b/apps/plugins/pitch_detector.c @@ -69,6 +69,7 @@ #include "pluginbitmaps/pitch_notes.h" PLUGIN_HEADER +PLUGIN_IRAM_DECLARE /* Some fixed point calculation stuff */ typedef int32_t fixed_data; @@ -149,7 +150,7 @@ typedef struct _fixed fixed; #define LCD_FACTOR (fp_div(int2fixed(LCD_WIDTH), int2fixed(100))) /* The threshold for the YIN algorithm */ #define DEFAULT_YIN_THRESHOLD 5 /* 0.10 */ -const fixed yin_threshold_table[] = +const fixed yin_threshold_table[] IDATA_ATTR = { float2fixed(0.01), float2fixed(0.02), @@ -252,7 +253,12 @@ static volatile int audio_tail = 0; /* which of the two buffers to record? */ /* It's stereo, so make the buffer twice as big */ #ifndef SIMULATOR static int16_t audio_data[2][BUFFER_SIZE] __attribute__((aligned(CACHEALIGN_SIZE))); -static fixed yin_buffer[YIN_BUFFER_SIZE]; +static fixed yin_buffer[YIN_BUFFER_SIZE] IBSS_ATTR; +#ifdef PLUGIN_USE_IRAM +static int16_t iram_audio_data[BUFFER_SIZE] IBSS_ATTR; +#else +#define iram_audio_data audio_data[audio_head] +#endif #endif /* Description of a note of scale */ @@ -815,7 +821,7 @@ unsigned vec_min_elem(fixed *s, unsigned buflen) } -fixed aubio_quadfrac(fixed s0, fixed s1, fixed s2, fixed pf) +static inline fixed aubio_quadfrac(fixed s0, fixed s1, fixed s2, fixed pf) { /* Original floating point version: */ /* tmp = s0 + (pf/2.0f) * (pf * ( s0 - 2.0f*s1 + s2 ) - @@ -869,7 +875,7 @@ fixed aubio_quadfrac(fixed s0, fixed s1, fixed s2, fixed pf) #define QUADINT_STEP float2fixed(1.0f/200.0f) -fixed vec_quadint_min(fixed *x, unsigned bufsize, unsigned pos, unsigned span) +fixed ICODE_ATTR vec_quadint_min(fixed *x, unsigned bufsize, unsigned pos, unsigned span) { fixed res, frac, s0, s1, s2; fixed exactpos = int2fixed(pos); @@ -916,7 +922,7 @@ fixed vec_quadint_min(fixed *x, unsigned bufsize, unsigned pos, unsigned span) /* The yin pointer is just a buffer that the algorithm uses as a work space. It needs to be half the length of the input buffer. */ -fixed pitchyin(int16_t *input, fixed *yin) +fixed ICODE_ATTR pitchyin(int16_t *input, fixed *yin) { fixed retval; unsigned j,tau = 0; @@ -956,19 +962,20 @@ fixed pitchyin(int16_t *input, fixed *yin) /*-----------------------------------------------------------------*/ -uint32_t buffer_magnitude(int16_t *input) +uint32_t ICODE_ATTR buffer_magnitude(int16_t *input) { unsigned n; uint64_t tally = 0; + const unsigned size = tuner_settings.sample_size; /* Operate on only one channel of the stereo signal */ - for(n = 0; n < tuner_settings.sample_size; n+=2) + for(n = 0; n < size; n+=2) { int s = input[n]; tally += s * s; } - tally /= tuner_settings.sample_size / 2; + tally /= size / 2; /* now tally holds the average of the squares of all the samples */ /* It must be between 0 and 0x7fff^2, so it fits in 32 bits */ @@ -1065,9 +1072,12 @@ void record_and_get_pitch(void) #ifdef HAVE_SCHEDULER_BOOSTCTRL rb->trigger_cpu_boost(); #endif - +#ifdef PLUGIN_USE_IRAM + rb->memcpy(iram_audio_data, audio_data[audio_head], + tuner_settings.sample_size * sizeof (int16_t)); +#endif /* This returns the period of the detected pitch in samples */ - period = pitchyin(audio_data[audio_head], yin_buffer); + period = pitchyin(iram_audio_data, yin_buffer); /* Hz = sample rate / period */ if(fp_gt(period, FP_ZERO)) { @@ -1099,6 +1109,7 @@ void record_and_get_pitch(void) } } rb->pcm_close_recording(); + rb->pcm_set_frequency(HW_SAMPR_DEFAULT); #ifdef HAVE_SCHEDULER_BOOSTCTRL rb->cancel_cpu_boost(); #endif @@ -1108,10 +1119,15 @@ void record_and_get_pitch(void) /* Init recording, tuning, and GUI */ void init_everything(void) -{ +{ + /* Disable all talking before initializing IRAM */ + rb->talk_disable(true); + + PLUGIN_IRAM_INIT(rb); + load_settings(); - /* Stop all playback */ + /* Stop all playback (if no IRAM, otherwise IRAM_INIT would have) */ rb->plugin_get_audio_buffer(NULL); /* --------- Init the audio recording ----------------- */ @@ -1149,6 +1165,8 @@ void init_everything(void) bar_grad_y = BAR_Y - BAR_PADDING - font_h; /* Put the note right between the top and bottom text elements */ note_y = ((font_h + bar_grad_y - note_bitmaps.slide_height) / 2); + + rb->talk_disable(false); }