@@ -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]; |