Fixed HighlyComplete silence detection to handle DC offset silence

CQTexperiment
Chris Moeller 2013-11-01 16:57:07 -07:00
parent d898cf4f71
commit 00c13ec061
2 changed files with 55 additions and 16 deletions

View File

@ -1101,7 +1101,7 @@ static int twosf_info(void * context, const char * name, const char * value)
if (![self fillBuffer])
return NO;
silence_test_buffer.remove_leading_silence(1);
silence_test_buffer.remove_leading_silence();
return YES;
}

View File

@ -4,7 +4,7 @@
#include <algorithm>
#include <vector>
long const silence_threshold = 64;
long const silence_threshold = 8;
template <typename T>
class circular_buffer
@ -12,8 +12,14 @@ class circular_buffer
std::vector<T> buffer;
unsigned long readptr, writeptr, used, size;
unsigned long silence_count;
T last_written[2];
T last_read[2];
public:
circular_buffer() : readptr( 0 ), writeptr( 0 ), size( 0 ), used( 0 ), silence_count( 0 ) { }
circular_buffer() : readptr( 0 ), writeptr( 0 ), size( 0 ), used( 0 ), silence_count( 0 )
{
memset( last_written, 0, sizeof(last_written) );
memset( last_read, 0, sizeof(last_read) );
}
unsigned long data_available() { return used; }
unsigned long free_space() { return size - used; }
T* get_write_ptr( unsigned long & count_out )
@ -27,7 +33,7 @@ public:
unsigned long max_count = size - writeptr;
if ( max_count > size - used ) max_count = size - used;
if ( count > max_count ) return false;
silence_count += count_silent( &buffer[ 0 ] + writeptr, &buffer[ 0 ] + writeptr + count );
silence_count += count_silent( &buffer[ 0 ] + writeptr, &buffer[ 0 ] + writeptr + count, last_written );
used += count;
writeptr = ( writeptr + count ) % size;
return true;
@ -43,7 +49,7 @@ public:
if ( !delta ) break;
if ( dst ) std::copy( buffer.begin() + readptr, buffer.begin() + readptr + delta, dst );
silence_count -= count_silent( &buffer[ 0 ] + readptr, &buffer[ 0 ] + readptr + delta );
silence_count -= count_silent( &buffer[ 0 ] + readptr, &buffer[ 0 ] + readptr + delta, last_read );
if ( dst ) dst += delta;
done += delta;
readptr = ( readptr + delta ) % size;
@ -55,6 +61,8 @@ public:
void reset()
{
readptr = writeptr = used = 0;
memset( last_written, 0, sizeof(last_written) );
memset( last_read, 0, sizeof(last_read) );
}
void resize(unsigned long p_size)
{
@ -66,27 +74,47 @@ public:
{
return silence_count == used;
}
void remove_leading_silence( unsigned long mask )
void remove_leading_silence()
{
T const* p;
T const* begin;
T const* end;
mask = ~mask;
if ( used )
{
p = ( begin = &buffer[ 0 ] + readptr ) - 1;
long delta[ 2 ];
p = begin = &buffer[ 0 ] + readptr;
end = &buffer[ 0 ] + ( writeptr > readptr ? writeptr : size );
while ( ++p < end && ( ( unsigned long ) ( *p + silence_threshold ) <= ( unsigned long ) silence_threshold * 2 ) );
unsigned long skipped = ( p - begin ) & mask;
while ( p < end )
{
delta[ 0 ] = p[ 0 ] - last_read[ 0 ];
delta[ 1 ] = p[ 1 ] - last_read[ 1 ];
if ( ( (unsigned long)( delta[ 0 ] + silence_threshold ) > ( unsigned long ) silence_threshold * 2 ) ||
( ( unsigned long )( delta[ 1 ] + silence_threshold ) > ( unsigned long ) silence_threshold * 2 ) )
break;
last_read[ 0 ] += (T) delta[ 0 ];
last_read[ 1 ] += (T) delta[ 1 ];
p += 2;
}
unsigned long skipped = p - begin;
silence_count -= skipped;
used -= skipped;
readptr = ( readptr + skipped ) % size;
if ( readptr == 0 && readptr != writeptr )
{
p = ( begin = &buffer[ 0 ] ) - 1;
p = begin = &buffer[ 0 ];
end = &buffer[ 0 ] + writeptr;
while ( ++p < end && ( ( unsigned long ) ( *p + silence_threshold ) <= ( unsigned long ) silence_threshold * 2 ) );
skipped = ( p - begin ) & mask;
while ( p < end )
{
delta[ 0 ] = p[ 0 ] - last_read[ 0 ];
delta[ 1 ] = p[ 1 ] - last_read[ 1 ];
if ( ( (unsigned long)( delta[ 0 ] + silence_threshold ) > ( unsigned long ) silence_threshold * 2 ) ||
( ( unsigned long )( delta[ 1 ] + silence_threshold ) > ( unsigned long ) silence_threshold * 2 ) )
break;
last_read[ 0 ] += (T) delta[ 0 ];
last_read[ 1 ] += (T) delta[ 1 ];
p += 2;
}
skipped = p - begin;
silence_count -= skipped;
used -= skipped;
readptr += skipped;
@ -94,11 +122,22 @@ public:
}
}
private:
static unsigned long count_silent(T const* begin, T const* end)
static unsigned long count_silent(T const* begin, T const* end, T * last)
{
unsigned long count = 0;
T const* p = begin - 1;
while ( ++p < end ) count += ( ( unsigned long ) ( *p + silence_threshold ) <= ( unsigned long ) silence_threshold * 2 );
T const* p = begin;
long delta[ 2 ];
while ( p < end )
{
delta[ 0 ] = p[ 0 ] - last[ 0 ];
delta[ 1 ] = p[ 1 ] - last[ 1 ];
if ( ( (unsigned long)( delta[ 0 ] + silence_threshold ) <= ( unsigned long ) silence_threshold * 2 ) ||
( ( unsigned long )( delta[ 1 ] + silence_threshold ) <= ( unsigned long ) silence_threshold * 2 ) )
count += 2;
last[ 0 ] += (T) delta[ 0 ];
last[ 1 ] += (T) delta[ 1 ];
p += 2;
}
return count;
}
};