123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418 |
- /***********************************************************************
- 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:
- - Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- - Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- - Neither the name of Skype Limited, nor the names of specific
- contributors, may be used to endorse or promote products derived from
- this software without specific prior written permission.
- NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
- BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
- BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- ***********************************************************************/
- /*****************************/
- /* Silk decoder test program */
- /*****************************/
- #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 codec specific settings should be moved to h file */
- #define MAX_BYTES_PER_FRAME 1024
- #define MAX_INPUT_FRAMES 5
- #define MAX_FRAME_LENGTH 480
- #define FRAME_LENGTH_MS 20
- #define MAX_API_FS_KHZ 48
- #define MAX_LBRR_DELAY 2
- #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[],
- SKP_int len
- )
- {
- 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
- /* Seed for the random number generator, which is used for simulating packet loss */
- static SKP_int32 rand_seed = 1;
- static void print_usage(char* argv[]) {
- printf( "\nusage: %s in.bit out.pcm [settings]\n", argv[ 0 ] );
- printf( "\nstream.bit : Bitstream input to decoder" );
- printf( "\nout.pcm : Speech output from decoder" );
- printf( "\n settings:" );
- printf( "\n-Fs_API <Hz> : Sampling rate of output signal in Hz; default: 24000" );
- printf( "\n-loss <perc> : Simulated packet loss percentage (0-100); default: 0" );
- printf( "\n" );
- }
- int main( int argc, char* argv[] )
- {
- size_t counter;
- SKP_int32 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 *payloadEnd = NULL, *payloadToDec = NULL;
- SKP_uint8 FECpayload[ MAX_BYTES_PER_FRAME * MAX_INPUT_FRAMES ], *payloadPtr;
- SKP_int16 nBytesFEC;
- SKP_int16 nBytesPerPacket[ MAX_LBRR_DELAY + 1 ], totBytes;
- SKP_int16 out[ ( ( FRAME_LENGTH_MS * MAX_API_FS_KHZ ) << 1 ) * MAX_INPUT_FRAMES ], *outPtr;
- char speechOutFileName[ 150 ], bitInFileName[ 150 ];
- FILE *bitInFile, *speechOutFile;
- SKP_int32 API_Fs_Hz = 0;
- SKP_int32 decSizeBytes;
- void *psDec;
- float loss_prob;
- SKP_int32 frames, lost, quiet;
- SKP_SILK_SDK_DecControlStruct DecControl;
- if( argc < 3 ) {
- print_usage( argv );
- exit( 0 );
- }
- /* default settings */
- quiet = 0;
- loss_prob = 0.0f;
- /* get arguments */
- 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_API" ) == 0 ) {
- sscanf( argv[ args + 1 ], "%d", &API_Fs_Hz );
- 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 );
- }
- /* Open files */
- bitInFile = fopen( bitInFileName, "rb" );
- if( bitInFile == NULL ) {
- printf( "Error: could not open input file %s\n", bitInFileName );
- exit( 0 );
- }
- /* Check Silk header */
- {
- char header_buf[ 50 ];
- counter = fread( header_buf, sizeof( char ), strlen( "#!SILK_V3" ), bitInFile );
- header_buf[ strlen( "#!SILK_V3" ) ] = ( char )0; /* Terminate with a null character */
- if( strcmp( header_buf, "#!SILK_V3" ) != 0 ) {
- /* Non-equal strings */
- printf( "Error: Wrong Header %s\n", header_buf );
- exit( 0 );
- }
- }
- speechOutFile = fopen( speechOutFileName, "wb" );
- if( speechOutFile == NULL ) {
- printf( "Error: could not open output file %s\n", speechOutFileName );
- exit( 0 );
- }
- /* Set the samplingrate that is requested for the output */
- if( API_Fs_Hz == 0 ) {
- DecControl.API_sampleRate = 24000;
- } else {
- DecControl.API_sampleRate = API_Fs_Hz;
- }
- /* Initialize to one frame per packet, for proper concealment before first packet arrives */
- DecControl.framesPerPacket = 1;
- /* Create decoder */
- ret = SKP_Silk_SDK_Get_Decoder_Size( &decSizeBytes );
- if( ret ) {
- printf( "\nSKP_Silk_SDK_Get_Decoder_Size returned %d", ret );
- }
- psDec = malloc( decSizeBytes );
- /* Reset decoder */
- ret = SKP_Silk_SDK_InitDecoder( psDec );
- if( ret ) {
- printf( "\nSKP_Silk_InitDecoder returned %d", ret );
- }
- totPackets = 0;
- payloadEnd = payload;
- /* Simulate the jitter buffer holding MAX_FEC_DELAY packets */
- for( i = 0; i < MAX_LBRR_DELAY; i++ ) {
- /* Read payload size */
- counter = fread( &nBytes, sizeof( SKP_int16 ), 1, bitInFile );
- #ifdef _SYSTEM_IS_BIG_ENDIAN
- swap_endian( &nBytes, 1 );
- #endif
- /* Read payload */
- counter = fread( payloadEnd, sizeof( SKP_uint8 ), nBytes, bitInFile );
- if( ( SKP_int16 )counter < nBytes ) {
- break;
- }
- nBytesPerPacket[ i ] = nBytes;
- payloadEnd += nBytes;
- }
- while( 1 ) {
- /* Read payload size */
- counter = fread( &nBytes, sizeof( SKP_int16 ), 1, bitInFile );
- #ifdef _SYSTEM_IS_BIG_ENDIAN
- swap_endian( &nBytes, 1 );
- #endif
- if( nBytes < 0 || counter < 1 ) {
- break;
- }
-
- /* Read payload */
- counter = fread( payloadEnd, sizeof( SKP_uint8 ), nBytes, bitInFile );
- if( ( SKP_int16 )counter < nBytes ) {
- break;
- }
- /* Simulate losses */
- rand_seed = SKP_RAND( rand_seed );
- if( ( ( ( float )( ( rand_seed >> 16 ) + ( 1 << 15 ) ) ) / 65535.0f >= ( loss_prob / 100.0f ) ) && ( counter > 0 ) ) {
- nBytesPerPacket[ MAX_LBRR_DELAY ] = nBytes;
- payloadEnd += nBytes;
- } else {
- nBytesPerPacket[ MAX_LBRR_DELAY ] = 0;
- }
- if( nBytesPerPacket[ 0 ] == 0 ) {
- /* Indicate lost packet */
- lost = 1;
- /* Packet loss. Search after FEC in next packets. Should be done in the jitter buffer */
- payloadPtr = payload;
- for( i = 0; i < MAX_LBRR_DELAY; i++ ) {
- if( nBytesPerPacket[ i + 1 ] > 0 ) {
- SKP_Silk_SDK_search_for_LBRR( 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;
- }
- /* Silk decoder */
- outPtr = out;
- tot_len = 0;
- if( lost == 0 ) {
- /* No Loss: Decode all frames in the packet */
- frames = 0;
- do {
- /* Decode 20 ms */
- 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 ) {
- /* Hack for corrupt stream that could generate too many frames */
- outPtr = out;
- tot_len = 0;
- frames = 0;
- }
- /* Until last 20 ms frame of packet has been decoded */
- } while( DecControl.moreInternalDecoderFrames );
- } else {
- /* Loss: Decode enough frames to cover one packet duration */
- for( i = 0; i < DecControl.framesPerPacket; i++ ) {
- /* Generate 20 ms */
- 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++;
- /* Write output to file */
- #ifdef _SYSTEM_IS_BIG_ENDIAN
- swap_endian( out, tot_len );
- #endif
- fwrite( out, sizeof( SKP_int16 ), tot_len, speechOutFile );
- /* Update buffer */
- 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 );
- }
- }
- /* Empty the recieve buffer */
- for( k = 0; k < MAX_LBRR_DELAY; k++ ) {
- if( nBytesPerPacket[ 0 ] == 0 ) {
- /* Indicate lost packet */
- lost = 1;
- /* Packet loss. Search after FEC in next packets. Should be done in the jitter buffer */
- payloadPtr = payload;
- for( i = 0; i < MAX_LBRR_DELAY; i++ ) {
- if( nBytesPerPacket[ i + 1 ] > 0 ) {
- SKP_Silk_SDK_search_for_LBRR( 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;
- }
- /* Silk decoder */
- outPtr = out;
- tot_len = 0;
- if( lost == 0 ) {
- /* No loss: Decode all frames in the packet */
- frames = 0;
- do {
- /* Decode 20 ms */
- 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 ) {
- /* Hack for corrupt stream that could generate too many frames */
- outPtr = out;
- tot_len = 0;
- frames = 0;
- }
- /* Until last 20 ms frame of packet has been decoded */
- } while( DecControl.moreInternalDecoderFrames );
- } else {
- /* Loss: Decode enough frames to cover one packet duration */
- /* Generate 20 ms */
- 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++;
- /* Write output to file */
- #ifdef _SYSTEM_IS_BIG_ENDIAN
- swap_endian( out, tot_len );
- #endif
- fwrite( out, sizeof( SKP_int16 ), tot_len, speechOutFile );
- /* Update Buffer */
- 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 decoder */
- free( psDec );
- /* Close files */
- fclose( speechOutFile );
- fclose( bitInFile );
- return 0;
- }
|