Initial Skype commit taken from FreeSwitch, which got it from the IETF draft.
[opus.git] / src / SKP_Silk_enc_API.c
1 /***********************************************************************\r
2 Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
3 Redistribution and use in source and binary forms, with or without \r
4 modification, (subject to the limitations in the disclaimer below) \r
5 are permitted provided that the following conditions are met:\r
6 - Redistributions of source code must retain the above copyright notice,\r
7 this list of conditions and the following disclaimer.\r
8 - Redistributions in binary form must reproduce the above copyright \r
9 notice, this list of conditions and the following disclaimer in the \r
10 documentation and/or other materials provided with the distribution.\r
11 - Neither the name of Skype Limited, nor the names of specific \r
12 contributors, may be used to endorse or promote products derived from \r
13 this software without specific prior written permission.\r
14 NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
15 BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
16 CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
17 BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
18 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
19 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
22 USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
23 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
26 ***********************************************************************/\r
27 \r
28 \r
29 #include "SKP_Silk_define.h"\r
30 #include "SKP_Silk_main_FIX.h"\r
31 #include "SKP_Silk_SDK_API.h"\r
32 #include "SKP_Silk_control.h"\r
33 #include "SKP_Silk_typedef.h"\r
34 #include "SKP_Silk_structs.h"\r
35 #define SKP_Silk_EncodeControlStruct SKP_SILK_SDK_EncControlStruct\r
36 \r
37 /****************************************/\r
38 /* Encoder functions                    */\r
39 /****************************************/\r
40 \r
41 SKP_int SKP_Silk_SDK_Get_Encoder_Size( SKP_int *encSizeBytes )\r
42 {\r
43     SKP_int ret = 0;\r
44     \r
45     *encSizeBytes = sizeof( SKP_Silk_encoder_state_FIX );\r
46     \r
47     return ret;\r
48 }\r
49 \r
50 \r
51 /***************************************/\r
52 /* Read control structure from encoder */\r
53 /***************************************/\r
54 SKP_int SKP_Silk_SDK_QueryEncoder(\r
55     const void *encState,                       /* I:   State Vector                                    */\r
56     SKP_Silk_EncodeControlStruct *encStatus     /* O:   Control Structure                               */\r
57 )\r
58 {\r
59     SKP_Silk_encoder_state_FIX *psEnc;\r
60     SKP_int ret = 0;    \r
61 \r
62     psEnc = ( SKP_Silk_encoder_state_FIX* )encState;\r
63 \r
64     encStatus->sampleRate = ( unsigned short )SKP_SMULBB( psEnc->sCmn.fs_kHz, 1000 );                       /* convert kHz -> Hz */ \r
65     encStatus->packetSize = ( unsigned short )SKP_SMULBB( psEnc->sCmn.fs_kHz, psEnc->sCmn.PacketSize_ms );  /* convert samples -> ms */\r
66     encStatus->bitRate    = ( unsigned short )psEnc->sCmn.TargetRate_bps;\r
67     encStatus->packetLossPercentage = psEnc->sCmn.PacketLoss_perc;\r
68     encStatus->complexity           = psEnc->sCmn.Complexity;\r
69 \r
70     return ret;\r
71 }\r
72 \r
73 /*************************/\r
74 /* Init or Reset encoder */\r
75 /*************************/\r
76 SKP_int SKP_Silk_SDK_InitEncoder(\r
77     void                            *encState,          /* I/O: State                                           */\r
78     SKP_Silk_EncodeControlStruct    *encStatus          /* O:   Control structure                               */\r
79 )\r
80 {\r
81     SKP_Silk_encoder_state_FIX *psEnc;\r
82     SKP_int ret = 0;\r
83 \r
84         \r
85     psEnc = ( SKP_Silk_encoder_state_FIX* )encState;\r
86 \r
87     /* Reset Encoder */\r
88     if( ret += SKP_Silk_init_encoder_FIX( psEnc ) ) {\r
89         SKP_assert( 0 );\r
90     }\r
91 \r
92     /* Read Control structure */\r
93     if( ret += SKP_Silk_SDK_QueryEncoder( encState, encStatus ) ) {\r
94         SKP_assert( 0 );\r
95     }\r
96 \r
97 \r
98     return ret;\r
99 }\r
100 \r
101 /**************************/\r
102 /* Encode frame with Silk */\r
103 /**************************/\r
104 SKP_int SKP_Silk_SDK_Encode( \r
105     void                                *encState,      /* I/O: State                                           */\r
106     const SKP_Silk_EncodeControlStruct  *encControl,    /* I:   Control structure                               */\r
107     const SKP_int16                     *samplesIn,     /* I:   Speech sample input vector                      */\r
108     SKP_int                             nSamplesIn,     /* I:   Number of samples in input vector               */\r
109     SKP_uint8                           *outData,       /* O:   Encoded output vector                           */\r
110     SKP_int16                           *nBytesOut      /* I/O: Number of bytes in outData (input: Max bytes)   */\r
111 )\r
112 {\r
113     SKP_int   API_fs_kHz, PacketSize_ms, PacketLoss_perc, UseInBandFec, UseDTX, ret = 0;\r
114     SKP_int   nSamplesToBuffer, Complexity, input_ms, nSamplesFromInput = 0;\r
115     SKP_int32 TargetRate_bps;\r
116     SKP_int16 MaxBytesOut;\r
117     SKP_Silk_encoder_state_FIX *psEnc = ( SKP_Silk_encoder_state_FIX* )encState;\r
118 \r
119 \r
120     SKP_assert( encControl != NULL );\r
121 \r
122     /* Check sampling frequency first, to avoid divide by zero later */\r
123     if( ( encControl->sampleRate !=  8000 ) && ( encControl->sampleRate != 12000 ) && \r
124         ( encControl->sampleRate != 16000 ) && ( encControl->sampleRate != 24000 ) ) {\r
125         ret = SKP_SILK_ENC_FS_NOT_SUPPORTED;\r
126         SKP_assert( 0 );\r
127         return( ret );\r
128     }\r
129 \r
130     /* Set Encoder parameters from Control structure */\r
131     API_fs_kHz      = SKP_DIV32_16( ( SKP_int )encControl->sampleRate, 1000 );          /* convert Hz -> kHz */\r
132     PacketSize_ms   = SKP_DIV32_16( ( SKP_int )encControl->packetSize, API_fs_kHz );    /* convert samples -> ms */\r
133     TargetRate_bps  =             ( SKP_int32 )encControl->bitRate;\r
134     PacketLoss_perc =               ( SKP_int )encControl->packetLossPercentage;\r
135     UseInBandFec    =               ( SKP_int )encControl->useInBandFEC;\r
136     Complexity      =               ( SKP_int )encControl->complexity;\r
137     UseDTX          =               ( SKP_int )encControl->useDTX;\r
138 \r
139     /* Only accept input lengths that are multiplum of 10 ms */\r
140     input_ms = SKP_DIV32_16( nSamplesIn, API_fs_kHz );\r
141     if( ( input_ms % 10) != 0 || nSamplesIn < 0 ) {\r
142         ret = SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;\r
143         SKP_assert( 0 );\r
144         return( ret );\r
145     }\r
146 \r
147     /* Make sure no more than one packet can be produced */\r
148     if( nSamplesIn > SKP_SMULBB( psEnc->sCmn.PacketSize_ms, API_fs_kHz ) ) {\r
149         ret = SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;\r
150         SKP_assert( 0 );\r
151         return( ret );\r
152     }\r
153 \r
154     if( ( ret = SKP_Silk_control_encoder_FIX( psEnc, API_fs_kHz, PacketSize_ms, TargetRate_bps, \r
155                     PacketLoss_perc, UseInBandFec, UseDTX, input_ms, Complexity ) ) != 0 ) {\r
156         SKP_assert( 0 );\r
157         return( ret );\r
158     }\r
159 \r
160     /* Detect energy above 8 kHz */\r
161     if( encControl->sampleRate == 24000 && psEnc->sCmn.sSWBdetect.SWB_detected == 0 && psEnc->sCmn.sSWBdetect.WB_detected == 0 ) {\r
162         SKP_Silk_detect_SWB_input( &psEnc->sCmn.sSWBdetect, samplesIn, ( SKP_int )nSamplesIn );\r
163     }\r
164 \r
165     /* Input buffering/resampling and encoding */\r
166     MaxBytesOut = 0;                    /* return 0 output bytes if no encoder called */\r
167     while( 1 ) {\r
168         /* Resample/buffer */\r
169         nSamplesToBuffer = psEnc->sCmn.frame_length - psEnc->sCmn.inputBufIx;\r
170         if( encControl->sampleRate == SKP_SMULBB( psEnc->sCmn.fs_kHz, 1000 ) ) { \r
171             /* Same sample frequency - copy the data */\r
172             nSamplesToBuffer  = SKP_min_int( nSamplesToBuffer, nSamplesIn );\r
173             nSamplesFromInput = nSamplesToBuffer;\r
174             SKP_memcpy( &psEnc->sCmn.inputBuf[ psEnc->sCmn.inputBufIx ], samplesIn, SKP_SMULBB( nSamplesToBuffer, sizeof( SKP_int16 ) ) );\r
175         } else if( encControl->sampleRate == 24000 && psEnc->sCmn.fs_kHz == 16 ) {\r
176             /* Resample the data from 24 kHz to 16 kHz */\r
177             nSamplesToBuffer  = SKP_min_int( nSamplesToBuffer, SKP_SMULWB( SKP_LSHIFT( nSamplesIn, 1 ), 21846 ) ); // 21846 = ceil(2/3)*2^15\r
178             nSamplesFromInput = SKP_RSHIFT( SKP_SMULBB( nSamplesToBuffer, 3 ), 1 );\r
179 #if LOW_COMPLEXITY_ONLY\r
180             {\r
181                 SKP_int16 scratch[ MAX_FRAME_LENGTH + SigProc_Resample_2_3_coarse_NUM_FIR_COEFS - 1 ];\r
182                 SKP_assert( nSamplesFromInput <= MAX_FRAME_LENGTH );\r
183                 SKP_Silk_resample_2_3_coarse( &psEnc->sCmn.inputBuf[ psEnc->sCmn.inputBufIx ], psEnc->sCmn.resample24To16state, \r
184                     samplesIn, nSamplesFromInput, scratch );\r
185             }\r
186 #else\r
187             SKP_Silk_resample_2_3( &psEnc->sCmn.inputBuf[ psEnc->sCmn.inputBufIx ], psEnc->sCmn.resample24To16state, \r
188                 samplesIn, nSamplesFromInput );\r
189 #endif\r
190         } else if( encControl->sampleRate == 24000 && psEnc->sCmn.fs_kHz == 12 ) {\r
191             SKP_int32 scratch[ 3 * MAX_FRAME_LENGTH ];\r
192             /* Resample the data from 24 kHz to 12 kHz */\r
193             nSamplesToBuffer  = SKP_min_int( nSamplesToBuffer, SKP_RSHIFT( nSamplesIn, 1 ) );\r
194             nSamplesFromInput = SKP_LSHIFT16( nSamplesToBuffer, 1 );\r
195             SKP_Silk_resample_1_2_coarse( samplesIn, psEnc->sCmn.resample24To12state, \r
196                 &psEnc->sCmn.inputBuf[ psEnc->sCmn.inputBufIx ], scratch, nSamplesToBuffer );\r
197         } else if( encControl->sampleRate == 24000 && psEnc->sCmn.fs_kHz == 8 ) {\r
198             /* Resample the data from 24 kHz to 8 kHz */\r
199             nSamplesToBuffer  = SKP_min_int( nSamplesToBuffer, SKP_DIV32_16( nSamplesIn, 3 ) );\r
200             nSamplesFromInput = SKP_SMULBB( nSamplesToBuffer, 3 );\r
201             SKP_Silk_resample_1_3( &psEnc->sCmn.inputBuf[ psEnc->sCmn.inputBufIx ], psEnc->sCmn.resample24To8state, \r
202                 samplesIn, nSamplesFromInput);\r
203         } else if( encControl->sampleRate == 16000 && psEnc->sCmn.fs_kHz == 12 ) {\r
204             /* Resample the data from 16 kHz to 12 kHz */\r
205             nSamplesToBuffer  = SKP_min_int( nSamplesToBuffer, SKP_RSHIFT( SKP_SMULBB( nSamplesIn, 3 ), 2 ) );\r
206             nSamplesFromInput = SKP_SMULWB( SKP_LSHIFT16( nSamplesToBuffer, 2 ), 21846 ); // 21846 = ceil((1/3)*2^16)\r
207             SKP_Silk_resample_3_4( &psEnc->sCmn.inputBuf[ psEnc->sCmn.inputBufIx ], psEnc->sCmn.resample16To12state, \r
208                 samplesIn, nSamplesFromInput );\r
209         } else if( encControl->sampleRate == 16000 && psEnc->sCmn.fs_kHz == 8 ) {\r
210             SKP_int32 scratch[ 3 * MAX_FRAME_LENGTH ];\r
211             /* Resample the data from 16 kHz to 8 kHz */\r
212             nSamplesToBuffer  = SKP_min_int( nSamplesToBuffer, SKP_RSHIFT( nSamplesIn, 1 ) );\r
213             nSamplesFromInput = SKP_LSHIFT16( nSamplesToBuffer, 1 );\r
214             SKP_Silk_resample_1_2_coarse( samplesIn, psEnc->sCmn.resample16To8state, \r
215                 &psEnc->sCmn.inputBuf[ psEnc->sCmn.inputBufIx ], scratch, nSamplesToBuffer );\r
216         } else if( encControl->sampleRate == 12000 && psEnc->sCmn.fs_kHz == 8 ) {\r
217             /* Resample the data from 12 kHz to 8 kHz */\r
218             nSamplesToBuffer  = SKP_min_int( nSamplesToBuffer, SKP_SMULWB( SKP_LSHIFT( nSamplesIn, 1 ), 21846 ) );\r
219             nSamplesFromInput = SKP_RSHIFT( SKP_SMULBB( nSamplesToBuffer, 3 ), 1 );\r
220 #if LOW_COMPLEXITY_ONLY\r
221             {\r
222                 SKP_int16 scratch[ MAX_FRAME_LENGTH + SigProc_Resample_2_3_coarse_NUM_FIR_COEFS - 1 ];\r
223                 SKP_assert( nSamplesFromInput <= MAX_FRAME_LENGTH );\r
224                 SKP_Silk_resample_2_3_coarse( &psEnc->sCmn.inputBuf[ psEnc->sCmn.inputBufIx ], psEnc->sCmn.resample12To8state, \r
225                     samplesIn, nSamplesFromInput, scratch );\r
226             }\r
227 #else\r
228             SKP_Silk_resample_2_3( &psEnc->sCmn.inputBuf[ psEnc->sCmn.inputBufIx ], psEnc->sCmn.resample12To8state, \r
229                 samplesIn, nSamplesFromInput );\r
230 #endif\r
231         }\r
232         samplesIn  += nSamplesFromInput;\r
233         nSamplesIn -= nSamplesFromInput;\r
234         psEnc->sCmn.inputBufIx += nSamplesToBuffer;\r
235 \r
236         /* Silk encoder */\r
237         if( psEnc->sCmn.inputBufIx >= psEnc->sCmn.frame_length ) {\r
238             /* Enough data in input buffer, so encode */\r
239             if( MaxBytesOut == 0 ) {\r
240                 /* No payload obtained so far */\r
241                 MaxBytesOut = *nBytesOut;\r
242                 if( ( ret = SKP_Silk_encode_frame_FIX( psEnc, outData, &MaxBytesOut, psEnc->sCmn.inputBuf ) ) != 0 ) {\r
243                     SKP_assert( 0 );\r
244                 }\r
245             } else {\r
246                 /* outData already contains a payload */\r
247                 if( ( ret = SKP_Silk_encode_frame_FIX( psEnc, outData, nBytesOut, psEnc->sCmn.inputBuf ) ) != 0 ) {\r
248                     SKP_assert( 0 );\r
249                 }\r
250                 /* Check that no second payload was created */\r
251                 SKP_assert( *nBytesOut == 0 );\r
252             }\r
253             psEnc->sCmn.inputBufIx = 0;\r
254         } else {\r
255             break;\r
256         }\r
257     }\r
258 \r
259     *nBytesOut = MaxBytesOut;\r
260     if( psEnc->sCmn.useDTX && psEnc->sCmn.inDTX ) {\r
261         /* Dtx simulation */\r
262         *nBytesOut = 0;\r
263     }\r
264 \r
265 \r
266     return ret;\r
267 }\r
268 \r