~michael-gruz/+junk/linphone-plugin-silk

« back to all changes in this revision

Viewing changes to sdk/SILK_SDK_SRC_v1.0.9/SILK_SDK_SRC_FIX_v1.0.9/test/Encoder.c

  • Committer: Michael Gruz
  • Date: 2013-05-03 18:54:43 UTC
  • Revision ID: michael-gruz@seznam.cz-20130503185443-x9slgz3glf5r1vj2
fix

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
***********************************************************************/
27
 
 
28
 
 
29
 
/*****************************/
30
 
/* Silk encoder test program */
31
 
/*****************************/
32
 
 
33
 
#ifdef _WIN32
34
 
#define _CRT_SECURE_NO_DEPRECATE    1
35
 
#endif
36
 
 
37
 
#include <stdio.h>
38
 
#include <stdlib.h>
39
 
#include <string.h>
40
 
#include "SKP_Silk_SDK_API.h"
41
 
 
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
47
 
 
48
 
#ifdef _SYSTEM_IS_BIG_ENDIAN
49
 
/* Function to convert a little endian int16 to a */
50
 
/* big endian int16 or vica verca                 */
51
 
void swap_endian(
52
 
    SKP_int16       vec[],              /*  I/O array of */
53
 
    SKP_int         len                 /*  I   length      */
54
 
)
55
 
{
56
 
    SKP_int i;
57
 
    SKP_int16 tmp;
58
 
    SKP_uint8 *p1, *p2;
59
 
 
60
 
    for( i = 0; i < len; i++ ){
61
 
        tmp = vec[ i ];
62
 
        p1 = (SKP_uint8 *)&vec[ i ]; p2 = (SKP_uint8 *)&tmp;
63
 
        p1[ 0 ] = p2[ 1 ]; p1[ 1 ] = p2[ 0 ];
64
 
    }
65
 
}
66
 
#endif
67
 
 
68
 
#if (defined(_WIN32) || defined(_WINCE)) 
69
 
#include <windows.h>    /* timer */
70
 
#else    // Linux or Mac
71
 
#include <sys/time.h>
72
 
#endif
73
 
 
74
 
#ifdef _WIN32
75
 
 
76
 
unsigned long GetHighResolutionTime() /* O: time in usec*/
77
 
{
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);
86
 
}
87
 
#else    // Linux or Mac
88
 
unsigned long GetHighResolutionTime() /* O: time in usec*/
89
 
{
90
 
    struct timeval tv;
91
 
    gettimeofday(&tv, 0);
92
 
    return((tv.tv_sec*1000000)+(tv.tv_usec));
93
 
}
94
 
#endif // _WIN32
95
 
 
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" );
110
 
    printf( "\n");
111
 
}
112
 
 
113
 
int main( int argc, char* argv[] )
114
 
{
115
 
    unsigned long tottime, starttime;
116
 
    double    filetime;
117
 
    size_t    counter;
118
 
    SKP_int32 k, args, totPackets, totActPackets, ret;
119
 
    SKP_int16 nBytes;
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;
126
 
    void      *psEnc;
127
 
#ifdef _SYSTEM_IS_BIG_ENDIAN
128
 
    SKP_int16 nBytes_LE;
129
 
#endif
130
 
 
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;
140
 
#else
141
 
    SKP_int32 complexity_mode = 2;
142
 
#endif
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
146
 
 
147
 
    if( argc < 3 ) {
148
 
        print_usage( argv );
149
 
        exit( 0 );
150
 
    } 
151
 
    
152
 
    /* get arguments */
153
 
    args = 1;
154
 
    strcpy( speechInFileName, argv[ args ] );
155
 
    args++;
156
 
    strcpy( bitOutFileName,   argv[ args ] );
157
 
    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 );
161
 
            args += 2;
162
 
        } else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-Fs_maxInternal" ) == 0 ) {
163
 
            sscanf( argv[ args + 1 ], "%d", &max_internal_fs_Hz );
164
 
            args += 2;
165
 
        } else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-packetlength" ) == 0 ) {
166
 
            sscanf( argv[ args + 1 ], "%d", &packetSize_ms );
167
 
            args += 2;
168
 
        } else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-rate" ) == 0 ) {
169
 
            sscanf( argv[ args + 1 ], "%d", &targetRate_bps );
170
 
            args += 2;
171
 
        } else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-loss" ) == 0 ) {
172
 
            sscanf( argv[ args + 1 ], "%d", &packetLoss_perc );
173
 
            args += 2;
174
 
        } else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-complexity" ) == 0 ) {
175
 
            sscanf( argv[ args + 1 ], "%d", &complexity_mode );
176
 
            args += 2;
177
 
        } else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-inbandFEC" ) == 0 ) {
178
 
            sscanf( argv[ args + 1 ], "%d", &INBandFEC_enabled );
179
 
            args += 2;
180
 
        } else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-DTX") == 0 ) {
181
 
            sscanf( argv[ args + 1 ], "%d", &DTX_enabled );
182
 
            args += 2;
183
 
        } else if( SKP_STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-quiet" ) == 0 ) {
184
 
            quiet = 1;
185
 
            args++;
186
 
        } else {
187
 
            printf( "Error: unrecognized setting: %s\n\n", argv[ args ] );
188
 
            print_usage( argv );
189
 
            exit( 0 );
190
 
        }
191
 
    }
192
 
 
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;
198
 
        }
199
 
    }
200
 
 
201
 
    /* Print options */
202
 
    if( !quiet ) {
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 );
214
 
    }
215
 
 
216
 
    /* Open files */
217
 
    speechInFile = fopen( speechInFileName, "rb" );
218
 
    if( speechInFile == NULL ) {
219
 
        printf( "Error: could not open input file %s\n", speechInFileName );
220
 
        exit( 0 );
221
 
    }
222
 
    bitOutFile = fopen( bitOutFileName, "wb" );
223
 
    if( bitOutFile == NULL ) {
224
 
        printf( "Error: could not open output file %s\n", bitOutFileName );
225
 
        exit( 0 );
226
 
    }
227
 
 
228
 
    /* Add Silk header to stream */
229
 
    {
230
 
        static const char Silk_header[] = "#!SILK_V3";
231
 
        fwrite( Silk_header, sizeof( char ), strlen( Silk_header ), bitOutFile );
232
 
    }
233
 
 
234
 
    /* Create Encoder */
235
 
    ret = SKP_Silk_SDK_Get_Encoder_Size( &encSizeBytes );
236
 
    if( ret ) {
237
 
        printf( "\nError: SKP_Silk_create_encoder returned %d\n", ret );
238
 
        exit( 0 );
239
 
    }
240
 
 
241
 
    psEnc = malloc( encSizeBytes );
242
 
 
243
 
    /* Reset Encoder */
244
 
    ret = SKP_Silk_SDK_InitEncoder( psEnc, &encStatus );
245
 
    if( ret ) {
246
 
        printf( "\nError: SKP_Silk_reset_encoder returned %d\n", ret );
247
 
        exit( 0 );
248
 
    }
249
 
 
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 );
259
 
 
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 );
262
 
        exit( 0 );
263
 
    }
264
 
 
265
 
    tottime              = 0;
266
 
    totPackets           = 0;
267
 
    totActPackets        = 0;
268
 
    smplsSinceLastPacket = 0;
269
 
    sumBytes             = 0.0;
270
 
    sumActBytes          = 0.0;
271
 
    smplsSinceLastPacket = 0;
272
 
    
273
 
    while( 1 ) {
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 );
278
 
#endif
279
 
        if( ( SKP_int )counter < ( ( frameSizeReadFromFile_ms * API_fs_Hz ) / 1000 ) ) {
280
 
            break;
281
 
        }
282
 
 
283
 
        /* max payload size */
284
 
        nBytes = MAX_BYTES_PER_FRAME * MAX_INPUT_FRAMES;
285
 
 
286
 
        starttime = GetHighResolutionTime();
287
 
 
288
 
        /* Silk Encoder */
289
 
        ret = SKP_Silk_SDK_Encode( psEnc, &encControl, in, (SKP_int16)counter, payload, &nBytes );
290
 
        if( ret ) {
291
 
            printf( "\nSKP_Silk_Encode returned %d", ret );
292
 
        }
293
 
 
294
 
        tottime += GetHighResolutionTime() - starttime;
295
 
 
296
 
        /* Get packet size */
297
 
        packetSize_ms = ( SKP_int )( ( 1000 * ( SKP_int32 )encControl.packetSize ) / encControl.API_sampleRate );
298
 
 
299
 
        smplsSinceLastPacket += ( SKP_int )counter;
300
 
        
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 */
305
 
            totPackets++;
306
 
            sumBytes  += nBytes;
307
 
            nrg = 0.0;
308
 
            for( k = 0; k < ( SKP_int )counter; k++ ) {
309
 
                nrg += in[ k ] * (double)in[ k ];
310
 
            }
311
 
            if( ( nrg / ( SKP_int )counter ) > 1e3 ) {
312
 
                sumActBytes += nBytes;
313
 
                totActPackets++;
314
 
            }
315
 
 
316
 
            /* Write payload size */
317
 
#ifdef _SYSTEM_IS_BIG_ENDIAN
318
 
            nBytes_LE = nBytes;
319
 
            swap_endian( &nBytes_LE, 1 );
320
 
            fwrite( &nBytes_LE, sizeof( SKP_int16 ), 1, bitOutFile );
321
 
#else
322
 
            fwrite( &nBytes, sizeof( SKP_int16 ), 1, bitOutFile );
323
 
#endif
324
 
 
325
 
            /* Write payload */
326
 
            fwrite( payload, sizeof( SKP_uint8 ), nBytes, bitOutFile );
327
 
 
328
 
            smplsSinceLastPacket = 0;
329
 
        
330
 
            if( !quiet ) {
331
 
                fprintf( stderr, "\rPackets encoded:                %d", totPackets );
332
 
            }
333
 
        }
334
 
    }
335
 
 
336
 
    /* Write dummy because it can not end with 0 bytes */
337
 
    nBytes = -1;
338
 
 
339
 
    /* Write payload size */
340
 
    fwrite( &nBytes, sizeof( SKP_int16 ), 1, bitOutFile );
341
 
 
342
 
    /* Free Encoder */
343
 
    free( psEnc );
344
 
 
345
 
    fclose( speechInFile );
346
 
    fclose( bitOutFile   );
347
 
 
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;
351
 
    if( !quiet ) {
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  );
356
 
        printf( "\n\n" );
357
 
    } else {
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 );
362
 
    }
363
 
 
364
 
    return 0;
365
 
}