| @@ -33,10 +33,11 @@ | |||
| * @param source source address | |||
| */ | |||
| static void copy_buffer(void *destination, const void *source) { | |||
| const uint16_t *src = (const uint16_t *)source; | |||
| uint16_t *dst = (uint16_t *)destination; | |||
| for (int i=0; i < AUDIO_BLOCK_SAMPLES; i++) *dst++ = *src++; | |||
| const uint16_t *src = ( const uint16_t * )source; | |||
| uint16_t *dst = ( uint16_t * )destination; | |||
| for (int i=0; i < AUDIO_BLOCK_SAMPLES; i++) *dst++ = (*src++); | |||
| } | |||
| /** | |||
| * Virtual function to override from Audio Library | |||
| */ | |||
| @@ -64,17 +65,21 @@ void AudioAnalyzeNoteFrequency::update( void ) { | |||
| if ( next_buffer ) { | |||
| if ( !first_run && process_buffer ) process( ); | |||
| for ( int i = 0; i < AUDIO_GUITARTUNER_BLOCKS; i++ ) copy_buffer( AudioBuffer+( i * 0x80 ), blocklist1[i]->data ); | |||
| for ( int i = 0; i < AUDIO_GUITARTUNER_BLOCKS; i++ ) release(blocklist1[i] ); | |||
| for ( int i = 0; i < AUDIO_GUITARTUNER_BLOCKS; i++ ) release( blocklist1[i] ); | |||
| next_buffer = false; | |||
| } else { | |||
| if ( !first_run && process_buffer ) process( ); | |||
| for ( int i = 0; i < AUDIO_GUITARTUNER_BLOCKS; i++ ) copy_buffer( AudioBuffer+( i * 0x80 ), blocklist2[i]->data ); | |||
| for ( int i = 0; i < AUDIO_GUITARTUNER_BLOCKS; i++ ) release( blocklist2[i] ); | |||
| next_buffer = true; | |||
| } | |||
| process_buffer = true; | |||
| first_run = false; | |||
| state = 0; | |||
| } | |||
| } | |||
| /** | |||
| * Start the Yin algorithm | |||
| * | |||
| @@ -83,7 +88,7 @@ void AudioAnalyzeNoteFrequency::update( void ) { | |||
| * page 79. Might have to downsample for low fundmental frequencies because of fft buffer | |||
| * size limit. | |||
| */ | |||
| FASTRUN void AudioAnalyzeNoteFrequency::process( void ) { | |||
| void AudioAnalyzeNoteFrequency::process( void ) { | |||
| const int16_t *p; | |||
| p = AudioBuffer; | |||
| @@ -92,27 +97,39 @@ FASTRUN void AudioAnalyzeNoteFrequency::process( void ) { | |||
| uint16_t tau = tau_global; | |||
| do { | |||
| uint16_t x = 0; | |||
| int64_t sum = 0; | |||
| uint64_t sum = 0; | |||
| do { | |||
| int16_t current, lag, delta; | |||
| lag = *( ( int16_t * )p + ( x+tau ) ); | |||
| current = *( ( int16_t * )p+x ); | |||
| delta = ( current-lag ); | |||
| sum += delta * delta; | |||
| #if F_CPU == 144000000 | |||
| x += 8; | |||
| #elif F_CPU == 120000000 | |||
| x += 12; | |||
| #elif F_CPU == 96000000 | |||
| x += 16; | |||
| #elif F_CPU < 96000000 | |||
| x += 32; | |||
| #endif | |||
| } while ( x <= HALF_BLOCKS ); | |||
| x += 4; | |||
| lag = *( ( int16_t * )p + ( x+tau ) ); | |||
| current = *( ( int16_t * )p+x ); | |||
| delta = ( current-lag ); | |||
| sum += delta * delta; | |||
| x += 4; | |||
| lag = *( ( int16_t * )p + ( x+tau ) ); | |||
| current = *( ( int16_t * )p+x ); | |||
| delta = ( current-lag ); | |||
| sum += delta * delta; | |||
| x += 4; | |||
| lag = *( ( int16_t * )p + ( x+tau ) ); | |||
| current = *( ( int16_t * )p+x ); | |||
| delta = ( current-lag ); | |||
| sum += delta * delta; | |||
| x += 4; | |||
| } while ( x < HALF_BLOCKS ); | |||
| running_sum += sum; | |||
| uint64_t rs = running_sum; | |||
| rs += sum; | |||
| yin_buffer[yin_idx] = sum*tau; | |||
| rs_buffer[yin_idx] = running_sum; | |||
| rs_buffer[yin_idx] = rs; | |||
| running_sum = rs; | |||
| yin_idx = ( ++yin_idx >= 5 ) ? 0 : yin_idx; | |||
| tau = estimate( yin_buffer, rs_buffer, yin_idx, tau ); | |||
| @@ -125,7 +142,7 @@ FASTRUN void AudioAnalyzeNoteFrequency::process( void ) { | |||
| return; | |||
| } | |||
| } while ( --cycles ); | |||
| digitalWriteFast(10, LOW); | |||
| if ( tau >= HALF_BLOCKS ) { | |||
| process_buffer = false; | |||
| new_output = false; | |||
| @@ -147,9 +164,9 @@ FASTRUN void AudioAnalyzeNoteFrequency::process( void ) { | |||
| * | |||
| * @return tau | |||
| */ | |||
| uint16_t AudioAnalyzeNoteFrequency::estimate( int64_t *yin, int64_t *rs, uint16_t head, uint16_t tau ) { | |||
| const int64_t *y = ( int64_t * )yin; | |||
| const int64_t *r = ( int64_t * )rs; | |||
| uint16_t AudioAnalyzeNoteFrequency::estimate( uint64_t *yin, uint64_t *rs, uint16_t head, uint16_t tau ) { | |||
| const uint64_t *y = ( uint64_t * )yin; | |||
| const uint64_t *r = ( uint64_t * )rs; | |||
| uint16_t _tau, _head; | |||
| const float thresh = yin_threshold; | |||
| _tau = tau; | |||
| @@ -47,7 +47,7 @@ public: | |||
| * @return none | |||
| */ | |||
| AudioAnalyzeNoteFrequency( void ) : AudioStream( 1, inputQueueArray ), enabled( false ), new_output(false) { | |||
| } | |||
| /** | |||
| @@ -94,7 +94,7 @@ public: | |||
| * @return none | |||
| */ | |||
| virtual void update( void ); | |||
| private: | |||
| /** | |||
| * check the sampled data for fundamental frequency | |||
| @@ -106,7 +106,7 @@ private: | |||
| * | |||
| * @return tau | |||
| */ | |||
| uint16_t estimate( int64_t *yin, int64_t *rs, uint16_t head, uint16_t tau ); | |||
| uint16_t estimate( uint64_t *yin, uint64_t *rs, uint16_t head, uint16_t tau ); | |||
| /** | |||
| * process audio data | |||
| @@ -120,7 +120,8 @@ private: | |||
| */ | |||
| uint64_t running_sum; | |||
| uint16_t tau_global; | |||
| int64_t rs_buffer[5], yin_buffer[5]; | |||
| uint64_t yin_buffer[5]; | |||
| uint64_t rs_buffer[5]; | |||
| int16_t AudioBuffer[AUDIO_GUITARTUNER_BLOCKS*128] __attribute__ ( ( aligned ( 4 ) ) ); | |||
| uint8_t yin_idx, state; | |||
| float periodicity, yin_threshold, cpu_usage_max, data; | |||
| @@ -71,6 +71,8 @@ void setup() { | |||
| */ | |||
| notefreq.begin(.15); | |||
| pinMode(LED_BUILTIN, OUTPUT); | |||
| // Audio library isr allways gets priority | |||
| playNoteTimer.priority(144); | |||
| playNoteTimer.begin(playNote, 1000); | |||
| } | |||
| @@ -1,5 +1,5 @@ | |||
| #include "a2_note.h" | |||
| const unsigned int a2_note[53971] = { | |||
| const unsigned int a2_note[53801] = { | |||
| 0x8100D2D3, 0xFFF7FFFB, 0xFFF7FFF8, 0xFFF3FFF6, 0xFFEDFFEF, 0xFFEAFFEC, 0xFFE6FFE9, 0xFFE0FFE2, 0xFFDAFFDD, 0xFFD5FFD7, 0xFFCFFFD3, | |||
| 0xFFC9FFCB, 0xFFC6FFC9, 0xFFC0FFC4, 0xFFBBFFBD, 0xFFB4FFB7, 0xFFB0FFB0, 0xFFABFFAE, 0xFFA3FFA7, 0xFF9CFFA0, 0xFF99FF9A, 0xFF94FF96, | |||
| 0xFF90FF93, 0xFF8CFF8D, 0xFF85FF89, 0xFF83FF82, 0xFF7DFF80, 0xFF78FF7C, 0xFF75FF77, 0xFF6EFF72, 0xFF6AFF6C, 0xFF69FF6A, 0xFF63FF67, | |||
| @@ -4891,20 +4891,4 @@ | |||
| 0x069F0620, 0x07A10721, 0x08A50822, 0x09B0092A, 0x0AB70A31, 0x0BC50B3D, 0x0CD20C4C, 0x0DDF0D58, 0x0EF00E67, 0x0FFD0F77, 0x1102107F, | |||
| 0x12011184, 0x12FA127F, 0x13E91373, 0x14CC145C, 0x15A4153A, 0x1670160C, 0x172D16D1, 0x17DD1786, 0x1879182E, 0x190118C0, 0x197A193F, | |||
| 0x19E019AF, 0x1A2C1A09, 0x1A5E1A47, 0x1A7B1A70, 0x1A851A81, 0x1A761A81, 0x1A501A66, 0x1A161A35, 0x19CF19F5, 0x197B19A8, 0x191D194D, | |||
| 0x18B518EB, 0x184A187F, 0x17DF1813, 0x177517A9, 0x1708173D, 0x16A016D2, 0x16441671, 0x15EF1617, 0x159F15C5, 0x15521578, 0x15131532, | |||
| 0x14D814F4, 0x149F14BB, 0x146B1485, 0x143B1454, 0x140A1421, 0x13DF13F3, 0x13B213C7, 0x1386139B, 0x135C1370, 0x1338134A, 0x13141326, | |||
| 0x12F31304, 0x12D712E4, 0x12BF12CA, 0x12A412B1, 0x12891295, 0x1274127F, 0x125B126B, 0x123D124D, 0x1220122E, 0x11FC120E, 0x11D411E9, | |||
| 0x11A611BE, 0x1173118D, 0x113A1156, 0x10F81119, 0x10B310D8, 0x1067108E, 0x1013103E, 0x0FC00FE8, 0x0F6A0F96, 0x0F0B0F3C, 0x0EAE0EDE, | |||
| 0x0E510E80, 0x0DF30E24, 0x0D940DC3, 0x0D360D64, 0x0CDA0D07, 0x0C7C0CAA, 0x0C200C4D, 0x0BC80BF5, 0x0B6E0B9D, 0x0B130B41, 0x0ABE0AE7, | |||
| 0x0A650A92, 0x0A0B0A38, 0x09B109DE, 0x09580984, 0x08FB092B, 0x089C08CC, 0x083D086D, 0x07DA080C, 0x077307A6, 0x070D0740, 0x06A006D7, | |||
| 0x062D0667, 0x05B205EE, 0x05320573, 0x04A704EF, 0x040E045E, 0x036A03BE, 0x02B80314, 0x01F30259, 0x011B018A, 0x003200A9, 0xFF33FFB3, | |||
| 0xFE1EFEAA, 0xFCF4FD8B, 0xFBB9FC59, 0xFA6FFB15, 0xF917F9C4, 0xF7B8F868, 0xF650F704, 0xF4E8F59C, 0xF385F436, 0xF228F2D7, 0xF0D3F17E, | |||
| 0xEF8DF02F, 0xEE56EEEF, 0xED2EEDC0, 0xEC16ECA0, 0xEB0DEB90, 0xEA1AEA92, 0xE935E9A6, 0xE85FE8C7, 0xE798E7F8, 0xE6E0E739, 0xE638E68B, | |||
| 0xE59FE5EA, 0xE510E557, 0xE48DE4CE, 0xE418E451, 0xE3ABE3E1, 0xE347E378, 0xE2E8E316, 0xE294E2BE, 0xE247E26D, 0xE1FEE222, 0xE1BEE1DE, | |||
| 0xE181E19E, 0xE14CE164, 0xE11BE133, 0xE0F0E106, 0xE0CBE0DD, 0xE0ADE0BB, 0xE098E0A2, 0xE086E08F, 0xE07DE080, 0xE07EE07C, 0xE089E085, | |||
| 0xE09CE092, 0xE0B8E0A8, 0xE0DCE0C8, 0xE108E0F1, 0xE141E122, 0xE180E15F, 0xE1C7E1A1, 0xE216E1EC, 0xE271E243, 0xE2D5E2A2, 0xE341E30A, | |||
| 0xE3C0E37E, 0xE449E403, 0xE4E0E494, 0xE581E52E, 0xE632E5D7, 0xE6EEE68F, 0xE7B6E751, 0xE88BE820, 0xE969E8F8, 0xEA4CE9D9, 0xEB39EAC2, | |||
| 0xEC2FEBB2, 0xED26ECA9, 0xEE21EDA3, 0xEF23EEA2, 0xF029EFA8, 0xF12FF0AD, 0xF23CF1B5, 0xF34CF2C4, 0xF461F3D7, 0xF577F4EC, 0xF693F605, | |||
| 0xF7ACF71D, 0xF8CAF83B, 0xF9E7F957, 0xFB04FA76, 0xFC1DFB91, 0xFD33FCA8, 0xFE49FDBE, 0xFF57FED1, 0x005FFFDC, 0x016A00E5, 0x026D01EB, | |||
| 0x036C02EC, 0x046A03EB, 0x056904EA, 0x066805E8, 0x076506E7, | |||
| }; | |||
| @@ -1,2 +1,2 @@ | |||
| #include "Arduino.h" | |||
| extern const unsigned int a2_note[53971]; | |||
| extern const unsigned int a2_note[53801]; | |||
| @@ -1,2 +1,2 @@ | |||
| #include "Arduino.h" | |||
| extern const unsigned int b3_note[53990]; | |||
| extern const unsigned int b3_note[53823]; | |||
| @@ -1,2 +1,2 @@ | |||
| #include "Arduino.h" | |||
| extern const unsigned int d3_note[53974]; | |||
| extern const unsigned int d3_note[53801]; | |||
| @@ -1,2 +1,2 @@ | |||
| #include "Arduino.h" | |||
| extern const unsigned int e2_note[53990]; | |||
| extern const unsigned int e2_note[53636]; | |||
| @@ -1,2 +1,2 @@ | |||
| #include "Arduino.h" | |||
| extern const unsigned int e4_note[53990]; | |||
| extern const unsigned int e4_note[53823]; | |||
| @@ -1,2 +1,2 @@ | |||
| #include "Arduino.h" | |||
| extern const unsigned int g3_note[53965]; | |||
| extern const unsigned int g3_note[53790]; | |||