#ifdef _WIN32 #define _CRT_SECURE_NO_DEPRECATE 1 #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include "SKP_Silk_SDK_API.h" #include "SKP_Silk_SigProc_FIX.h" #define MAX_BYTES_PER_FRAME 1024 #define MAX_INPUT_FRAMES 5 #define MAX_FRAME_LENGTH 480 #define MAX_LBRR_DELAY 2 static void print_usage(char* argv[]) { printf( "\nusage: %s in.bit out.pcm [settings]\n", argv[ 0 ] ); printf( "\nin.bit : Bitstream input to decoder" ); printf( "\nout.pcm : Speech output from decoder" ); printf( "\n settings:" ); printf( "\n-fs <kHz> : Sampling rate of output signal in kHz; default: 24" ); printf( "\n-loss <perc> : Simulated packet loss percentage (0-100); default: 0" ); printf( "\n" ); } int main( int argc, char* argv[] ) { size_t counter; SKP_int args, totPackets, i, k; SKP_int16 ret, len, tot_len; SKP_int16 nBytes; SKP_uint8 payload[ MAX_BYTES_PER_FRAME * MAX_INPUT_FRAMES * ( MAX_LBRR_DELAY + 1 ) ]; SKP_uint8 FECpayload[ MAX_BYTES_PER_FRAME * MAX_INPUT_FRAMES ], *payloadPtr; SKP_uint8 *payloadEnd = NULL, *payloadToDec = NULL; SKP_int16 nBytesFEC; SKP_int16 nBytesPerPacket[ MAX_LBRR_DELAY + 1 ], totBytes; SKP_int16 out[ ( MAX_FRAME_LENGTH << 1 ) * MAX_INPUT_FRAMES ], *outPtr; char speechOutFileName[ 150 ], bitInFileName[ 150 ]; FILE *bitInFile, *speechOutFile; SKP_int Fs_kHz = 0; SKP_int32 decSizeBytes; void *psDec; float loss_prob; SKP_int frames, lost, quiet; SKP_SILK_SDK_DecControlStruct DecControl; if( argc < 3 ) { print_usage( argv ); exit( 0 ); } quiet = 0; loss_prob = 0.0f; args = 1; strcpy( bitInFileName, argv[ args ] ); args++; strcpy( speechOutFileName, argv[ args ] ); args++; while( args < argc ) { if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-loss" ) == 0 ) { sscanf( argv[ args + 1 ], "%f", &loss_prob ); args += 2; } else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-fs" ) == 0 ) { sscanf( argv[ args + 1 ], "%d", &Fs_kHz ); args += 2; } else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-quiet" ) == 0 ) { quiet = 1; args++; } else { printf( "Error: unrecognized setting: %s\n\n", argv[ args ] ); print_usage( argv ); exit( 0 ); } } if( !quiet ) { printf("******************* Silk Decoder v %s ****************\n", SKP_Silk_SDK_get_version()); printf("******************* Compiled for %d bit cpu ********* \n", (int)sizeof(void*) * 8 ); printf( "Input: %s\n", bitInFileName ); printf( "Output: %s\n", speechOutFileName ); } bitInFile = fopen( bitInFileName, "rb" ); if( bitInFile == NULL ) { printf( "Error: could not open input file %s\n", bitInFileName ); exit( 0 ); } speechOutFile = fopen( speechOutFileName, "wb" ); if( speechOutFile == NULL ) { printf( "Error: could not open output file %s\n", speechOutFileName ); exit( 0 ); } if( Fs_kHz == 0 ) { DecControl.sampleRate = 24000; } else { DecControl.sampleRate = Fs_kHz * 1000; } ret = SKP_Silk_SDK_Get_Decoder_Size( &decSizeBytes ); if( ret ) { printf( "\nSKP_Silk_SDK_Get_Decoder_Size returned %d", ret ); } psDec = malloc( decSizeBytes ); ret = SKP_Silk_SDK_InitDecoder( psDec ); if( ret ) { printf( "\nSKP_Silk_InitDecoder returned %d", ret ); } totPackets = 0; payloadEnd = payload; for( i = 0; i < MAX_LBRR_DELAY; i++ ) { counter = fread( &nBytes, sizeof( SKP_int16 ), 1, bitInFile ); counter = fread( payloadEnd, sizeof( SKP_uint8 ), nBytes, bitInFile ); if( (SKP_int16)counter < nBytes ) { break; } nBytesPerPacket[ i ] = nBytes; payloadEnd += nBytes; } while( 1 ) { counter = fread( &nBytes, sizeof( SKP_int16 ), 1, bitInFile ); if( nBytes < 0 || counter < 1 ) { break; } counter = fread( payloadEnd, sizeof( SKP_uint8 ), nBytes, bitInFile ); if( (SKP_int16)counter < nBytes ) { break; } if( ( (float)rand() / (float)RAND_MAX >= loss_prob / 100 ) && counter > 0 ) { nBytesPerPacket[ MAX_LBRR_DELAY ] = nBytes; payloadEnd += nBytes; } else { nBytesPerPacket[ MAX_LBRR_DELAY ] = 0; } if( nBytesPerPacket[ 0 ] == 0 ) { lost = 1; payloadPtr = payload; for( i = 0; i < MAX_LBRR_DELAY; i++ ) { if( nBytesPerPacket[ i + 1 ] > 0 ) { SKP_Silk_SDK_search_for_LBRR( psDec, payloadPtr, nBytesPerPacket[ i + 1 ], i + 1, FECpayload, &nBytesFEC ); if( nBytesFEC > 0 ) { payloadToDec = FECpayload; nBytes = nBytesFEC; lost = 0; break; } } payloadPtr += nBytesPerPacket[ i + 1 ]; } } else { lost = 0; nBytes = nBytesPerPacket[ 0 ]; payloadToDec = payload; } outPtr = out; tot_len = 0; if( lost == 0 ) { frames = 0; do { ret = SKP_Silk_SDK_Decode( psDec, &DecControl, 0, payloadToDec, nBytes, outPtr, &len ); if( ret ) { printf( "\nSKP_Silk_SDK_Decode returned %d", ret ); } frames++; outPtr += len; tot_len += len; if( frames > MAX_INPUT_FRAMES ) { outPtr = out; tot_len = 0; frames = 0; } } while( DecControl.moreInternalDecoderFrames ); } else { for( i = 0; i < DecControl.framesPerPacket; i++ ) { ret = SKP_Silk_SDK_Decode( psDec, &DecControl, 1, payloadToDec, nBytes, outPtr, &len ); if( ret ) { printf( "\nSKP_Silk_Decode returned %d", ret ); } outPtr += len; tot_len += len; } } totPackets++; fwrite( out, sizeof( SKP_int16 ), tot_len, speechOutFile ); totBytes = 0; for( i = 0; i < MAX_LBRR_DELAY; i++ ) { totBytes += nBytesPerPacket[ i + 1 ]; } SKP_memmove( payload, &payload[ nBytesPerPacket[ 0 ] ], totBytes * sizeof( SKP_uint8 ) ); payloadEnd -= nBytesPerPacket[ 0 ]; SKP_memmove( nBytesPerPacket, &nBytesPerPacket[ 1 ], MAX_LBRR_DELAY * sizeof( SKP_int16 ) ); if( !quiet ) { fprintf( stderr, "\rFrames decoded: %d", totPackets ); } } for( k = 0; k < MAX_LBRR_DELAY; k++ ) { if( nBytesPerPacket[ 0 ] == 0 ) { lost = 1; payloadPtr = payload; for( i = 0; i < MAX_LBRR_DELAY; i++ ) { if( nBytesPerPacket[ i + 1 ] > 0 ) { SKP_Silk_SDK_search_for_LBRR( psDec, payloadPtr, nBytesPerPacket[ i + 1 ], i + 1, FECpayload, &nBytesFEC ); if( nBytesFEC > 0 ) { payloadToDec = FECpayload; nBytes = nBytesFEC; lost = 0; break; } } payloadPtr += nBytesPerPacket[ i + 1 ]; } } else { lost = 0; nBytes = nBytesPerPacket[ 0 ]; payloadToDec = payload; } outPtr = out; tot_len = 0; if( lost == 0 ) { frames = 0; do { ret = SKP_Silk_SDK_Decode( psDec, &DecControl, 0, payloadToDec, nBytes, outPtr, &len ); if( ret ) { printf( "\nSKP_Silk_SDK_Decode returned %d", ret ); } frames++; outPtr += len; tot_len += len; if( frames > MAX_INPUT_FRAMES ) { outPtr = out; tot_len = 0; frames = 0; } } while( DecControl.moreInternalDecoderFrames ); } else { for( i = 0; i < DecControl.framesPerPacket; i++ ) { ret = SKP_Silk_SDK_Decode( psDec, &DecControl, 1, payloadToDec, nBytes, outPtr, &len ); if( ret ) { printf( "\nSKP_Silk_Decode returned %d", ret ); } outPtr += len; tot_len += len; } } totPackets++; fwrite( out, sizeof( SKP_int16 ), tot_len, speechOutFile ); totBytes = 0; for( i = 0; i < MAX_LBRR_DELAY; i++ ) { totBytes += nBytesPerPacket[ i + 1 ]; } SKP_memmove( payload, &payload[ nBytesPerPacket[ 0 ] ], totBytes * sizeof( SKP_uint8 ) ); payloadEnd -= nBytesPerPacket[ 0 ]; SKP_memmove( nBytesPerPacket, &nBytesPerPacket[ 1 ], MAX_LBRR_DELAY * sizeof( SKP_int16 ) ); if( !quiet ) { fprintf( stderr, "\rPackets decoded: %d", totPackets ); } } if( !quiet ) { printf( "\nDecoding Finished \n" ); } free( psDec ); fclose( speechOutFile ); fclose( bitInFile ); return 0; }