2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
11 #include "opus_interface.h"
18 #include "neteq_defines.h"
19 #include "signal_processing_library.h"
20 #include "resample_by_2_internal.h"
22 /* We always produce 20ms frames. */
23 #define WEBRTC_OPUS_MAX_ENCODE_FRAME_SIZE_MS (20)
25 /* The format allows up to 120ms frames. Since we
26 * don't control the other side, we must allow
27 * for packets that large. NetEq is currently
28 * limited to 60 ms on the receive side.
30 #define WEBRTC_OPUS_MAX_DECODE_FRAME_SIZE_MS (120)
32 /* Sample count is 48 kHz * FRAME_SIZE_MS. */
33 #define WEBRTC_OPUS_MAX_FRAME_SIZE (48*WEBRTC_OPUS_MAX_DECODE_FRAME_SIZE_MS)
35 struct WebRTCOpusEncInst
{
36 int32_t state_32_64
[8];
37 int32_t state_64_48
[8];
41 int16_t WebRtcOpus_EncoderCreate(OpusEncInst
**inst
,
45 state
= (OpusEncInst
*)calloc(1, sizeof(*state
));
48 state
->encoder
= opus_encoder_create(48000, channels
,
49 OPUS_APPLICATION_VOIP
, &error
);
50 if (error
== OPUS_OK
&& state
->encoder
!= NULL
) {
59 int16_t WebRtcOpus_EncoderFree(OpusEncInst
*inst
)
61 opus_encoder_destroy(inst
->encoder
);
66 int16_t WebRtcOpus_EncodeNative(OpusEncInst
*inst
,
69 int16_t encodedLenByte
,
72 opus_int16
*audio
= (opus_int16
*)audioIn
;
73 unsigned char *coded
= encoded
;
75 int res
= opus_encode(inst
->encoder
, audio
, len
, coded
, encodedLenByte
);
84 int16_t WebRtcOpus_Encode(OpusEncInst
*inst
,
87 int16_t encodedLenByte
,
90 int16_t buffer16
[48*WEBRTC_OPUS_MAX_ENCODE_FRAME_SIZE_MS
];
91 int32_t buffer32
[64*WEBRTC_OPUS_MAX_ENCODE_FRAME_SIZE_MS
+7];
94 if (len
> 32*WEBRTC_OPUS_MAX_ENCODE_FRAME_SIZE_MS
) {
97 /* Resample 32 kHz to 64 kHz. */
98 for(i
= 0; i
< 7; i
++) {
99 buffer32
[i
] = inst
->state_64_48
[i
];
101 WebRtcSpl_UpBy2ShortToInt(audioIn
, len
, buffer32
+7, inst
->state_32_64
);
102 /* Resample 64 kHz to 48 kHz. */
103 for(i
= 0; i
< 7; i
++) {
104 inst
->state_64_48
[i
] = buffer32
[2*len
+i
];
107 WebRtcSpl_Resample32khzTo24khz(buffer32
, buffer32
, len
);
109 WebRtcSpl_VectorBitShiftW32ToW16(buffer16
, len
, buffer32
, 15);
111 return WebRtcOpus_EncodeNative(inst
, buffer16
,
112 encoded
, encodedLenByte
, len
);
115 int16_t WebRtcOpus_SetBitRate(OpusEncInst
*inst
, int32_t rate
)
117 return opus_encoder_ctl(inst
->encoder
, OPUS_SET_BITRATE(rate
));
121 struct WebRTCOpusDecInst
{
122 int16_t state_48_32
[8];
123 OpusDecoder
*decoder
;
126 int16_t WebRtcOpus_DecoderCreate(OpusDecInst
**inst
,
131 state
= (OpusDecInst
*)calloc(1 ,sizeof(*state
));
134 state
->decoder
= opus_decoder_create(48000, channels
, &error
);
135 if (error
== OPUS_OK
&& state
->decoder
!= NULL
) {
144 int16_t WebRtcOpus_DecoderFree(OpusDecInst
*inst
)
146 opus_decoder_destroy(inst
->decoder
);
151 int16_t WebRtcOpus_DecoderInit(OpusDecInst
* inst
)
153 int error
= opus_decoder_ctl(inst
->decoder
, OPUS_RESET_STATE
);
154 if(error
== OPUS_OK
) {
155 memset(inst
->state_48_32
,0,sizeof(inst
->state_48_32
));
161 int16_t WebRtcOpus_DecodeNative(OpusDecInst
*inst
,
167 unsigned char *coded
= (unsigned char *)encoded
;
168 opus_int16
*audio
= (opus_int16
*)decoded
;
170 int res
= opus_decode(inst
->decoder
, coded
, len
, audio
,
171 WEBRTC_OPUS_MAX_FRAME_SIZE
, 0);
172 /* TODO: set to DTX for zero-length packets? */
182 int16_t WebRtcOpus_Decode(OpusDecInst
*inst
,
188 /* Enough for 120 ms (the largest Opus packet size) of mono audio at 48 kHz.
189 * This will need to be enlarged for stereo decoding. */
190 int16_t buffer16
[WEBRTC_OPUS_MAX_FRAME_SIZE
];
191 int32_t buffer32
[WEBRTC_OPUS_MAX_FRAME_SIZE
+7];
194 int16_t outputSamples
;
197 /* Decode to a temporary buffer. */
199 WebRtcOpus_DecodeNative(inst
, encoded
, len
, buffer16
, audioType
);
200 if (decodedSamples
< 0) {
203 /* Resample from 48 kHz to 32 kHz. */
204 for (i
= 0; i
< 7; i
++) {
205 buffer32
[i
] = inst
->state_48_32
[i
];
207 for (i
= 0; i
< decodedSamples
; i
++) {
208 buffer32
[7+i
] = buffer16
[i
];
210 for (i
= 0; i
< 7; i
++) {
211 inst
->state_48_32
[i
] = (int16_t)buffer32
[decodedSamples
+i
];
213 blocks
= decodedSamples
/3;
214 WebRtcSpl_Resample48khzTo32khz(buffer32
, buffer32
, blocks
);
215 outputSamples
= (int16_t)(blocks
*2);
216 WebRtcSpl_VectorBitShiftW32ToW16(decoded
, outputSamples
, buffer32
, 15);
218 return outputSamples
;
222 int16_t WebRtcOpus_DecodePlc(OpusDecInst
*inst
,
224 int16_t noOfLostFrames
)
226 /* TODO: We can pass NULL to opus_decode to activate packet
227 * loss concealment, but I don't know how many samples
228 * noOfLostFrames corresponds to. */
232 int16_t WebRtcOpus_Version(char *version
, int16_t lenBytes
)
234 const char *opus
= opus_get_version_string();
236 if (opus
== NULL
|| version
== NULL
|| lenBytes
< 0) {
240 strncpy(version
, opus
, lenBytes
);
241 version
[lenBytes
-1] = '\0';