@ -164,3 +164,155 @@ void AudioEffectModulatedDelay::update(void)
release ( block ) ;
}
}
boolean AudioEffectModulatedDelayStereo : : begin ( short * delayline_l , short * delayline_r , uint16_t d_length )
{
#if 0
Serial . print ( F ( " AudioEffectModulatedDelayStereo.begin(modulated-delay line length = " ) ) ;
Serial . print ( d_length ) ;
Serial . println ( F ( " ) " ) ) ;
# endif
_delay_length = 0 ;
_delayline [ 0 ] = NULL ;
_cb_index [ 0 ] = 0 ;
_delay_offset [ 0 ] = 0 ;
_delayline [ 1 ] = NULL ;
_cb_index [ 1 ] = 0 ;
_delay_offset [ 1 ] = 0 ;
if ( delayline_r = = NULL )
return ( false ) ;
if ( delayline_l = = NULL )
return ( false ) ;
if ( d_length < 10 )
return ( false ) ;
_delay_length = d_length ;
_delayline [ 0 ] = delayline_l ;
memset ( _delayline [ 0 ] , 0 , _delay_length * sizeof ( int16_t ) ) ;
_delay_offset [ 0 ] = _delay_length > > 1 ;
_delayline [ 1 ] = delayline_r ;
memset ( _delayline [ 1 ] , 0 , _delay_length * sizeof ( int16_t ) ) ;
_delay_offset [ 1 ] = _delay_length > > 1 ;
return ( true ) ;
}
uint16_t AudioEffectModulatedDelayStereo : : get_delay_length ( void )
{
return ( _delay_length ) ;
}
void AudioEffectModulatedDelayStereo : : update ( void )
{
audio_block_t * block [ 2 ] ;
audio_block_t * modulation ;
if ( _delayline = = NULL )
return ;
block [ 0 ] = receiveWritable ( 0 ) ;
if ( ! block [ 0 ] )
block [ 0 ] = ( audio_block_t * ) & zeroblock ;
block [ 1 ] = receiveWritable ( 1 ) ;
if ( ! block [ 1 ] )
block [ 1 ] = ( audio_block_t * ) & zeroblock ;
modulation = receiveReadOnly ( 2 ) ;
if ( ! modulation )
modulation = ( audio_block_t * ) & zeroblock ;
if ( block [ 0 ] & & block [ 1 ] & & modulation )
{
int16_t * bp [ 2 ] ;
int16_t cb_mod_index_neighbor [ 2 ] ;
float * mp ;
float mod_index ;
float mod_number ;
float mod_fraction ;
float modulation_f32 [ AUDIO_BLOCK_SAMPLES ] ;
bp [ 0 ] = block [ 0 ] - > data ;
bp [ 1 ] = block [ 1 ] - > data ;
arm_q15_to_float ( modulation - > data , modulation_f32 , AUDIO_BLOCK_SAMPLES ) ;
mp = modulation_f32 ;
for ( uint16_t i = 0 ; i < AUDIO_BLOCK_SAMPLES ; i + + )
{
// LEFT
// calculate the modulation-index as a floating point number for interpolation
mod_index = * mp * _delay_offset [ 0 ] ;
mod_fraction = modff ( mod_index , & mod_number ) ; // split float of mod_index into integer (= mod_number) and fraction part
// write data into circular buffer (delayline)
if ( _cb_index [ 0 ] > = _delay_length )
_cb_index [ 0 ] = 0 ;
_delayline [ 0 ] [ _cb_index [ 0 ] ] = * bp [ 0 ] ;
// calculate modulation index into circular buffer
cb_mod_index [ 0 ] = _cb_index [ 0 ] - ( _delay_offset [ 0 ] + mod_number ) ;
if ( cb_mod_index [ 0 ] < 0 ) // check for negative offsets and correct them
cb_mod_index [ 0 ] + = _delay_length ;
if ( cb_mod_index [ 0 ] = = _delay_length - 1 )
cb_mod_index_neighbor [ 0 ] = 0 ;
else
cb_mod_index_neighbor [ 0 ] = cb_mod_index [ 0 ] + 1 ;
* bp [ 0 ] = round ( float ( _delayline [ 0 ] [ cb_mod_index [ 0 ] ] ) * mod_fraction + float ( _delayline [ 0 ] [ cb_mod_index_neighbor [ 0 ] ] ) * ( 1.0 - mod_fraction ) ) ;
// push the pointers forward
bp [ 0 ] + + ; // next audio data
_cb_index [ 0 ] + + ; // next circular buffer index
// RIGHT
// calculate the modulation-index as a floating point number for interpolation
mod_index = - 1.0 * * mp * _delay_offset [ 0 ] ;
mod_fraction = modff ( mod_index , & mod_number ) ; // split float of mod_index into integer (= mod_number) and fraction part
// write data into circular buffer (delayline)
if ( _cb_index [ 1 ] > = _delay_length )
_cb_index [ 1 ] = 0 ;
_delayline [ 1 ] [ _cb_index [ 1 ] ] = * bp [ 1 ] ;
// calculate modulation index into circular buffer
cb_mod_index [ 1 ] = _cb_index [ 1 ] - ( _delay_offset [ 1 ] + mod_number ) ;
if ( cb_mod_index [ 1 ] < 0 ) // check for negative offsets and correct them
cb_mod_index [ 1 ] + = _delay_length ;
if ( cb_mod_index [ 1 ] = = _delay_length - 1 )
cb_mod_index_neighbor [ 1 ] = 0 ;
else
cb_mod_index_neighbor [ 1 ] = cb_mod_index [ 1 ] + 1 ;
* bp [ 1 ] = round ( float ( _delayline [ 1 ] [ cb_mod_index [ 1 ] ] ) * mod_fraction + float ( _delayline [ 1 ] [ cb_mod_index_neighbor [ 1 ] ] ) * ( 1.0 - mod_fraction ) ) ;
// push the pointers forward
bp [ 1 ] + + ; // next audio data
_cb_index [ 1 ] + + ; // next circular buffer index
mp + + ; // next modulation data
}
}
if ( modulation ! = ( audio_block_t * ) & zeroblock )
release ( modulation ) ;
if ( block [ 0 ] ! = ( audio_block_t * ) & zeroblock )
{
transmit ( block [ 0 ] , 0 ) ;
release ( block [ 0 ] ) ;
}
if ( block [ 1 ] ! = ( audio_block_t * ) & zeroblock )
{
transmit ( block [ 1 ] , 0 ) ;
release ( block [ 1 ] ) ;
}
}