|
|
|
|
|
|
|
|
const int16_t *p, *end; |
|
|
const int16_t *p, *end; |
|
|
block = receiveReadOnly( ); |
|
|
block = receiveReadOnly( ); |
|
|
if ( !block ) return; |
|
|
if ( !block ) return; |
|
|
|
|
|
|
|
|
if ( !enabled ) { |
|
|
if ( !enabled ) { |
|
|
release( block ); |
|
|
release( block ); |
|
|
return; |
|
|
return; |
|
|
|
|
|
|
|
|
yin_buffer[yin_idx] = sum*tau; |
|
|
yin_buffer[yin_idx] = sum*tau; |
|
|
rs_buffer[yin_idx] = running_sum; |
|
|
rs_buffer[yin_idx] = running_sum; |
|
|
yin_idx = ( ++yin_idx >= 5 ) ? 0 : yin_idx; |
|
|
yin_idx = ( ++yin_idx >= 5 ) ? 0 : yin_idx; |
|
|
|
|
|
|
|
|
tau = estimate( yin_buffer, rs_buffer, yin_idx, tau ); |
|
|
tau = estimate( yin_buffer, rs_buffer, yin_idx, tau ); |
|
|
|
|
|
|
|
|
if ( tau == 0 ) { |
|
|
if ( tau == 0 ) { |
|
|
process_buffer = false; |
|
|
process_buffer = false; |
|
|
new_output = true; |
|
|
new_output = true; |
|
|
|
|
|
|
|
|
//digitalWriteFast(0, LOW); |
|
|
//digitalWriteFast(0, LOW); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} while ( tau <= ( tau_global + 31 ) ); |
|
|
} while ( tau <= ( tau_global + 31 ) ); |
|
|
tau_global = tau; |
|
|
tau_global = tau; |
|
|
//digitalWriteFast(0, LOW); |
|
|
//digitalWriteFast(0, LOW); |
|
|
|
|
|
|
|
|
uint16_t AudioTuner::estimate( int64_t *yin, int64_t *rs, uint16_t head, uint16_t tau ) { |
|
|
uint16_t AudioTuner::estimate( int64_t *yin, int64_t *rs, uint16_t head, uint16_t tau ) { |
|
|
const int64_t *p = ( int64_t * )yin; |
|
|
const int64_t *p = ( int64_t * )yin; |
|
|
const int64_t *r = ( int64_t * )rs; |
|
|
const int64_t *r = ( int64_t * )rs; |
|
|
uint16_t period = 0, _tau, _head; |
|
|
|
|
|
|
|
|
uint16_t _tau, _head; |
|
|
_tau = tau; |
|
|
_tau = tau; |
|
|
_head = head; |
|
|
_head = head; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
s2 = ( ( float )*( p+idx2 ) / r[idx2] ); |
|
|
s2 = ( ( float )*( p+idx2 ) / r[idx2] ); |
|
|
|
|
|
|
|
|
if ( s1 < threshold && s1 < s2 ) { |
|
|
if ( s1 < threshold && s1 < s2 ) { |
|
|
period = _tau - 3; |
|
|
|
|
|
|
|
|
uint16_t period = _tau - 3; |
|
|
periodicity = 1 - s1; |
|
|
periodicity = 1 - s1; |
|
|
data = period + 0.5f * ( s0 - s2 ) / ( s0 - 2.0f * s1 + s2 ); |
|
|
data = period + 0.5f * ( s0 - s2 ) / ( s0 - 2.0f * s1 + s2 ); |
|
|
return 0; |
|
|
return 0; |
|
|
|
|
|
|
|
|
float AudioTuner::read( void ) { |
|
|
float AudioTuner::read( void ) { |
|
|
return SAMPLE_RATE / data; |
|
|
return SAMPLE_RATE / data; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Periodicity of the sampled signal from Yin algorithm from read function. |
|
|
* Periodicity of the sampled signal from Yin algorithm from read function. |
|
|
* |
|
|
* |
|
|
|
|
|
|
|
|
float AudioTuner::probability( void ) { |
|
|
float AudioTuner::probability( void ) { |
|
|
return periodicity; |
|
|
return periodicity; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Initialise parameters. |
|
|
* Initialise parameters. |
|
|
* |
|
|
* |
|
|
* @param thresh Allowed uncertainty |
|
|
* @param thresh Allowed uncertainty |
|
|
*/ |
|
|
*/ |
|
|
void AudioTuner::set_params( float thresh ) { |
|
|
|
|
|
|
|
|
void AudioTuner::set_threshold( float thresh ) { |
|
|
__disable_irq( ); |
|
|
__disable_irq( ); |
|
|
//arm_cfft_radix4_init_q15(&fft_inst, 1024, 0, 1); |
|
|
|
|
|
//arm_cfft_radix4_init_q15(&ifft_inst, 1024, 1, 1); |
|
|
|
|
|
threshold = thresh; |
|
|
threshold = thresh; |
|
|
periodicity = 0.0f; |
|
|
|
|
|
block_count = 0; |
|
|
|
|
|
enabled = true; |
|
|
|
|
|
__enable_irq( ); |
|
|
|
|
|
|
|
|
process_buffer = false; |
|
|
|
|
|
periodicity = 0.0f; |
|
|
|
|
|
next_buffer = 1; |
|
|
|
|
|
running_sum = 0; |
|
|
|
|
|
block_count = 0; |
|
|
|
|
|
block_count = 0; |
|
|
|
|
|
yin_idx = 1; |
|
|
|
|
|
data = 0; |
|
|
|
|
|
__enable_irq( ); |
|
|
} |
|
|
} |