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