2
* Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
3
* Author: Emmanuel Lepage <emmanuel.lepage@savoirfairelinux.com>
4
* Author: Adrien Beraud <adrien.beraud@wisdomvibes.com>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 3 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
* Additional permission under GNU GPL version 3 section 7:
22
* If you modify this program, or any covered work, by linking or
23
* combining it with the OpenSSL project's OpenSSL library (or a
24
* modified version of that library), containing parts covered by the
25
* terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
26
* grants you additional permission to convey the resulting work.
27
* Corresponding Source for a non-source form of such a combination
28
* shall include the source code for the parts of OpenSSL used as well
29
* as that of the covered work.
31
#include "opuscodec.h"
32
#include "sfl_types.h"
37
constexpr uint32_t Opus::VALID_SAMPLING_RATE[];
39
Opus::Opus() : sfl::AudioCodec(PAYLOAD_TYPE, "opus", CLOCK_RATE, FRAME_SIZE, CHANNELS),
42
lastDecodedFrameSize_(0)
44
hasDynamicPayload_ = true;
45
setOptimalFormat(CLOCK_RATE, 1);
51
opus_encoder_destroy(encoder_);
53
opus_decoder_destroy(decoder_);
62
void Opus::setOptimalFormat(uint32_t sample_rate, uint8_t channels)
64
// Use a SR higher or equal to sample_rate.
65
// Typical case: 44.1kHz => 48kHz.
67
while (i < VALID_SAMPLING_RATE_NUM - 1 and VALID_SAMPLING_RATE[i] < sample_rate)
69
sample_rate = VALID_SAMPLING_RATE[i];
71
// Opus supports 1 or 2 channels.
72
channels = std::max(std::min(channels, (uint8_t) 2), (uint8_t) 1);
74
if (not (!encoder_ || !decoder_ || sample_rate != clockRateCur_ || channels != channelsCur_))
77
clockRateCur_ = sample_rate;
78
channelsCur_ = channels;
82
opus_encoder_destroy(encoder_);
83
encoder_ = opus_encoder_create(sample_rate, channels, OPUS_APPLICATION_VOIP, &err);
85
throw std::runtime_error("opus: could not create encoder");
88
opus_decoder_destroy(decoder_);
89
lastDecodedFrameSize_ = 0;
90
decoder_ = opus_decoder_create(sample_rate, channels, &err);
92
throw std::runtime_error("opus: could not create decoder");
95
// Reference: http://tools.ietf.org/html/draft-spittka-payload-rtp-opus-03#section-6.2
96
// "The RTP clock rate in "a=rtpmap" MUST be 48000..."
97
uint32_t Opus::getSDPClockRate() const
102
// "...and the number of channels MUST be 2."
104
Opus::getSDPChannels() const
109
int Opus::decode(std::vector<std::vector<SFLAudioSample> > &pcm, const uint8_t *data, size_t len)
111
if (data == nullptr) return 0;
114
if (channelsCur_ == 1) {
115
ret = opus_decode(decoder_, data, len, pcm[0].data(), MAX_PACKET_SIZE, 0);
117
std::array<SFLAudioSample, 2 * MAX_PACKET_SIZE> ibuf; // deinterleave on stack, 11.25KiB used.
118
ret = opus_decode(decoder_, data, len, ibuf.data(), MAX_PACKET_SIZE, 0);
119
for (int i = 0; i < ret; i++) {
120
pcm[0][i] = ibuf[2 * i];
121
pcm[1][i] = ibuf[2 * i + 1];
125
std::cerr << opus_strerror(ret) << std::endl;
126
lastDecodedFrameSize_ = ret;
130
int Opus::decode(std::vector<std::vector<SFLAudioSample> > &pcm)
132
if (!lastDecodedFrameSize_) return 0;
134
if (channelsCur_ == 1) {
135
ret = opus_decode(decoder_, nullptr, 0, pcm[0].data(), lastDecodedFrameSize_, 0);
137
std::array<SFLAudioSample, 2 * MAX_PACKET_SIZE> ibuf; // deinterleave on stack, 11.25KiB used.
138
ret = opus_decode(decoder_, nullptr, 0, ibuf.data(), lastDecodedFrameSize_, 0);
139
for (int i = 0; i < ret; i++) {
140
pcm[0][i] = ibuf[2 * i];
141
pcm[1][i] = ibuf[2 * i + 1];
145
std::cerr << opus_strerror(ret) << std::endl;
149
size_t Opus::encode(const std::vector<std::vector<SFLAudioSample> > &pcm, uint8_t *data, size_t len)
151
if (data == nullptr) return 0;
153
if (channelsCur_ == 1) {
154
ret = opus_encode(encoder_, pcm[0].data(), FRAME_SIZE, data, len);
156
std::array<SFLAudioSample, 2 * FRAME_SIZE> ibuf; // interleave on stack, 1.875KiB used;
157
for (unsigned i = 0; i < FRAME_SIZE; i++) {
158
ibuf[2 * i] = pcm[0][i];
159
ibuf[2 * i + 1] = pcm[1][i];
161
ret = opus_encode(encoder_, ibuf.data(), FRAME_SIZE, data, len);
164
std::cerr << opus_strerror(ret) << std::endl;
170
// cppcheck-suppress unusedFunction
171
extern "C" sfl::AudioCodec* AUDIO_CODEC_ENTRY()
175
} catch (const std::runtime_error &e) {
176
std::cerr << e.what() << std::endl;
181
// cppcheck-suppress unusedFunction
182
extern "C" void destroy(sfl::AudioCodec* a)