summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/plugin.c2
-rw-r--r--apps/plugin.h2
-rw-r--r--apps/plugins/pitch_detector.c394
3 files changed, 170 insertions, 228 deletions
diff --git a/apps/plugin.c b/apps/plugin.c
index 53a05bf527..5101ceeb20 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -721,6 +721,8 @@ static const struct plugin_api rockbox_api = {
721 721
722 /* new stuff at the end, sort into place next time 722 /* new stuff at the end, sort into place next time
723 the API gets incompatible */ 723 the API gets incompatible */
724
725 lcd_putsf,
724}; 726};
725 727
726int plugin_load(const char* plugin, const void* parameter) 728int plugin_load(const char* plugin, const void* parameter)
diff --git a/apps/plugin.h b/apps/plugin.h
index 17c36fa8b1..2bcd93e3ad 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -894,6 +894,8 @@ struct plugin_api {
894 894
895 /* new stuff at the end, sort into place next time 895 /* new stuff at the end, sort into place next time
896 the API gets incompatible */ 896 the API gets incompatible */
897
898 void (*lcd_putsf)(int x, int y, const unsigned char *fmt, ...);
897}; 899};
898 900
899/* plugin header */ 901/* plugin header */
diff --git a/apps/plugins/pitch_detector.c b/apps/plugins/pitch_detector.c
index 36e7059c1f..92ba6e53ac 100644
--- a/apps/plugins/pitch_detector.c
+++ b/apps/plugins/pitch_detector.c
@@ -5,7 +5,7 @@
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (C) 2008 Lechner Michael / smoking gnu 10 * Copyright (C) 2008 Lechner Michael / smoking gnu
11 * 11 *
@@ -19,15 +19,15 @@
19 * 19 *
20 * INTRODUCTION: 20 * INTRODUCTION:
21 * OK, this is an attempt to write an instrument tuner for rockbox. 21 * OK, this is an attempt to write an instrument tuner for rockbox.
22 * It uses a Schmitt trigger algorithm, which I copied from 22 * It uses a Schmitt trigger algorithm, which I copied from
23 * tuneit [ (c) 2004 Mario Lang <mlang@delysid.org> ], for detecting the 23 * tuneit [ (c) 2004 Mario Lang <mlang@delysid.org> ], for detecting the
24 * fundamental freqency of a sound. A FFT algorithm would be more accurate 24 * fundamental freqency of a sound. A FFT algorithm would be more accurate
25 * but also much slower. 25 * but also much slower.
26 * 26 *
27 * TODO: 27 * TODO:
28 * - Adapt the Yin FFT algorithm, which would reduce complexity from O(n^2) 28 * - Adapt the Yin FFT algorithm, which would reduce complexity from O(n^2)
29 * to O(nlogn), theoretically reducing latency by a factor of ~10. -David 29 * to O(nlogn), theoretically reducing latency by a factor of ~10. -David
30 * 30 *
31 * MAJOR CHANGES: 31 * MAJOR CHANGES:
32 * 08.03.2008 Started coding 32 * 08.03.2008 Started coding
33 * 21.03.2008 Pitch detection works more or less 33 * 21.03.2008 Pitch detection works more or less
@@ -42,7 +42,7 @@
42 * Aubio sound processing library (aubio.org). -David 42 * Aubio sound processing library (aubio.org). -David
43 * 08.31.2009 Lots of changes: 43 * 08.31.2009 Lots of changes:
44 * Added a menu to tweak settings 44 * Added a menu to tweak settings
45 * Converted everything to fixed point (greatly improving 45 * Converted everything to fixed point (greatly improving
46 * latency) 46 * latency)
47 * Improved the display 47 * Improved the display
48 * Improved efficiency with judicious use of cpu_boost, the 48 * Improved efficiency with judicious use of cpu_boost, the
@@ -51,17 +51,17 @@
51 * Fixed a problem that caused an octave-off error 51 * Fixed a problem that caused an octave-off error
52 * -David 52 * -David
53 * 05.14.2010 Multibuffer continuous recording with two buffers 53 * 05.14.2010 Multibuffer continuous recording with two buffers
54 * 54 *
55 * 55 *
56 * CURRENT LIMITATIONS: 56 * CURRENT LIMITATIONS:
57 * - No gapless recording. Strictly speaking true gappless isn't possible, 57 * - No gapless recording. Strictly speaking true gappless isn't possible,
58 * since the algorithm takes longer to calculate than the length of the 58 * since the algorithm takes longer to calculate than the length of the
59 * sample, but latency could be improved a bit with proper use of the DMA 59 * sample, but latency could be improved a bit with proper use of the DMA
60 * recording functions. 60 * recording functions.
61 * - Due to how the Yin algorithm works, latency is higher for lower 61 * - Due to how the Yin algorithm works, latency is higher for lower
62 * frequencies. 62 * frequencies.
63 */ 63 */
64 64
65#include "plugin.h" 65#include "plugin.h"
66#include "lib/pluginlib_actions.h" 66#include "lib/pluginlib_actions.h"
67#include "lib/picture.h" 67#include "lib/picture.h"
@@ -140,7 +140,7 @@ typedef struct _fixed fixed;
140/* there'll be one sample per second, or a latency of one second. */ 140/* there'll be one sample per second, or a latency of one second. */
141/* Furthermore, the lowest detectable frequency will be about twice */ 141/* Furthermore, the lowest detectable frequency will be about twice */
142/* the number of reads per second */ 142/* the number of reads per second */
143/* If we ever switch to Yin FFT algorithm then this needs to be 143/* If we ever switch to Yin FFT algorithm then this needs to be
144 a power of 2 */ 144 a power of 2 */
145#define BUFFER_SIZE 4096 145#define BUFFER_SIZE 4096
146#define SAMPLE_SIZE 4096 146#define SAMPLE_SIZE 4096
@@ -150,7 +150,7 @@ typedef struct _fixed fixed;
150#define LCD_FACTOR (fp_div(int2fixed(LCD_WIDTH), int2fixed(100))) 150#define LCD_FACTOR (fp_div(int2fixed(LCD_WIDTH), int2fixed(100)))
151/* The threshold for the YIN algorithm */ 151/* The threshold for the YIN algorithm */
152#define DEFAULT_YIN_THRESHOLD 5 /* 0.10 */ 152#define DEFAULT_YIN_THRESHOLD 5 /* 0.10 */
153const fixed yin_threshold_table[] IDATA_ATTR = 153static const fixed yin_threshold_table[] IDATA_ATTR =
154{ 154{
155 float2fixed(0.01), 155 float2fixed(0.01),
156 float2fixed(0.02), 156 float2fixed(0.02),
@@ -173,14 +173,12 @@ const fixed yin_threshold_table[] IDATA_ATTR =
173 * the note. The frequency is scaled in a way that the main 173 * the note. The frequency is scaled in a way that the main
174 * algorithm can assume the frequency of A to be 440 Hz. 174 * algorithm can assume the frequency of A to be 440 Hz.
175 */ 175 */
176struct freq_A_entry 176static const struct
177{ 177{
178 const int frequency; /* Frequency in Hz */ 178 const int frequency; /* Frequency in Hz */
179 const fixed ratio; /* 440/frequency */ 179 const fixed ratio; /* 440/frequency */
180 const fixed logratio; /* log2(factor) */ 180 const fixed logratio; /* log2(factor) */
181}; 181} freq_A[] =
182
183const struct freq_A_entry freq_A[] =
184{ 182{
185 {435, float2fixed(1.011363636), float2fixed( 0.016301812)}, 183 {435, float2fixed(1.011363636), float2fixed( 0.016301812)},
186 {436, float2fixed(1.009090909), float2fixed( 0.013056153)}, 184 {436, float2fixed(1.009090909), float2fixed( 0.013056153)},
@@ -214,8 +212,8 @@ const struct freq_A_entry freq_A[] =
214#define DISPLAY_HZ_PRECISION 100 212#define DISPLAY_HZ_PRECISION 100
215 213
216/* Where to put the various GUI elements */ 214/* Where to put the various GUI elements */
217int note_y; 215static int note_y;
218int bar_grad_y; 216static int bar_grad_y;
219#define LCD_RES_MIN (LCD_HEIGHT < LCD_WIDTH ? LCD_HEIGHT : LCD_WIDTH) 217#define LCD_RES_MIN (LCD_HEIGHT < LCD_WIDTH ? LCD_HEIGHT : LCD_WIDTH)
220#define BAR_PADDING (LCD_RES_MIN / 32) 218#define BAR_PADDING (LCD_RES_MIN / 32)
221#define BAR_Y (LCD_HEIGHT * 3 / 4) 219#define BAR_Y (LCD_HEIGHT * 3 / 4)
@@ -225,7 +223,7 @@ int bar_grad_y;
225#define HZ_Y 0 223#define HZ_Y 0
226#define GRADUATION 10 /* Subdivisions of the whole 100-cent scale */ 224#define GRADUATION 10 /* Subdivisions of the whole 100-cent scale */
227 225
228/* Bitmaps for drawing the note names. These need to have height 226/* Bitmaps for drawing the note names. These need to have height
229 <= (bar_grad_y - note_y), or 15/32 * LCD_HEIGHT 227 <= (bar_grad_y - note_y), or 15/32 * LCD_HEIGHT
230 */ 228 */
231#define NUM_NOTE_IMAGES 9 229#define NUM_NOTE_IMAGES 9
@@ -238,7 +236,8 @@ int bar_grad_y;
238#define NOTE_INDEX_G 6 236#define NOTE_INDEX_G 6
239#define NOTE_INDEX_SHARP 7 237#define NOTE_INDEX_SHARP 7
240#define NOTE_INDEX_FLAT 8 238#define NOTE_INDEX_FLAT 8
241const struct picture note_bitmaps = 239
240static const struct picture note_bitmaps =
242{ 241{
243 pitch_notes, 242 pitch_notes,
244 BMPWIDTH_pitch_notes, 243 BMPWIDTH_pitch_notes,
@@ -261,16 +260,13 @@ static int16_t iram_audio_data[BUFFER_SIZE] IBSS_ATTR;
261#endif 260#endif
262#endif 261#endif
263 262
264/* Description of a note of scale */ 263/* Notes within one (reference) scale */
265struct note_entry 264static const struct
266{ 265{
267 const char *name; /* Name of the note, e.g. "A#" */ 266 const char *name; /* Name of the note, e.g. "A#" */
268 const fixed freq; /* Note frequency, Hz */ 267 const fixed freq; /* Note frequency, Hz */
269 const fixed logfreq; /* log2(frequency) */ 268 const fixed logfreq; /* log2(frequency) */
270}; 269} notes[] =
271
272/* Notes within one (reference) scale */
273static const struct note_entry notes[] =
274{ 270{
275 {"A" , float2fixed(440.0000000f), float2fixed(8.781359714f)}, 271 {"A" , float2fixed(440.0000000f), float2fixed(8.781359714f)},
276 {"A#", float2fixed(466.1637615f), float2fixed(8.864693047f)}, 272 {"A#", float2fixed(466.1637615f), float2fixed(8.864693047f)},
@@ -295,7 +291,7 @@ static int bar_x_0;
295static int lbl_x_minus_50, lbl_x_minus_20, lbl_x_0, lbl_x_20, lbl_x_50; 291static int lbl_x_minus_50, lbl_x_minus_20, lbl_x_0, lbl_x_20, lbl_x_50;
296 292
297/* Settings for the plugin */ 293/* Settings for the plugin */
298struct tuner_settings 294static struct tuner_settings
299{ 295{
300 unsigned volume_threshold; 296 unsigned volume_threshold;
301 unsigned record_gain; 297 unsigned record_gain;
@@ -305,7 +301,7 @@ struct tuner_settings
305 int freq_A; /* Index of the frequency of A */ 301 int freq_A; /* Index of the frequency of A */
306 bool use_sharps; 302 bool use_sharps;
307 bool display_hz; 303 bool display_hz;
308} tuner_settings; 304} settings;
309 305
310/*=================================================================*/ 306/*=================================================================*/
311/* Settings loading and saving(adapted from the clock plugin) */ 307/* Settings loading and saving(adapted from the clock plugin) */
@@ -313,98 +309,68 @@ struct tuner_settings
313 309
314#define SETTINGS_FILENAME PLUGIN_APPS_DIR "/.pitch_settings" 310#define SETTINGS_FILENAME PLUGIN_APPS_DIR "/.pitch_settings"
315 311
316enum message 312/* The settings as they exist on the hard disk, so that
317{
318 MESSAGE_LOADING,
319 MESSAGE_LOADED,
320 MESSAGE_ERRLOAD,
321 MESSAGE_SAVING,
322 MESSAGE_SAVED,
323 MESSAGE_ERRSAVE
324};
325
326enum settings_file_status
327{
328 LOADED, ERRLOAD,
329 SAVED, ERRSAVE
330};
331
332/* The settings as they exist on the hard disk, so that
333 * we can know at saving time if changes have been made */ 313 * we can know at saving time if changes have been made */
334struct tuner_settings hdd_tuner_settings; 314static struct tuner_settings hdd_settings;
335 315
336/*---------------------------------------------------------------------*/ 316/*---------------------------------------------------------------------*/
337 317
338bool settings_needs_saving(struct tuner_settings* settings) 318static bool settings_needs_saving(void)
339{ 319{
340 return(rb->memcmp(settings, &hdd_tuner_settings, sizeof(*settings))); 320 return(rb->memcmp(&settings, &hdd_settings, sizeof(settings)));
341} 321}
342 322
343/*---------------------------------------------------------------------*/ 323/*---------------------------------------------------------------------*/
344 324
345void tuner_settings_reset(struct tuner_settings* settings) 325static void tuner_settings_reset(void)
346{ 326{
347 settings->volume_threshold = VOLUME_THRESHOLD; 327 settings = (struct tuner_settings) {
348 settings->record_gain = rb->global_settings->rec_mic_gain; 328 .volume_threshold = VOLUME_THRESHOLD,
349 settings->sample_size = BUFFER_SIZE; 329 .record_gain = rb->global_settings->rec_mic_gain,
350 settings->lowest_freq = period2freq(BUFFER_SIZE / 4); 330 .sample_size = BUFFER_SIZE,
351 settings->yin_threshold = DEFAULT_YIN_THRESHOLD; 331 .lowest_freq = period2freq(BUFFER_SIZE / 4),
352 settings->freq_A = DEFAULT_FREQ_A; 332 .yin_threshold = DEFAULT_YIN_THRESHOLD,
353 settings->use_sharps = true; 333 .freq_A = DEFAULT_FREQ_A,
354 settings->display_hz = false; 334 .use_sharps = true,
335 .display_hz = false,
336 };
355} 337}
356 338
357/*---------------------------------------------------------------------*/ 339/*---------------------------------------------------------------------*/
358 340
359enum settings_file_status tuner_settings_load(struct tuner_settings* settings, 341static void load_settings(void)
360 char* filename)
361{ 342{
362 int fd = rb->open(filename, O_RDONLY); 343 int fd = rb->open(SETTINGS_FILENAME, O_RDONLY);
363 if(fd >= 0){ /* does file exist? */ 344 if(fd < 0){ /* file doesn't exist */
364 /* basic consistency check */ 345 /* Initializes the settings with default values at least */
365 if(rb->filesize(fd) == sizeof(*settings)){ 346 tuner_settings_reset();
366 rb->read(fd, settings, sizeof(*settings)); 347 return;
367 rb->close(fd);
368 rb->memcpy(&hdd_tuner_settings, settings, sizeof(*settings));
369 return(LOADED);
370 }
371 } 348 }
372 /* Initializes the settings with default values at least */
373 tuner_settings_reset(settings);
374 return(ERRLOAD);
375}
376
377/*---------------------------------------------------------------------*/
378 349
379enum settings_file_status tuner_settings_save(struct tuner_settings* settings, 350 /* basic consistency check */
380 char* filename) 351 if(rb->filesize(fd) == sizeof(settings)){
381{ 352 rb->read(fd, &settings, sizeof(settings));
382 int fd = rb->creat(filename, 0666); 353 rb->memcpy(&hdd_settings, &settings, sizeof(settings));
383 if(fd >= 0){ /* does file exist? */ 354 }
384 rb->write (fd, settings, sizeof(*settings)); 355 else{
385 rb->close(fd); 356 tuner_settings_reset();
386 return(SAVED);
387 } 357 }
388 return(ERRSAVE);
389}
390
391/*---------------------------------------------------------------------*/
392
393void load_settings(void)
394{
395 tuner_settings_load(&tuner_settings, SETTINGS_FILENAME);
396 358
397 rb->storage_sleep(); 359 rb->close(fd);
398} 360}
399 361
400/*---------------------------------------------------------------------*/ 362/*---------------------------------------------------------------------*/
401 363
402void save_settings(void) 364static void save_settings(void)
403{ 365{
404 if(!settings_needs_saving(&tuner_settings)) 366 if(!settings_needs_saving())
405 return; 367 return;
406 368
407 tuner_settings_save(&tuner_settings, SETTINGS_FILENAME); 369 int fd = rb->creat(SETTINGS_FILENAME, 0666);
370 if(fd >= 0){ /* does file exist? */
371 rb->write (fd, &settings, sizeof(settings));
372 rb->close(fd);
373 }
408} 374}
409 375
410/*=================================================================*/ 376/*=================================================================*/
@@ -423,7 +389,7 @@ const struct button_mapping* plugin_contexts[]={
423/* Option strings */ 389/* Option strings */
424 390
425/* This has to match yin_threshold_table */ 391/* This has to match yin_threshold_table */
426static const struct opt_items yin_threshold_text[] = 392static const struct opt_items yin_threshold_text[] =
427{ 393{
428 { "0.01", -1 }, 394 { "0.01", -1 },
429 { "0.02", -1 }, 395 { "0.02", -1 },
@@ -441,27 +407,27 @@ static const struct opt_items yin_threshold_text[] =
441 { "0.50", -1 }, 407 { "0.50", -1 },
442}; 408};
443 409
444static const struct opt_items accidental_text[] = 410static const struct opt_items accidental_text[] =
445{ 411{
446 { "Flat", -1 }, 412 { "Flat", -1 },
447 { "Sharp", -1 }, 413 { "Sharp", -1 },
448}; 414};
449 415
450void set_min_freq(int new_freq) 416static void set_min_freq(int new_freq)
451{ 417{
452 tuner_settings.sample_size = freq2period(new_freq) * 4; 418 settings.sample_size = freq2period(new_freq) * 4;
453 419
454 /* clamp the sample size between min and max */ 420 /* clamp the sample size between min and max */
455 if(tuner_settings.sample_size <= SAMPLE_SIZE_MIN) 421 if(settings.sample_size <= SAMPLE_SIZE_MIN)
456 tuner_settings.sample_size = SAMPLE_SIZE_MIN; 422 settings.sample_size = SAMPLE_SIZE_MIN;
457 else if(tuner_settings.sample_size >= BUFFER_SIZE) 423 else if(settings.sample_size >= BUFFER_SIZE)
458 tuner_settings.sample_size = BUFFER_SIZE; 424 settings.sample_size = BUFFER_SIZE;
459 425
460 /* sample size must be divisible by 4 - round up */ 426 /* sample size must be divisible by 4 - round up */
461 tuner_settings.sample_size = (tuner_settings.sample_size + 3) & ~3; 427 settings.sample_size = (settings.sample_size + 3) & ~3;
462} 428}
463 429
464bool main_menu(void) 430static bool main_menu(void)
465{ 431{
466 int selection = 0; 432 int selection = 0;
467 bool done = false; 433 bool done = false;
@@ -494,58 +460,58 @@ bool main_menu(void)
494 { 460 {
495 case 1: 461 case 1:
496 rb->set_int("Volume Threshold", "%", UNIT_INT, 462 rb->set_int("Volume Threshold", "%", UNIT_INT,
497 &tuner_settings.volume_threshold, 463 &settings.volume_threshold,
498 NULL, 5, 5, 95, NULL); 464 NULL, 5, 5, 95, NULL);
499 break; 465 break;
500 case 2: 466 case 2:
501 rb->set_int("Listening Volume", "%", UNIT_INT, 467 rb->set_int("Listening Volume", "%", UNIT_INT,
502 &tuner_settings.record_gain, 468 &settings.record_gain,
503 NULL, 1, rb->sound_min(SOUND_MIC_GAIN), 469 NULL, 1, rb->sound_min(SOUND_MIC_GAIN),
504 rb->sound_max(SOUND_MIC_GAIN), NULL); 470 rb->sound_max(SOUND_MIC_GAIN), NULL);
505 break; 471 break;
506 case 3: 472 case 3:
507 rb->set_int("Lowest Frequency", "Hz", UNIT_INT, 473 rb->set_int("Lowest Frequency", "Hz", UNIT_INT,
508 &tuner_settings.lowest_freq, set_min_freq, 1, 474 &settings.lowest_freq, set_min_freq, 1,
509 /* Range depends on the size of the buffer */ 475 /* Range depends on the size of the buffer */
510 sample_rate / (BUFFER_SIZE / 4), 476 sample_rate / (BUFFER_SIZE / 4),
511 sample_rate / (SAMPLE_SIZE_MIN / 4), NULL); 477 sample_rate / (SAMPLE_SIZE_MIN / 4), NULL);
512 break; 478 break;
513 case 4: 479 case 4:
514 rb->set_option( 480 rb->set_option(
515 "Algorithm Pickiness (Lower -> more discriminating)", 481 "Algorithm Pickiness (Lower -> more discriminating)",
516 &tuner_settings.yin_threshold, 482 &settings.yin_threshold,
517 INT, yin_threshold_text, 483 INT, yin_threshold_text,
518 sizeof(yin_threshold_text) / sizeof(yin_threshold_text[0]), 484 sizeof(yin_threshold_text) / sizeof(yin_threshold_text[0]),
519 NULL); 485 NULL);
520 break; 486 break;
521 case 5: 487 case 5:
522 rb->set_option("Display Accidentals As", 488 rb->set_option("Display Accidentals As",
523 &tuner_settings.use_sharps, 489 &settings.use_sharps,
524 BOOL, accidental_text, 2, NULL); 490 BOOL, accidental_text, 2, NULL);
525 break; 491 break;
526 case 6: 492 case 6:
527 rb->set_bool("Display Frequency (Hz)", 493 rb->set_bool("Display Frequency (Hz)",
528 &tuner_settings.display_hz); 494 &settings.display_hz);
529 break; 495 break;
530 case 7: 496 case 7:
531 freq_val = freq_A[tuner_settings.freq_A].frequency; 497 freq_val = freq_A[settings.freq_A].frequency;
532 rb->set_int("Frequency of A (Hz)", 498 rb->set_int("Frequency of A (Hz)",
533 "Hz", UNIT_INT, &freq_val, NULL, 499 "Hz", UNIT_INT, &freq_val, NULL,
534 1, freq_A[0].frequency, freq_A[NUM_FREQ_A-1].frequency, 500 1, freq_A[0].frequency, freq_A[NUM_FREQ_A-1].frequency,
535 NULL); 501 NULL);
536 tuner_settings.freq_A = freq_val - freq_A[0].frequency; 502 settings.freq_A = freq_val - freq_A[0].frequency;
537 break; 503 break;
538 case 8: 504 case 8:
539 reset = false; 505 reset = false;
540 rb->set_bool("Reset Tuner Settings?", &reset); 506 rb->set_bool("Reset Tuner Settings?", &reset);
541 if (reset) 507 if (reset)
542 tuner_settings_reset(&tuner_settings); 508 tuner_settings_reset();
543 break; 509 break;
544 case 9: 510 case 9:
545 exit_tuner = true; 511 exit_tuner = true;
546 done = true; 512 done = true;
547 break; 513 break;
548 case 0: 514 case 0:
549 default: 515 default:
550 /* Return to the tuner */ 516 /* Return to the tuner */
551 done = true; 517 done = true;
@@ -562,15 +528,15 @@ bool main_menu(void)
562/*=================================================================*/ 528/*=================================================================*/
563 529
564/* Fixed-point log base 2*/ 530/* Fixed-point log base 2*/
565/* Adapted from python code at 531/* Adapted from python code at
566 http://en.wikipedia.org/wiki/Binary_logarithm#Algorithm 532 http://en.wikipedia.org/wiki/Binary_logarithm#Algorithm
567*/ 533*/
568fixed log(fixed inp) 534static fixed log(fixed inp)
569{ 535{
570 fixed x = inp; 536 fixed x = inp;
571 fixed fp = int2fixed(1); 537 fixed fp = int2fixed(1);
572 fixed res = int2fixed(0); 538 fixed res = int2fixed(0);
573 539
574 if(fp_lte(x, FP_ZERO)) 540 if(fp_lte(x, FP_ZERO))
575 { 541 {
576 return FP_MIN; 542 return FP_MIN;
@@ -611,59 +577,25 @@ fixed log(fixed inp)
611/* GUI Stuff */ 577/* GUI Stuff */
612/*=================================================================*/ 578/*=================================================================*/
613 579
614/* The function name is pretty self-explaining ;) */
615void print_int_xy(int x, int y, int v)
616{
617 char temp[20];
618#if LCD_DEPTH > 1
619 rb->lcd_set_foreground(front_color);
620#endif
621 rb->snprintf(temp,20,"%d",v);
622 rb->lcd_putsxy(x,y,temp);
623}
624
625/* Print out the frequency etc */
626void print_str(char* s)
627{
628#if LCD_DEPTH > 1
629 rb->lcd_set_foreground(front_color);
630#endif
631 rb->lcd_putsxy(0, HZ_Y, s);
632}
633
634/* What can I say? Read the function name... */
635void print_char_xy(int x, int y, char c)
636{
637 char temp[2];
638
639 temp[0]=c;
640 temp[1]=0;
641#if LCD_DEPTH > 1
642 rb->lcd_set_foreground(front_color);
643#endif
644
645 rb->lcd_putsxy(x, y, temp);
646}
647
648/* Draw the note bitmap */ 580/* Draw the note bitmap */
649void draw_note(const char *note) 581static void draw_note(const char *note)
650{ 582{
651 int i; 583 int i;
652 int note_x = (LCD_WIDTH - BMPWIDTH_pitch_notes) / 2; 584 int note_x = (LCD_WIDTH - BMPWIDTH_pitch_notes) / 2;
653 int accidental_index = NOTE_INDEX_SHARP; 585 int accidental_index = NOTE_INDEX_SHARP;
654 586
655 i = note[0]-'A'; 587 i = note[0]-'A';
656 588
657 if(note[1] == '#') 589 if(note[1] == '#')
658 { 590 {
659 if(!(tuner_settings.use_sharps)) 591 if(!(settings.use_sharps))
660 { 592 {
661 i = (i + 1) % 7; 593 i = (i + 1) % 7;
662 accidental_index = NOTE_INDEX_FLAT; 594 accidental_index = NOTE_INDEX_FLAT;
663 } 595 }
664 596
665 vertical_picture_draw_sprite(rb->screens[0], 597 vertical_picture_draw_sprite(rb->screens[0],
666 &note_bitmaps, 598 &note_bitmaps,
667 accidental_index, 599 accidental_index,
668 LCD_WIDTH / 2, 600 LCD_WIDTH / 2,
669 note_y); 601 note_y);
@@ -674,9 +606,10 @@ void draw_note(const char *note)
674 note_x, 606 note_x,
675 note_y); 607 note_y);
676} 608}
609
677/* Draw the red bar and the white lines */ 610/* Draw the red bar and the white lines */
678void draw_bar(fixed wrong_by_cents) 611static void draw_bar(fixed wrong_by_cents)
679{ 612{
680 unsigned n; 613 unsigned n;
681 int x; 614 int x;
682 615
@@ -698,11 +631,14 @@ void draw_bar(fixed wrong_by_cents)
698 rb->lcd_vline(x, BAR_HLINE_Y, BAR_HLINE_Y2); 631 rb->lcd_vline(x, BAR_HLINE_Y, BAR_HLINE_Y2);
699 } 632 }
700 633
701 print_int_xy(lbl_x_minus_50 ,bar_grad_y, -50); 634#if LCD_DEPTH > 1
702 print_int_xy(lbl_x_minus_20 ,bar_grad_y, -20); 635 rb->lcd_set_foreground(front_color);
703 print_int_xy(lbl_x_0 ,bar_grad_y, 0); 636#endif
704 print_int_xy(lbl_x_20 ,bar_grad_y, 20); 637 rb->lcd_putsf(lbl_x_minus_50 ,bar_grad_y, "%d", -50);
705 print_int_xy(lbl_x_50 ,bar_grad_y, 50); 638 rb->lcd_putsf(lbl_x_minus_20 ,bar_grad_y, "%d", -20);
639 rb->lcd_putsf(lbl_x_0 ,bar_grad_y, "%d", 0);
640 rb->lcd_putsf(lbl_x_20 ,bar_grad_y, "%d", 20);
641 rb->lcd_putsf(lbl_x_50 ,bar_grad_y, "%d", 50);
706 642
707#ifdef HAVE_LCD_COLOR 643#ifdef HAVE_LCD_COLOR
708 rb->lcd_set_foreground(LCD_RGBPACK(255,0,0)); /* Color screens */ 644 rb->lcd_set_foreground(LCD_RGBPACK(255,0,0)); /* Color screens */
@@ -712,26 +648,25 @@ void draw_bar(fixed wrong_by_cents)
712 648
713 if (fp_gt(wrong_by_cents, FP_ZERO)) 649 if (fp_gt(wrong_by_cents, FP_ZERO))
714 { 650 {
715 rb->lcd_fillrect(bar_x_0, BAR_Y, 651 rb->lcd_fillrect(bar_x_0, BAR_Y,
716 fixed2int(fp_mul(wrong_by_cents, LCD_FACTOR)), BAR_HEIGHT); 652 fixed2int(fp_mul(wrong_by_cents, LCD_FACTOR)), BAR_HEIGHT);
717 } 653 }
718 else 654 else
719 { 655 {
720 rb->lcd_fillrect(bar_x_0 + fixed2int(fp_mul(wrong_by_cents,LCD_FACTOR)), 656 rb->lcd_fillrect(bar_x_0 + fixed2int(fp_mul(wrong_by_cents,LCD_FACTOR)),
721 BAR_Y, 657 BAR_Y,
722 fixed2int(fp_mul(wrong_by_cents, LCD_FACTOR)) * -1, 658 fixed2int(fp_mul(wrong_by_cents, LCD_FACTOR)) * -1,
723 BAR_HEIGHT); 659 BAR_HEIGHT);
724 } 660 }
725} 661}
726 662
727/* Calculate how wrong the note is and draw the GUI */ 663/* Calculate how wrong the note is and draw the GUI */
728void display_frequency (fixed freq) 664static void display_frequency (fixed freq)
729{ 665{
730 fixed ldf, mldf; 666 fixed ldf, mldf;
731 fixed lfreq, nfreq; 667 fixed lfreq, nfreq;
732 fixed orig_freq; 668 fixed orig_freq;
733 int i, note = 0; 669 int i, note = 0;
734 char str_buf[30];
735 670
736 if (fp_lt(freq, FP_LOW)) 671 if (fp_lt(freq, FP_LOW))
737 freq = FP_LOW; 672 freq = FP_LOW;
@@ -739,8 +674,8 @@ void display_frequency (fixed freq)
739 /* We calculate the frequency and its log as if */ 674 /* We calculate the frequency and its log as if */
740 /* the reference frequency of A were 440 Hz. */ 675 /* the reference frequency of A were 440 Hz. */
741 orig_freq = freq; 676 orig_freq = freq;
742 lfreq = fp_add(log(freq), freq_A[tuner_settings.freq_A].logratio); 677 lfreq = fp_add(log(freq), freq_A[settings.freq_A].logratio);
743 freq = fp_mul(freq, freq_A[tuner_settings.freq_A].ratio); 678 freq = fp_mul(freq, freq_A[settings.freq_A].ratio);
744 679
745 /* This calculates a log freq offset for note A */ 680 /* This calculates a log freq offset for note A */
746 /* Get the frequency to within the range of our reference table, */ 681 /* Get the frequency to within the range of our reference table, */
@@ -775,39 +710,41 @@ void display_frequency (fixed freq)
775 if(fp_round(freq) != 0) 710 if(fp_round(freq) != 0)
776 { 711 {
777 draw_note(notes[note].name); 712 draw_note(notes[note].name);
778 if(tuner_settings.display_hz) 713 if(settings.display_hz)
779 { 714 {
780 rb->snprintf(str_buf,30, "%s : %d cents (%d.%02dHz)", 715#if LCD_DEPTH > 1
716 rb->lcd_set_foreground(front_color);
717#endif
718 rb->lcd_putsf(0, HZ_Y, "%s : %d cents (%d.%02dHz)",
781 notes[note].name, fp_round(ldf) ,fixed2int(orig_freq), 719 notes[note].name, fp_round(ldf) ,fixed2int(orig_freq),
782 fp_round(fp_mul(fp_frac(orig_freq), 720 fp_round(fp_mul(fp_frac(orig_freq),
783 int2fixed(DISPLAY_HZ_PRECISION)))); 721 int2fixed(DISPLAY_HZ_PRECISION))));
784 print_str(str_buf);
785 } 722 }
786 } 723 }
787 rb->lcd_update(); 724 rb->lcd_update();
788} 725}
789 726
790/*----------------------------------------------------------------------- 727/*-----------------------------------------------------------------------
791 * Functions for the Yin algorithm 728 * Functions for the Yin algorithm
792 * 729 *
793 * These were all adapted from the versions in Aubio v0.3.2 730 * These were all adapted from the versions in Aubio v0.3.2
794 * Here's what the Aubio documentation has to say: 731 * Here's what the Aubio documentation has to say:
795 * 732 *
796 * This algorithm was developped by A. de Cheveigne and H. Kawahara and 733 * This algorithm was developped by A. de Cheveigne and H. Kawahara and
797 * published in: 734 * published in:
798 * 735 *
799 * de Cheveign?, A., Kawahara, H. (2002) "YIN, a fundamental frequency 736 * de Cheveign?, A., Kawahara, H. (2002) "YIN, a fundamental frequency
800 * estimator for speech and music", J. Acoust. Soc. Am. 111, 1917-1930. 737 * estimator for speech and music", J. Acoust. Soc. Am. 111, 1917-1930.
801 * 738 *
802 * see http://recherche.ircam.fr/equipes/pcm/pub/people/cheveign.html 739 * see http://recherche.ircam.fr/equipes/pcm/pub/people/cheveign.html
803-------------------------------------------------------------------------*/ 740-------------------------------------------------------------------------*/
804 741
805/* Find the index of the minimum element of an array of floats */ 742/* Find the index of the minimum element of an array of floats */
806unsigned vec_min_elem(fixed *s, unsigned buflen) 743static unsigned vec_min_elem(fixed *s, unsigned buflen)
807{ 744{
808 unsigned j, pos=0.0f; 745 unsigned j, pos=0.0f;
809 fixed tmp = s[0]; 746 fixed tmp = s[0];
810 for (j=0; j < buflen; j++) 747 for (j=0; j < buflen; j++)
811 { 748 {
812 if(fp_gt(tmp, s[j])) 749 if(fp_gt(tmp, s[j]))
813 { 750 {
@@ -819,13 +756,13 @@ unsigned vec_min_elem(fixed *s, unsigned buflen)
819} 756}
820 757
821 758
822static inline fixed aubio_quadfrac(fixed s0, fixed s1, fixed s2, fixed pf) 759static inline fixed aubio_quadfrac(fixed s0, fixed s1, fixed s2, fixed pf)
823{ 760{
824 /* Original floating point version: */ 761 /* Original floating point version: */
825 /* tmp = s0 + (pf/2.0f) * (pf * ( s0 - 2.0f*s1 + s2 ) - 762 /* tmp = s0 + (pf/2.0f) * (pf * ( s0 - 2.0f*s1 + s2 ) -
826 3.0f*s0 + 4.0f*s1 - s2);*/ 763 3.0f*s0 + 4.0f*s1 - s2);*/
827 /* Converted to explicit operator precedence: */ 764 /* Converted to explicit operator precedence: */
828 /* tmp = s0 + ((pf/2.0f) * ((((pf * ((s0 - (2*s1)) + s2)) - 765 /* tmp = s0 + ((pf/2.0f) * ((((pf * ((s0 - (2*s1)) + s2)) -
829 (3*s0)) + (4*s1)) - s2)); */ 766 (3*s0)) + (4*s1)) - s2)); */
830 767
831 /* I made it look like this so I could easily track the precedence and */ 768 /* I made it look like this so I could easily track the precedence and */
@@ -853,7 +790,7 @@ static inline fixed aubio_quadfrac(fixed s0, fixed s1, fixed s2, fixed pf)
853 s0, 790 s0,
854 fp_shl(s1, 1) 791 fp_shl(s1, 1)
855 ), 792 ),
856 s2 793 s2
857 ) 794 )
858 ), 795 ),
859 fp_mul 796 fp_mul
@@ -873,32 +810,32 @@ static inline fixed aubio_quadfrac(fixed s0, fixed s1, fixed s2, fixed pf)
873 810
874#define QUADINT_STEP float2fixed(1.0f/200.0f) 811#define QUADINT_STEP float2fixed(1.0f/200.0f)
875 812
876fixed ICODE_ATTR vec_quadint_min(fixed *x, unsigned bufsize, unsigned pos, unsigned span) 813static fixed ICODE_ATTR vec_quadint_min(fixed *x, unsigned bufsize, unsigned pos, unsigned span)
877{ 814{
878 fixed res, frac, s0, s1, s2; 815 fixed res, frac, s0, s1, s2;
879 fixed exactpos = int2fixed(pos); 816 fixed exactpos = int2fixed(pos);
880 /* init resold to something big (in case x[pos+-span]<0)) */ 817 /* init resold to something big (in case x[pos+-span]<0)) */
881 fixed resold = FP_MAX; 818 fixed resold = FP_MAX;
882 819
883 if ((pos > span) && (pos < bufsize-span)) 820 if ((pos > span) && (pos < bufsize-span))
884 { 821 {
885 s0 = x[pos-span]; 822 s0 = x[pos-span];
886 s1 = x[pos] ; 823 s1 = x[pos] ;
887 s2 = x[pos+span]; 824 s2 = x[pos+span];
888 /* increase frac */ 825 /* increase frac */
889 for (frac = float2fixed(0.0f); 826 for (frac = float2fixed(0.0f);
890 fp_lt(frac, float2fixed(2.0f)); 827 fp_lt(frac, float2fixed(2.0f));
891 frac = fp_add(frac, QUADINT_STEP)) 828 frac = fp_add(frac, QUADINT_STEP))
892 { 829 {
893 res = aubio_quadfrac(s0, s1, s2, frac); 830 res = aubio_quadfrac(s0, s1, s2, frac);
894 if (fp_lt(res, resold)) 831 if (fp_lt(res, resold))
895 { 832 {
896 resold = res; 833 resold = res;
897 } 834 }
898 else 835 else
899 { 836 {
900 /* exactpos += (frac-QUADINT_STEP)*span - span/2.0f; */ 837 /* exactpos += (frac-QUADINT_STEP)*span - span/2.0f; */
901 exactpos = fp_add(exactpos, 838 exactpos = fp_add(exactpos,
902 fp_sub( 839 fp_sub(
903 fp_mul( 840 fp_mul(
904 fp_sub(frac, QUADINT_STEP), 841 fp_sub(frac, QUADINT_STEP),
@@ -915,17 +852,17 @@ fixed ICODE_ATTR vec_quadint_min(fixed *x, unsigned bufsize, unsigned pos, unsig
915} 852}
916 853
917 854
918/* Calculate the period of the note in the 855/* Calculate the period of the note in the
919 buffer using the YIN algorithm */ 856 buffer using the YIN algorithm */
920/* The yin pointer is just a buffer that the algorithm uses as a work 857/* The yin pointer is just a buffer that the algorithm uses as a work
921 space. It needs to be half the length of the input buffer. */ 858 space. It needs to be half the length of the input buffer. */
922 859
923fixed ICODE_ATTR pitchyin(int16_t *input, fixed *yin) 860static fixed ICODE_ATTR pitchyin(int16_t *input, fixed *yin)
924{ 861{
925 fixed retval; 862 fixed retval;
926 unsigned j,tau = 0; 863 unsigned j,tau = 0;
927 int period; 864 int period;
928 unsigned yin_size = tuner_settings.sample_size / 4; 865 unsigned yin_size = settings.sample_size / 4;
929 866
930 fixed tmp = FP_ZERO, tmp2 = FP_ZERO; 867 fixed tmp = FP_ZERO, tmp2 = FP_ZERO;
931 yin[0] = int2fixed(1); 868 yin[0] = int2fixed(1);
@@ -934,7 +871,7 @@ fixed ICODE_ATTR pitchyin(int16_t *input, fixed *yin)
934 yin[tau] = FP_ZERO; 871 yin[tau] = FP_ZERO;
935 for (j = 0; j < yin_size; j++) 872 for (j = 0; j < yin_size; j++)
936 { 873 {
937 tmp = fp_sub(int2mantissa(input[2 * j]), 874 tmp = fp_sub(int2mantissa(input[2 * j]),
938 int2mantissa(input[2 * (j + tau)])); 875 int2mantissa(input[2 * (j + tau)]));
939 yin[tau] = fp_add(yin[tau], fp_mul(tmp, tmp)); 876 yin[tau] = fp_add(yin[tau], fp_mul(tmp, tmp));
940 } 877 }
@@ -944,15 +881,15 @@ fixed ICODE_ATTR pitchyin(int16_t *input, fixed *yin)
944 yin[tau] = fp_mul(yin[tau], fp_div(int2fixed(tau), tmp2)); 881 yin[tau] = fp_mul(yin[tau], fp_div(int2fixed(tau), tmp2));
945 } 882 }
946 period = tau - 3; 883 period = tau - 3;
947 if(tau > 4 && fp_lt(yin[period], 884 if(tau > 4 && fp_lt(yin[period],
948 yin_threshold_table[tuner_settings.yin_threshold]) 885 yin_threshold_table[settings.yin_threshold])
949 && fp_lt(yin[period], yin[period+1])) 886 && fp_lt(yin[period], yin[period+1]))
950 { 887 {
951 retval = vec_quadint_min(yin, yin_size, period, 1); 888 retval = vec_quadint_min(yin, yin_size, period, 1);
952 return retval; 889 return retval;
953 } 890 }
954 } 891 }
955 retval = vec_quadint_min(yin, yin_size, 892 retval = vec_quadint_min(yin, yin_size,
956 vec_min_elem(yin, yin_size), 1); 893 vec_min_elem(yin, yin_size), 1);
957 return retval; 894 return retval;
958 /*return FP_ZERO;*/ 895 /*return FP_ZERO;*/
@@ -960,11 +897,11 @@ fixed ICODE_ATTR pitchyin(int16_t *input, fixed *yin)
960 897
961/*-----------------------------------------------------------------*/ 898/*-----------------------------------------------------------------*/
962 899
963uint32_t ICODE_ATTR buffer_magnitude(int16_t *input) 900static uint32_t ICODE_ATTR buffer_magnitude(int16_t *input)
964{ 901{
965 unsigned n; 902 unsigned n;
966 uint64_t tally = 0; 903 uint64_t tally = 0;
967 const unsigned size = tuner_settings.sample_size; 904 const unsigned size = settings.sample_size;
968 905
969 /* Operate on only one channel of the stereo signal */ 906 /* Operate on only one channel of the stereo signal */
970 for(n = 0; n < size; n+=2) 907 for(n = 0; n < size; n+=2)
@@ -982,7 +919,7 @@ uint32_t ICODE_ATTR buffer_magnitude(int16_t *input)
982 919
983/* Stop the recording when the buffer is full */ 920/* Stop the recording when the buffer is full */
984#ifndef SIMULATOR 921#ifndef SIMULATOR
985void recording_callback(int status, void **start, size_t *size) 922static void recording_callback(int status, void **start, size_t *size)
986{ 923{
987 int tail = audio_tail ^ 1; 924 int tail = audio_tail ^ 1;
988 925
@@ -1003,13 +940,13 @@ static void record_data(void)
1003{ 940{
1004#ifndef SIMULATOR 941#ifndef SIMULATOR
1005 /* Always record full buffer, even if not required */ 942 /* Always record full buffer, even if not required */
1006 rb->pcm_record_data(recording_callback, audio_data[audio_tail], 943 rb->pcm_record_data(recording_callback, audio_data[audio_tail],
1007 BUFFER_SIZE * sizeof (int16_t)); 944 BUFFER_SIZE * sizeof (int16_t));
1008#endif 945#endif
1009} 946}
1010 947
1011/* The main program loop */ 948/* The main program loop */
1012void record_and_get_pitch(void) 949static void record_and_get_pitch(void)
1013{ 950{
1014 int quit=0, button; 951 int quit=0, button;
1015 bool redraw = true; 952 bool redraw = true;
@@ -1029,18 +966,18 @@ void record_and_get_pitch(void)
1029 966
1030 record_data(); 967 record_data();
1031 968
1032 while(!quit) 969 while(!quit)
1033 { 970 {
1034 while (audio_head == audio_tail && !quit) /* wait for the buffer to be filled */ 971 while (audio_head == audio_tail && !quit) /* wait for the buffer to be filled */
1035 { 972 {
1036 button=pluginlib_getaction(HZ/100, plugin_contexts, PLA_ARRAY_COUNT); 973 button=pluginlib_getaction(HZ/100, plugin_contexts, PLA_ARRAY_COUNT);
1037 974
1038 switch(button) 975 switch(button)
1039 { 976 {
1040 case PLA_EXIT: 977 case PLA_EXIT:
1041 quit=true; 978 quit=true;
1042 break; 979 break;
1043 980
1044 case PLA_CANCEL: 981 case PLA_CANCEL:
1045 rb->pcm_stop_recording(); 982 rb->pcm_stop_recording();
1046 quit = main_menu() != 0; 983 quit = main_menu() != 0;
@@ -1050,17 +987,17 @@ void record_and_get_pitch(void)
1050 record_data(); 987 record_data();
1051 } 988 }
1052 break; 989 break;
1053 990
1054 break; 991 break;
1055 } 992 }
1056 } 993 }
1057 994
1058 if(!quit) 995 if(!quit)
1059 { 996 {
1060#ifndef SIMULATOR 997#ifndef SIMULATOR
1061 /* Only do the heavy lifting if the volume is high enough */ 998 /* Only do the heavy lifting if the volume is high enough */
1062 if(buffer_magnitude(audio_data[audio_head]) > 999 if(buffer_magnitude(audio_data[audio_head]) >
1063 sqr(tuner_settings.volume_threshold * 1000 sqr(settings.volume_threshold *
1064 rb->sound_max(SOUND_MIC_GAIN))) 1001 rb->sound_max(SOUND_MIC_GAIN)))
1065 { 1002 {
1066 waiting = false; 1003 waiting = false;
@@ -1071,7 +1008,7 @@ void record_and_get_pitch(void)
1071 #endif 1008 #endif
1072#ifdef PLUGIN_USE_IRAM 1009#ifdef PLUGIN_USE_IRAM
1073 rb->memcpy(iram_audio_data, audio_data[audio_head], 1010 rb->memcpy(iram_audio_data, audio_data[audio_head],
1074 tuner_settings.sample_size * sizeof (int16_t)); 1011 settings.sample_size * sizeof (int16_t));
1075#endif 1012#endif
1076 /* This returns the period of the detected pitch in samples */ 1013 /* This returns the period of the detected pitch in samples */
1077 period = pitchyin(iram_audio_data, yin_buffer); 1014 period = pitchyin(iram_audio_data, yin_buffer);
@@ -1080,7 +1017,7 @@ void record_and_get_pitch(void)
1080 { 1017 {
1081 display_frequency(fp_period2freq(period)); 1018 display_frequency(fp_period2freq(period));
1082 } 1019 }
1083 else 1020 else
1084 { 1021 {
1085 display_frequency(FP_ZERO); 1022 display_frequency(FP_ZERO);
1086 } 1023 }
@@ -1115,7 +1052,7 @@ void record_and_get_pitch(void)
1115} 1052}
1116 1053
1117/* Init recording, tuning, and GUI */ 1054/* Init recording, tuning, and GUI */
1118void init_everything(void) 1055static void init_everything(void)
1119{ 1056{
1120 /* Disable all talking before initializing IRAM */ 1057 /* Disable all talking before initializing IRAM */
1121 rb->talk_disable(true); 1058 rb->talk_disable(true);
@@ -1123,17 +1060,18 @@ void init_everything(void)
1123 PLUGIN_IRAM_INIT(rb); 1060 PLUGIN_IRAM_INIT(rb);
1124 1061
1125 load_settings(); 1062 load_settings();
1063 rb->storage_sleep();
1126 1064
1127 /* Stop all playback (if no IRAM, otherwise IRAM_INIT would have) */ 1065 /* Stop all playback (if no IRAM, otherwise IRAM_INIT would have) */
1128 rb->plugin_get_audio_buffer(NULL); 1066 rb->plugin_get_audio_buffer(NULL);
1129 1067
1130 /* --------- Init the audio recording ----------------- */ 1068 /* --------- Init the audio recording ----------------- */
1131 rb->audio_set_output_source(AUDIO_SRC_PLAYBACK); 1069 rb->audio_set_output_source(AUDIO_SRC_PLAYBACK);
1132 rb->audio_set_input_source(INPUT_TYPE, SRCF_RECORDING); 1070 rb->audio_set_input_source(INPUT_TYPE, SRCF_RECORDING);
1133 1071
1134 /* set to maximum gain */ 1072 /* set to maximum gain */
1135 rb->audio_set_recording_gain(tuner_settings.record_gain, 1073 rb->audio_set_recording_gain(settings.record_gain,
1136 tuner_settings.record_gain, 1074 settings.record_gain,
1137 AUDIO_GAIN_MIC); 1075 AUDIO_GAIN_MIC);
1138 1076
1139 /* Highest C on piano is approx 4.186 kHz, so we need just over 1077 /* Highest C on piano is approx 4.186 kHz, so we need just over
@@ -1145,15 +1083,15 @@ void init_everything(void)
1145 rb->pcm_init_recording(); 1083 rb->pcm_init_recording();
1146 1084
1147 /* avoid divsion by zero */ 1085 /* avoid divsion by zero */
1148 if(tuner_settings.lowest_freq == 0) 1086 if(settings.lowest_freq == 0)
1149 tuner_settings.lowest_freq = period2freq(BUFFER_SIZE / 4); 1087 settings.lowest_freq = period2freq(BUFFER_SIZE / 4);
1150 1088
1151 /* GUI */ 1089 /* GUI */
1152#if LCD_DEPTH > 1 1090#if LCD_DEPTH > 1
1153 front_color = rb->lcd_get_foreground(); 1091 front_color = rb->lcd_get_foreground();
1154#endif 1092#endif
1155 rb->lcd_getstringsize("X", &font_w, &font_h); 1093 rb->lcd_getstringsize("X", &font_w, &font_h);
1156 1094
1157 bar_x_0 = LCD_WIDTH / 2; 1095 bar_x_0 = LCD_WIDTH / 2;
1158 lbl_x_minus_50 = 0; 1096 lbl_x_minus_50 = 0;
1159 lbl_x_minus_20 = (LCD_WIDTH / 2) - 1097 lbl_x_minus_20 = (LCD_WIDTH / 2) -
@@ -1174,10 +1112,10 @@ void init_everything(void)
1174enum plugin_status plugin_start(const void* parameter) NO_PROF_ATTR 1112enum plugin_status plugin_start(const void* parameter) NO_PROF_ATTR
1175{ 1113{
1176 (void)parameter; 1114 (void)parameter;
1177 1115
1178 init_everything(); 1116 init_everything();
1179 record_and_get_pitch(); 1117 record_and_get_pitch();
1180 save_settings(); 1118 save_settings();
1181 1119
1182 return 0; 1120 return PLUGIN_OK;
1183} 1121}