diff options
-rw-r--r-- | apps/plugins/pitch_detector.c | 42 |
1 files 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 @@ | |||
69 | #include "pluginbitmaps/pitch_notes.h" | 69 | #include "pluginbitmaps/pitch_notes.h" |
70 | 70 | ||
71 | PLUGIN_HEADER | 71 | PLUGIN_HEADER |
72 | PLUGIN_IRAM_DECLARE | ||
72 | 73 | ||
73 | /* Some fixed point calculation stuff */ | 74 | /* Some fixed point calculation stuff */ |
74 | typedef int32_t fixed_data; | 75 | typedef int32_t fixed_data; |
@@ -149,7 +150,7 @@ typedef struct _fixed fixed; | |||
149 | #define LCD_FACTOR (fp_div(int2fixed(LCD_WIDTH), int2fixed(100))) | 150 | #define LCD_FACTOR (fp_div(int2fixed(LCD_WIDTH), int2fixed(100))) |
150 | /* The threshold for the YIN algorithm */ | 151 | /* The threshold for the YIN algorithm */ |
151 | #define DEFAULT_YIN_THRESHOLD 5 /* 0.10 */ | 152 | #define DEFAULT_YIN_THRESHOLD 5 /* 0.10 */ |
152 | const fixed yin_threshold_table[] = | 153 | const fixed yin_threshold_table[] IDATA_ATTR = |
153 | { | 154 | { |
154 | float2fixed(0.01), | 155 | float2fixed(0.01), |
155 | float2fixed(0.02), | 156 | float2fixed(0.02), |
@@ -252,7 +253,12 @@ static volatile int audio_tail = 0; /* which of the two buffers to record? */ | |||
252 | /* It's stereo, so make the buffer twice as big */ | 253 | /* It's stereo, so make the buffer twice as big */ |
253 | #ifndef SIMULATOR | 254 | #ifndef SIMULATOR |
254 | static int16_t audio_data[2][BUFFER_SIZE] __attribute__((aligned(CACHEALIGN_SIZE))); | 255 | static int16_t audio_data[2][BUFFER_SIZE] __attribute__((aligned(CACHEALIGN_SIZE))); |
255 | static fixed yin_buffer[YIN_BUFFER_SIZE]; | 256 | static fixed yin_buffer[YIN_BUFFER_SIZE] IBSS_ATTR; |
257 | #ifdef PLUGIN_USE_IRAM | ||
258 | static int16_t iram_audio_data[BUFFER_SIZE] IBSS_ATTR; | ||
259 | #else | ||
260 | #define iram_audio_data audio_data[audio_head] | ||
261 | #endif | ||
256 | #endif | 262 | #endif |
257 | 263 | ||
258 | /* Description of a note of scale */ | 264 | /* Description of a note of scale */ |
@@ -815,7 +821,7 @@ unsigned vec_min_elem(fixed *s, unsigned buflen) | |||
815 | } | 821 | } |
816 | 822 | ||
817 | 823 | ||
818 | fixed aubio_quadfrac(fixed s0, fixed s1, fixed s2, fixed pf) | 824 | static inline fixed aubio_quadfrac(fixed s0, fixed s1, fixed s2, fixed pf) |
819 | { | 825 | { |
820 | /* Original floating point version: */ | 826 | /* Original floating point version: */ |
821 | /* tmp = s0 + (pf/2.0f) * (pf * ( s0 - 2.0f*s1 + s2 ) - | 827 | /* 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) | |||
869 | 875 | ||
870 | #define QUADINT_STEP float2fixed(1.0f/200.0f) | 876 | #define QUADINT_STEP float2fixed(1.0f/200.0f) |
871 | 877 | ||
872 | fixed vec_quadint_min(fixed *x, unsigned bufsize, unsigned pos, unsigned span) | 878 | fixed ICODE_ATTR vec_quadint_min(fixed *x, unsigned bufsize, unsigned pos, unsigned span) |
873 | { | 879 | { |
874 | fixed res, frac, s0, s1, s2; | 880 | fixed res, frac, s0, s1, s2; |
875 | fixed exactpos = int2fixed(pos); | 881 | fixed exactpos = int2fixed(pos); |
@@ -916,7 +922,7 @@ fixed vec_quadint_min(fixed *x, unsigned bufsize, unsigned pos, unsigned span) | |||
916 | /* The yin pointer is just a buffer that the algorithm uses as a work | 922 | /* The yin pointer is just a buffer that the algorithm uses as a work |
917 | space. It needs to be half the length of the input buffer. */ | 923 | space. It needs to be half the length of the input buffer. */ |
918 | 924 | ||
919 | fixed pitchyin(int16_t *input, fixed *yin) | 925 | fixed ICODE_ATTR pitchyin(int16_t *input, fixed *yin) |
920 | { | 926 | { |
921 | fixed retval; | 927 | fixed retval; |
922 | unsigned j,tau = 0; | 928 | unsigned j,tau = 0; |
@@ -956,19 +962,20 @@ fixed pitchyin(int16_t *input, fixed *yin) | |||
956 | 962 | ||
957 | /*-----------------------------------------------------------------*/ | 963 | /*-----------------------------------------------------------------*/ |
958 | 964 | ||
959 | uint32_t buffer_magnitude(int16_t *input) | 965 | uint32_t ICODE_ATTR buffer_magnitude(int16_t *input) |
960 | { | 966 | { |
961 | unsigned n; | 967 | unsigned n; |
962 | uint64_t tally = 0; | 968 | uint64_t tally = 0; |
969 | const unsigned size = tuner_settings.sample_size; | ||
963 | 970 | ||
964 | /* Operate on only one channel of the stereo signal */ | 971 | /* Operate on only one channel of the stereo signal */ |
965 | for(n = 0; n < tuner_settings.sample_size; n+=2) | 972 | for(n = 0; n < size; n+=2) |
966 | { | 973 | { |
967 | int s = input[n]; | 974 | int s = input[n]; |
968 | tally += s * s; | 975 | tally += s * s; |
969 | } | 976 | } |
970 | 977 | ||
971 | tally /= tuner_settings.sample_size / 2; | 978 | tally /= size / 2; |
972 | 979 | ||
973 | /* now tally holds the average of the squares of all the samples */ | 980 | /* now tally holds the average of the squares of all the samples */ |
974 | /* It must be between 0 and 0x7fff^2, so it fits in 32 bits */ | 981 | /* It must be between 0 and 0x7fff^2, so it fits in 32 bits */ |
@@ -1065,9 +1072,12 @@ void record_and_get_pitch(void) | |||
1065 | #ifdef HAVE_SCHEDULER_BOOSTCTRL | 1072 | #ifdef HAVE_SCHEDULER_BOOSTCTRL |
1066 | rb->trigger_cpu_boost(); | 1073 | rb->trigger_cpu_boost(); |
1067 | #endif | 1074 | #endif |
1068 | 1075 | #ifdef PLUGIN_USE_IRAM | |
1076 | rb->memcpy(iram_audio_data, audio_data[audio_head], | ||
1077 | tuner_settings.sample_size * sizeof (int16_t)); | ||
1078 | #endif | ||
1069 | /* This returns the period of the detected pitch in samples */ | 1079 | /* This returns the period of the detected pitch in samples */ |
1070 | period = pitchyin(audio_data[audio_head], yin_buffer); | 1080 | period = pitchyin(iram_audio_data, yin_buffer); |
1071 | /* Hz = sample rate / period */ | 1081 | /* Hz = sample rate / period */ |
1072 | if(fp_gt(period, FP_ZERO)) | 1082 | if(fp_gt(period, FP_ZERO)) |
1073 | { | 1083 | { |
@@ -1099,6 +1109,7 @@ void record_and_get_pitch(void) | |||
1099 | } | 1109 | } |
1100 | } | 1110 | } |
1101 | rb->pcm_close_recording(); | 1111 | rb->pcm_close_recording(); |
1112 | rb->pcm_set_frequency(HW_SAMPR_DEFAULT); | ||
1102 | #ifdef HAVE_SCHEDULER_BOOSTCTRL | 1113 | #ifdef HAVE_SCHEDULER_BOOSTCTRL |
1103 | rb->cancel_cpu_boost(); | 1114 | rb->cancel_cpu_boost(); |
1104 | #endif | 1115 | #endif |
@@ -1108,10 +1119,15 @@ void record_and_get_pitch(void) | |||
1108 | 1119 | ||
1109 | /* Init recording, tuning, and GUI */ | 1120 | /* Init recording, tuning, and GUI */ |
1110 | void init_everything(void) | 1121 | void init_everything(void) |
1111 | { | 1122 | { |
1123 | /* Disable all talking before initializing IRAM */ | ||
1124 | rb->talk_disable(true); | ||
1125 | |||
1126 | PLUGIN_IRAM_INIT(rb); | ||
1127 | |||
1112 | load_settings(); | 1128 | load_settings(); |
1113 | 1129 | ||
1114 | /* Stop all playback */ | 1130 | /* Stop all playback (if no IRAM, otherwise IRAM_INIT would have) */ |
1115 | rb->plugin_get_audio_buffer(NULL); | 1131 | rb->plugin_get_audio_buffer(NULL); |
1116 | 1132 | ||
1117 | /* --------- Init the audio recording ----------------- */ | 1133 | /* --------- Init the audio recording ----------------- */ |
@@ -1149,6 +1165,8 @@ void init_everything(void) | |||
1149 | bar_grad_y = BAR_Y - BAR_PADDING - font_h; | 1165 | bar_grad_y = BAR_Y - BAR_PADDING - font_h; |
1150 | /* Put the note right between the top and bottom text elements */ | 1166 | /* Put the note right between the top and bottom text elements */ |
1151 | note_y = ((font_h + bar_grad_y - note_bitmaps.slide_height) / 2); | 1167 | note_y = ((font_h + bar_grad_y - note_bitmaps.slide_height) / 2); |
1168 | |||
1169 | rb->talk_disable(false); | ||
1152 | } | 1170 | } |
1153 | 1171 | ||
1154 | 1172 | ||