1
/***********************************************************************
2
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
3
Redistribution and use in source and binary forms, with or without
4
modification, (subject to the limitations in the disclaimer below)
5
are permitted provided that the following conditions are met:
6
- Redistributions of source code must retain the above copyright notice,
7
this list of conditions and the following disclaimer.
8
- Redistributions in binary form must reproduce the above copyright
9
notice, this list of conditions and the following disclaimer in the
10
documentation and/or other materials provided with the distribution.
11
- Neither the name of Skype Limited, nor the names of specific
12
contributors, may be used to endorse or promote products derived from
13
this software without specific prior written permission.
14
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
15
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
16
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
17
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
22
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
***********************************************************************/
29
/*****************************/
30
/* Silk encoder test program */
31
/*****************************/
34
#define _CRT_SECURE_NO_DEPRECATE 1
40
#include "SKP_Silk_SDK_API.h"
42
/* Define codec specific settings */
43
#define MAX_BYTES_PER_FRAME 250 // Equals peak bitrate of 100 kbps
44
#define MAX_INPUT_FRAMES 5
45
#define FRAME_LENGTH_MS 20
46
#define MAX_API_FS_KHZ 48
48
#ifdef _SYSTEM_IS_BIG_ENDIAN
49
/* Function to convert a little endian int16 to a */
50
/* big endian int16 or vica verca */
52
SKP_int16 vec[], /* I/O array of */
53
SKP_int len /* I length */
60
for( i = 0; i < len; i++ ){
62
p1 = (SKP_uint8 *)&vec[ i ]; p2 = (SKP_uint8 *)&tmp;
63
p1[ 0 ] = p2[ 1 ]; p1[ 1 ] = p2[ 0 ];
68
#if (defined(_WIN32) || defined(_WINCE))
69
#include <windows.h> /* timer */
76
unsigned long GetHighResolutionTime() /* O: time in usec*/
78
/* Returns a time counter in microsec */
79
/* the resolution is platform dependent */
80
/* but is typically 1.62 us resolution */
81
LARGE_INTEGER lpPerformanceCount;
82
LARGE_INTEGER lpFrequency;
83
QueryPerformanceCounter(&lpPerformanceCount);
84
QueryPerformanceFrequency(&lpFrequency);
85
return (unsigned long)((1000000*(lpPerformanceCount.QuadPart)) / lpFrequency.QuadPart);
88
unsigned long GetHighResolutionTime() /* O: time in usec*/
92
return((tv.tv_sec*1000000)+(tv.tv_usec));
96
static void print_usage( char* argv[] ) {
97
printf( "\nusage: %s in.pcm out.bit [settings]\n", argv[ 0 ] );
98
printf( "\nin.pcm : Speech input to encoder" );
99
printf( "\nout.bit : Bitstream output from encoder" );
100
printf( "\n settings:" );
101
printf( "\n-Fs_API <Hz> : API sampling rate in Hz, default: 24000" );
102
printf( "\n-Fs_maxInternal <Hz> : Maximum internal sampling rate in Hz, default: 24000" );
103
printf( "\n-packetlength <ms> : Packet interval in ms, default: 20" );
104
printf( "\n-rate <bps> : Target bitrate; default: 25000" );
105
printf( "\n-loss <perc> : Uplink loss estimate, in percent (0-100); default: 0" );
106
printf( "\n-inbandFEC <flag> : Enable inband FEC usage (0/1); default: 0" );
107
printf( "\n-complexity <comp> : Set complexity, 0: low, 1: medium, 2: high; default: 2" );
108
printf( "\n-DTX <flag> : Enable DTX (0/1); default: 0" );
109
printf( "\n-quiet : Print only some basic values" );
113
int main( int argc, char* argv[] )
115
unsigned long tottime, starttime;
118
SKP_int32 k, args, totPackets, totActPackets, ret;
120
double sumBytes, sumActBytes, avg_rate, act_rate, nrg;
121
SKP_uint8 payload[ MAX_BYTES_PER_FRAME * MAX_INPUT_FRAMES ];
122
SKP_int16 in[ FRAME_LENGTH_MS * MAX_API_FS_KHZ * MAX_INPUT_FRAMES ];
123
char speechInFileName[ 150 ], bitOutFileName[ 150 ];
124
FILE *bitOutFile, *speechInFile;
125
SKP_int32 encSizeBytes;
127
#ifdef _SYSTEM_IS_BIG_ENDIAN
131
/* default settings */
132
SKP_int32 API_fs_Hz = 24000;
133
SKP_int32 max_internal_fs_Hz = 0;
134
SKP_int32 targetRate_bps = 25000;
135
SKP_int32 smplsSinceLastPacket, packetSize_ms = 20;
136
SKP_int32 frameSizeReadFromFile_ms = 20;
137
SKP_int32 packetLoss_perc = 0;
138
#if LOW_COMPLEXITY_ONLY
139
SKP_int32 complexity_mode = 0;
141
SKP_int32 complexity_mode = 2;
143
SKP_int32 DTX_enabled = 0, INBandFEC_enabled = 0, quiet = 0;
144
SKP_SILK_SDK_EncControlStruct encControl; // Struct for input to encoder
145
SKP_SILK_SDK_EncControlStruct encStatus; // Struct for status of encoder
154
strcpy( speechInFileName, argv[ args ] );
156
strcpy( bitOutFileName, argv[ args ] );
158
while( args < argc ) {
159
if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-Fs_API" ) == 0 ) {
160
sscanf( argv[ args + 1 ], "%d", &API_fs_Hz );
162
} else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-Fs_maxInternal" ) == 0 ) {
163
sscanf( argv[ args + 1 ], "%d", &max_internal_fs_Hz );
165
} else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-packetlength" ) == 0 ) {
166
sscanf( argv[ args + 1 ], "%d", &packetSize_ms );
168
} else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-rate" ) == 0 ) {
169
sscanf( argv[ args + 1 ], "%d", &targetRate_bps );
171
} else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-loss" ) == 0 ) {
172
sscanf( argv[ args + 1 ], "%d", &packetLoss_perc );
174
} else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-complexity" ) == 0 ) {
175
sscanf( argv[ args + 1 ], "%d", &complexity_mode );
177
} else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-inbandFEC" ) == 0 ) {
178
sscanf( argv[ args + 1 ], "%d", &INBandFEC_enabled );
180
} else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-DTX") == 0 ) {
181
sscanf( argv[ args + 1 ], "%d", &DTX_enabled );
183
} else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-quiet" ) == 0 ) {
187
printf( "Error: unrecognized setting: %s\n\n", argv[ args ] );
193
/* If no max internal is specified, set to minimum of API fs and 24 kHz */
194
if( max_internal_fs_Hz == 0 ) {
195
max_internal_fs_Hz = 24000;
196
if( API_fs_Hz < max_internal_fs_Hz ) {
197
max_internal_fs_Hz = API_fs_Hz;
203
printf("********** Silk Encoder (Fixed Point) v %s ********************\n", SKP_Silk_SDK_get_version());
204
printf("********** Compiled for %d bit cpu ******************************* \n", (int)sizeof(void*) * 8 );
205
printf( "Input: %s\n", speechInFileName );
206
printf( "Output: %s\n", bitOutFileName );
207
printf( "API sampling rate: %d Hz\n", API_fs_Hz );
208
printf( "Maximum internal sampling rate: %d Hz\n", max_internal_fs_Hz );
209
printf( "Packet interval: %d ms\n", packetSize_ms );
210
printf( "Inband FEC used: %d\n", INBandFEC_enabled );
211
printf( "DTX used: %d\n", DTX_enabled );
212
printf( "Complexity: %d\n", complexity_mode );
213
printf( "Target bitrate: %d bps\n", targetRate_bps );
217
speechInFile = fopen( speechInFileName, "rb" );
218
if( speechInFile == NULL ) {
219
printf( "Error: could not open input file %s\n", speechInFileName );
222
bitOutFile = fopen( bitOutFileName, "wb" );
223
if( bitOutFile == NULL ) {
224
printf( "Error: could not open output file %s\n", bitOutFileName );
228
/* Add Silk header to stream */
230
static const char Silk_header[] = "#!SILK_V3";
231
fwrite( Silk_header, sizeof( char ), strlen( Silk_header ), bitOutFile );
235
ret = SKP_Silk_SDK_Get_Encoder_Size( &encSizeBytes );
237
printf( "\nError: SKP_Silk_create_encoder returned %d\n", ret );
241
psEnc = malloc( encSizeBytes );
244
ret = SKP_Silk_SDK_InitEncoder( psEnc, &encStatus );
246
printf( "\nError: SKP_Silk_reset_encoder returned %d\n", ret );
250
/* Set Encoder parameters */
251
encControl.API_sampleRate = API_fs_Hz;
252
encControl.maxInternalSampleRate = max_internal_fs_Hz;
253
encControl.packetSize = ( packetSize_ms * API_fs_Hz ) / 1000;
254
encControl.packetLossPercentage = packetLoss_perc;
255
encControl.useInBandFEC = INBandFEC_enabled;
256
encControl.useDTX = DTX_enabled;
257
encControl.complexity = complexity_mode;
258
encControl.bitRate = ( targetRate_bps > 0 ? targetRate_bps : 0 );
260
if( API_fs_Hz > MAX_API_FS_KHZ * 1000 || API_fs_Hz < 0 ) {
261
printf( "\nError: API sampling rate = %d out of range, valid range 8000 - 48000 \n \n", API_fs_Hz );
268
smplsSinceLastPacket = 0;
271
smplsSinceLastPacket = 0;
274
/* Read input from file */
275
counter = fread( in, sizeof( SKP_int16 ), ( frameSizeReadFromFile_ms * API_fs_Hz ) / 1000, speechInFile );
276
#ifdef _SYSTEM_IS_BIG_ENDIAN
277
swap_endian( in, counter );
279
if( ( SKP_int )counter < ( ( frameSizeReadFromFile_ms * API_fs_Hz ) / 1000 ) ) {
283
/* max payload size */
284
nBytes = MAX_BYTES_PER_FRAME * MAX_INPUT_FRAMES;
286
starttime = GetHighResolutionTime();
289
ret = SKP_Silk_SDK_Encode( psEnc, &encControl, in, (SKP_int16)counter, payload, &nBytes );
291
printf( "\nSKP_Silk_Encode returned %d", ret );
294
tottime += GetHighResolutionTime() - starttime;
296
/* Get packet size */
297
packetSize_ms = ( SKP_int )( ( 1000 * ( SKP_int32 )encControl.packetSize ) / encControl.API_sampleRate );
299
smplsSinceLastPacket += ( SKP_int )counter;
301
if( ( ( 1000 * smplsSinceLastPacket ) / API_fs_Hz ) == packetSize_ms ) {
302
/* Sends a dummy zero size packet in case of DTX period */
303
/* to make it work with the decoder test program. */
304
/* In practice should be handled by RTP sequence numbers */
308
for( k = 0; k < ( SKP_int )counter; k++ ) {
309
nrg += in[ k ] * (double)in[ k ];
311
if( ( nrg / ( SKP_int )counter ) > 1e3 ) {
312
sumActBytes += nBytes;
316
/* Write payload size */
317
#ifdef _SYSTEM_IS_BIG_ENDIAN
319
swap_endian( &nBytes_LE, 1 );
320
fwrite( &nBytes_LE, sizeof( SKP_int16 ), 1, bitOutFile );
322
fwrite( &nBytes, sizeof( SKP_int16 ), 1, bitOutFile );
326
fwrite( payload, sizeof( SKP_uint8 ), nBytes, bitOutFile );
328
smplsSinceLastPacket = 0;
331
fprintf( stderr, "\rPackets encoded: %d", totPackets );
336
/* Write dummy because it can not end with 0 bytes */
339
/* Write payload size */
340
fwrite( &nBytes, sizeof( SKP_int16 ), 1, bitOutFile );
345
fclose( speechInFile );
346
fclose( bitOutFile );
348
filetime = totPackets * 1e-3 * packetSize_ms;
349
avg_rate = 8.0 / packetSize_ms * sumBytes / totPackets;
350
act_rate = 8.0 / packetSize_ms * sumActBytes / totActPackets;
352
printf( "\nFile length: %.3f s", filetime );
353
printf( "\nTime for encoding: %.3f s (%.3f%% of realtime)", 1e-6 * tottime, 1e-4 * tottime / filetime );
354
printf( "\nAverage bitrate: %.3f kbps", avg_rate );
355
printf( "\nActive bitrate: %.3f kbps", act_rate );
358
/* print time and % of realtime */
359
printf("%.3f %.3f %d ", 1e-6 * tottime, 1e-4 * tottime / filetime, totPackets );
360
/* print average and active bitrates */
361
printf( "%.3f %.3f \n", avg_rate, act_rate );