Fixed HighlyComplete silence detection to handle DC offset silence
parent
d898cf4f71
commit
00c13ec061
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue