mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-07-24 13:12:03 +00:00
FS-3486 --resolve update silk
This commit is contained in:
+107
-58
@@ -1,5 +1,5 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2010, Skype Limited. All rights reserved.
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, (subject to the limitations in the disclaimer below)
|
||||
are permitted provided that the following conditions are met:
|
||||
@@ -25,6 +25,7 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
/*****************************/
|
||||
/* Silk encoder test program */
|
||||
/*****************************/
|
||||
@@ -44,43 +45,70 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#define MAX_INPUT_FRAMES 5
|
||||
#define MAX_LBRR_DELAY 2
|
||||
#define MAX_FRAME_LENGTH 480
|
||||
#define FRAME_LENGTH_MS 20
|
||||
#define MAX_API_FS_KHZ 48
|
||||
|
||||
#ifdef _SYSTEM_IS_BIG_ENDIAN
|
||||
/* Function to convert a little endian int16 to a */
|
||||
/* big endian int16 or vica verca */
|
||||
void swap_endian(
|
||||
SKP_int16 vec[], /* I/O array of */
|
||||
SKP_int len /* I length */
|
||||
)
|
||||
{
|
||||
SKP_int i;
|
||||
SKP_int16 tmp;
|
||||
SKP_uint8 *p1, *p2;
|
||||
|
||||
for( i = 0; i < len; i++ ){
|
||||
tmp = vec[ i ];
|
||||
p1 = (SKP_uint8 *)&vec[ i ]; p2 = (SKP_uint8 *)&tmp;
|
||||
p1[ 0 ] = p2[ 1 ]; p1[ 1 ] = p2[ 0 ];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void print_usage( char* argv[] ) {
|
||||
printf( "\nusage: %s in.pcm out.bit [settings]\n", argv[ 0 ] );
|
||||
printf( "\nin.pcm : Speech input to encoder" );
|
||||
printf( "\nout.bit : Bitstream output from encoder" );
|
||||
printf( "\nin.pcm : Speech input to encoder" );
|
||||
printf( "\nstream.bit : Bitstream output from encoder" );
|
||||
printf( "\n settings:" );
|
||||
printf( "\n-fs <kHz> : Sampling rate in kHz, default: 24" );
|
||||
printf( "\n-packetlength <ms> : Packet interval in ms, default: 20" );
|
||||
printf( "\n-rate <bps> : Target bitrate; default: 25000" );
|
||||
printf( "\n-loss <perc> : Uplink loss estimate, in percent (0-100); default: 0" );
|
||||
printf( "\n-inbandFEC <flag> : Enable inband FEC usage (0/1); default: 0" );
|
||||
printf( "\n-complexity <comp> : Set complexity, 0: low, 1: medium, 2: high; default: 2" );
|
||||
printf( "\n-DTX <flag> : Enable DTX (0/1); default: 0" );
|
||||
printf( "\n-quiet : Print only some basic values" );
|
||||
printf( "\n-Fs_API <Hz> : API sampling rate in Hz, default: 24000" );
|
||||
printf( "\n-Fs_maxInternal <Hz> : Maximum internal sampling rate in Hz, default: 24000" );
|
||||
printf( "\n-packetlength <ms> : Packet interval in ms, default: 20" );
|
||||
printf( "\n-rate <bps> : Target bitrate; default: 25000" );
|
||||
printf( "\n-loss <perc> : Uplink loss estimate, in percent (0-100); default: 0" );
|
||||
printf( "\n-inbandFEC <flag> : Enable inband FEC usage (0/1); default: 0" );
|
||||
printf( "\n-complexity <comp> : Set complexity, 0: low, 1: medium, 2: high; default: 2" );
|
||||
printf( "\n-DTX <flag> : Enable DTX (0/1); default: 0" );
|
||||
printf( "\n-quiet : Print only some basic values" );
|
||||
printf( "\n");
|
||||
}
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
size_t counter;
|
||||
SKP_int k, args, totPackets, totActPackets, ret;
|
||||
SKP_int32 k, args, totPackets, totActPackets, ret;
|
||||
SKP_int16 nBytes;
|
||||
double sumBytes, sumWBytes, sumActBytes, avg_rate, act_rate, wght_rate, nrg;
|
||||
double sumBytes, sumActBytes, avg_rate, act_rate, nrg;
|
||||
SKP_uint8 payload[ MAX_BYTES_PER_FRAME * MAX_INPUT_FRAMES ];
|
||||
SKP_int16 in[ MAX_FRAME_LENGTH * MAX_INPUT_FRAMES ];
|
||||
SKP_int16 in[ FRAME_LENGTH_MS * MAX_API_FS_KHZ * MAX_INPUT_FRAMES ];
|
||||
char speechInFileName[ 150 ], bitOutFileName[ 150 ];
|
||||
FILE *bitOutFile, *speechInFile;
|
||||
SKP_int32 encSizeBytes;
|
||||
void *psEnc;
|
||||
#ifdef _SYSTEM_IS_BIG_ENDIAN
|
||||
SKP_int16 nBytes_LE;
|
||||
#endif
|
||||
|
||||
/* default settings */
|
||||
SKP_int fs_kHz = 24;
|
||||
SKP_int targetRate_bps = 25000;
|
||||
SKP_int packetSize_ms = 20;
|
||||
SKP_int frameSizeReadFromFile_ms = 20;
|
||||
SKP_int packetLoss_perc = 0, complexity_mode = 2, smplsSinceLastPacket;
|
||||
SKP_int INBandFec_enabled = 0, DTX_enabled = 0, quiet = 0;
|
||||
SKP_int32 API_fs_Hz = 24000;
|
||||
SKP_int32 max_internal_fs_Hz = 0;
|
||||
SKP_int32 targetRate_bps = 25000;
|
||||
SKP_int32 packetSize_ms = 20;
|
||||
SKP_int32 frameSizeReadFromFile_ms = 20;
|
||||
SKP_int32 packetLoss_perc = 0, complexity_mode = 2, smplsSinceLastPacket;
|
||||
SKP_int32 INBandFEC_enabled = 0, DTX_enabled = 0, quiet = 0;
|
||||
SKP_SILK_SDK_EncControlStruct encControl; // Struct for input to encoder
|
||||
|
||||
if( argc < 3 ) {
|
||||
@@ -95,8 +123,11 @@ int main( int argc, char* argv[] )
|
||||
strcpy( bitOutFileName, argv[ args ] );
|
||||
args++;
|
||||
while( args < argc ) {
|
||||
if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-fs" ) == 0 ) {
|
||||
sscanf( argv[ args + 1 ], "%d", &fs_kHz );
|
||||
if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-Fs_API" ) == 0 ) {
|
||||
sscanf( argv[ args + 1 ], "%d", &API_fs_Hz );
|
||||
args += 2;
|
||||
} else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-Fs_maxInternal" ) == 0 ) {
|
||||
sscanf( argv[ args + 1 ], "%d", &max_internal_fs_Hz );
|
||||
args += 2;
|
||||
} else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-packetlength" ) == 0 ) {
|
||||
sscanf( argv[ args + 1 ], "%d", &packetSize_ms );
|
||||
@@ -111,7 +142,7 @@ int main( int argc, char* argv[] )
|
||||
sscanf( argv[ args + 1 ], "%d", &complexity_mode );
|
||||
args += 2;
|
||||
} else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-inbandFEC" ) == 0 ) {
|
||||
sscanf( argv[ args + 1 ], "%d", &INBandFec_enabled );
|
||||
sscanf( argv[ args + 1 ], "%d", &INBandFEC_enabled );
|
||||
args += 2;
|
||||
} else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-DTX") == 0 ) {
|
||||
sscanf( argv[ args + 1 ], "%d", &DTX_enabled );
|
||||
@@ -126,18 +157,27 @@ int main( int argc, char* argv[] )
|
||||
}
|
||||
}
|
||||
|
||||
/* If no max internal is specified, set to minimum of API fs and 24 kHz */
|
||||
if( max_internal_fs_Hz == 0 ) {
|
||||
max_internal_fs_Hz = 24000;
|
||||
if( API_fs_Hz < max_internal_fs_Hz ) {
|
||||
max_internal_fs_Hz = API_fs_Hz;
|
||||
}
|
||||
}
|
||||
|
||||
/* Print options */
|
||||
if( !quiet ) {
|
||||
printf("******************* Silk Encoder v %s ****************\n", SKP_Silk_SDK_get_version());
|
||||
printf("******************* Compiled for %d bit cpu ********* \n", (int)sizeof(void*) * 8 );
|
||||
printf( "Input: %s\n", speechInFileName );
|
||||
printf( "Output: %s\n", bitOutFileName );
|
||||
printf( "Sampling rate: %d kHz\n", fs_kHz);
|
||||
printf( "Packet interval: %d ms\n", packetSize_ms);
|
||||
printf( "Inband FEC used: %d\n", INBandFec_enabled);
|
||||
printf( "DTX used: %d\n", DTX_enabled);
|
||||
printf( "Complexity: %d\n", complexity_mode);
|
||||
printf( "Target bitrate: %d bps\n", targetRate_bps);
|
||||
printf( "Input: %s\n", speechInFileName );
|
||||
printf( "Output: %s\n", bitOutFileName );
|
||||
printf( "API sampling rate: %d Hz\n", API_fs_Hz );
|
||||
printf( "Maximum internal sampling rate: %d Hz\n", max_internal_fs_Hz );
|
||||
printf( "Packet interval: %d ms\n", packetSize_ms );
|
||||
printf( "Inband FEC used: %d\n", INBandFEC_enabled );
|
||||
printf( "DTX used: %d\n", DTX_enabled );
|
||||
printf( "Complexity: %d\n", complexity_mode );
|
||||
printf( "Target bitrate: %d bps\n", targetRate_bps );
|
||||
}
|
||||
|
||||
/* Open files */
|
||||
@@ -152,6 +192,12 @@ int main( int argc, char* argv[] )
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
/* Add Silk header to stream */
|
||||
{
|
||||
static const char Silk_header[] = "#!SILK_V3";
|
||||
fwrite( Silk_header, sizeof( char ), strlen( Silk_header ), bitOutFile );
|
||||
}
|
||||
|
||||
/* Create Encoder */
|
||||
ret = SKP_Silk_SDK_Get_Encoder_Size( &encSizeBytes );
|
||||
if( ret ) {
|
||||
@@ -159,7 +205,7 @@ int main( int argc, char* argv[] )
|
||||
}
|
||||
|
||||
psEnc = malloc( encSizeBytes );
|
||||
|
||||
|
||||
/* Reset Encoder */
|
||||
ret = SKP_Silk_SDK_InitEncoder( psEnc, &encControl );
|
||||
if( ret ) {
|
||||
@@ -167,16 +213,17 @@ int main( int argc, char* argv[] )
|
||||
}
|
||||
|
||||
/* Set Encoder parameters */
|
||||
encControl.sampleRate = fs_kHz * 1000;
|
||||
encControl.packetSize = packetSize_ms * fs_kHz;
|
||||
encControl.packetLossPercentage = packetLoss_perc;
|
||||
encControl.useInBandFEC = INBandFec_enabled;
|
||||
encControl.useDTX = DTX_enabled;
|
||||
encControl.complexity = complexity_mode;
|
||||
encControl.bitRate = targetRate_bps;
|
||||
encControl.API_sampleRate = API_fs_Hz;
|
||||
encControl.maxInternalSampleRate = max_internal_fs_Hz;
|
||||
encControl.packetSize = ( packetSize_ms * API_fs_Hz ) / 1000;
|
||||
encControl.packetLossPercentage = packetLoss_perc;
|
||||
encControl.useInBandFEC = INBandFEC_enabled;
|
||||
encControl.useDTX = DTX_enabled;
|
||||
encControl.complexity = complexity_mode;
|
||||
encControl.bitRate = ( targetRate_bps > 0 ? targetRate_bps : 0 );
|
||||
|
||||
if( fs_kHz > 24 || fs_kHz < 0 ) {
|
||||
printf( "\nError: Sampling rate = %d out of range, valid range 8 - 24 \n \n", fs_kHz );
|
||||
if( API_fs_Hz > MAX_API_FS_KHZ * 1000 || API_fs_Hz < 0 ) {
|
||||
printf( "\nError: API sampling rate = %d out of range, valid range 8000 - 48000 \n \n", API_fs_Hz );
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
@@ -185,12 +232,14 @@ int main( int argc, char* argv[] )
|
||||
smplsSinceLastPacket = 0;
|
||||
sumBytes = 0.0;
|
||||
sumActBytes = 0.0;
|
||||
sumWBytes = 0.0;
|
||||
|
||||
while( 1 ) {
|
||||
/* Read input to file */
|
||||
counter = fread( in, sizeof( SKP_int16 ), frameSizeReadFromFile_ms * fs_kHz, speechInFile );
|
||||
if( (SKP_int)counter < frameSizeReadFromFile_ms * fs_kHz ) {
|
||||
/* Read input from file */
|
||||
counter = fread( in, sizeof( SKP_int16 ), ( frameSizeReadFromFile_ms * API_fs_Hz ) / 1000, speechInFile );
|
||||
#ifdef _SYSTEM_IS_BIG_ENDIAN
|
||||
swap_endian( in, counter );
|
||||
#endif
|
||||
if( (SKP_int)counter < ( ( frameSizeReadFromFile_ms * API_fs_Hz ) / 1000 ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -205,28 +254,33 @@ int main( int argc, char* argv[] )
|
||||
}
|
||||
|
||||
/* Get packet size */
|
||||
packetSize_ms = (SKP_int)( 1000 * encControl.packetSize ) / encControl.sampleRate;
|
||||
packetSize_ms = ( SKP_int )( ( 1000 * ( SKP_int32 )encControl.packetSize ) / encControl.API_sampleRate );
|
||||
|
||||
smplsSinceLastPacket += (SKP_int)counter;
|
||||
smplsSinceLastPacket += ( SKP_int )counter;
|
||||
|
||||
if( ( smplsSinceLastPacket / fs_kHz ) == packetSize_ms ) {
|
||||
if( ( ( 1000 * smplsSinceLastPacket ) / API_fs_Hz ) == packetSize_ms ) {
|
||||
/* Sends a dummy zero size packet in case of DTX period */
|
||||
/* to make it work with the decoder test program. */
|
||||
/* In practice should be handled by RTP sequence numbers */
|
||||
totPackets++;
|
||||
sumBytes += nBytes;
|
||||
sumWBytes += pow( (double)nBytes, 10.0 );
|
||||
nrg = 0.0;
|
||||
for( k = 0; k < (SKP_int)counter; k++ ) {
|
||||
for( k = 0; k < ( SKP_int )counter; k++ ) {
|
||||
nrg += in[ k ] * (double)in[ k ];
|
||||
}
|
||||
if( ( nrg / (SKP_int)counter ) > 1e3 ) {
|
||||
if( ( nrg / ( SKP_int )counter ) > 1e3 ) {
|
||||
sumActBytes += nBytes;
|
||||
totActPackets++;
|
||||
}
|
||||
|
||||
/* Write payload size */
|
||||
#ifdef _SYSTEM_IS_BIG_ENDIAN
|
||||
nBytes_LE = nBytes;
|
||||
swap_endian( &nBytes_LE, 1 );
|
||||
fwrite( &nBytes_LE, sizeof( SKP_int16 ), 1, bitOutFile );
|
||||
#else
|
||||
fwrite( &nBytes, sizeof( SKP_int16 ), 1, bitOutFile );
|
||||
#endif
|
||||
|
||||
/* Write payload */
|
||||
fwrite( payload, sizeof( SKP_uint8 ), nBytes, bitOutFile );
|
||||
@@ -244,9 +298,6 @@ int main( int argc, char* argv[] )
|
||||
/* Write payload size */
|
||||
fwrite( &nBytes, sizeof( SKP_int16 ), 1, bitOutFile );
|
||||
|
||||
/* Query encoder */
|
||||
packetSize_ms = (SKP_int)( 1000 * encControl.packetSize ) / encControl.sampleRate;
|
||||
|
||||
/* Free Encoder */
|
||||
free( psEnc );
|
||||
|
||||
@@ -255,15 +306,13 @@ int main( int argc, char* argv[] )
|
||||
|
||||
avg_rate = 8.0 / packetSize_ms * sumBytes / totPackets;
|
||||
act_rate = 8.0 / packetSize_ms * sumActBytes / totActPackets;
|
||||
wght_rate = 8.0 / packetSize_ms * pow( sumWBytes / totPackets, 0.1 );
|
||||
if( !quiet ) {
|
||||
printf( "\nAverage bitrate: %.3f kbps", avg_rate );
|
||||
printf( "\nActive bitrate: %.3f kbps", act_rate );
|
||||
printf( "\nWeighted bitrate: %.3f kbps", wght_rate );
|
||||
printf( "\n\n" );
|
||||
} else {
|
||||
/* print average and weighted bitrates */
|
||||
printf( "%.3f %.3f %.3f \n", avg_rate, act_rate, wght_rate );
|
||||
/* print average and active bitrates */
|
||||
printf( "%.3f %.3f \n", avg_rate, act_rate );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user