17 PRETTY_INFO <<
"Initialising the Opus manager" << std::endl;
18 PRETTY_INFO <<
"Initialising the encoder..." << std::endl;
19 _encoder = opus_encoder_create(
20 static_cast<opus_int32
>(48000),
22 OPUS_APPLICATION_AUDIO,
25 if (_error != OPUS_OK) {
26 PRETTY_ERROR <<
"Opus encoder initialization error: " << opus_strerror(_error) << std::endl;
27 handleOpusError(_error,
"Opus encoder initialization");
31 PRETTY_INFO <<
"Initialising the decoder..." << std::endl;
33 _decoder = opus_decoder_create(
34 static_cast<opus_int32
>(48000),
38 if (_error != OPUS_OK) {
39 handleOpusError(_error,
"Opus decoder initialization");
47 PRETTY_INFO <<
"Initialising the Opus manager" << std::endl;
50 throw std::invalid_argument(
"Invalid sample rate, supported values are 24000 and 48000.");
54 throw std::invalid_argument(
"Invalid number of channels, supported values are 1 (mono) or 2 (stereo).");
58 PRETTY_INFO <<
"Initialising the encoder..." << std::endl;
59 _encoder = opus_encoder_create(
62 OPUS_APPLICATION_AUDIO,
65 if (_error != OPUS_OK) {
66 handleOpusError(_error,
"Opus encoder initialization");
70 PRETTY_INFO <<
"Initialising the decoder..." << std::endl;
72 _decoder = opus_decoder_create(
77 if (_error != OPUS_OK) {
78 handleOpusError(_error,
"Opus decoder initialization");
86 PRETTY_INFO <<
"Destroying the Opus manager" << std::endl;
88 PRETTY_INFO <<
"Destroying the encoder..." << std::endl;
89 opus_encoder_destroy(_encoder);
92 PRETTY_INFO <<
"Checking if the decoder exists..." << std::endl;
94 PRETTY_INFO <<
"Destroying the decoder..." << std::endl;
95 opus_decoder_destroy(_decoder);
108 PRETTY_INFO <<
"Setting the maximum packet size to " << maxPacketSize << std::endl;
109 _maxPacketSize = maxPacketSize;
120 PRETTY_INFO <<
"Fetching the maximum packet size" << std::endl;
121 return _maxPacketSize;
129 PRETTY_INFO <<
"Checking materials before compressing..." << std::endl;
130 if (!_rawStreamSet) {
131 PRETTY_ERROR <<
"Uncompressed stream not set" << std::endl;
132 std::cerr <<
"Uncompressed stream not set" << std::endl;
133 throw std::runtime_error(
"Uncompressed stream not set");
136 PRETTY_DEBUG <<
"Checking if the encoder exists..." << std::endl;
139 std::cerr <<
"Encoder not set" << std::endl;
140 throw std::runtime_error(
"Encoder not set");
143 PRETTY_INFO <<
"Locking the mutex..." << std::endl;
144 std::lock_guard<std::mutex> lock(_mutex);
146 PRETTY_INFO <<
"Initialising the compressed stream..." << std::endl;
147 const int maxPacketSize = _maxPacketSize;
148 int frameSize = _uncompressedStream.framesPerBuffer * (_uncompressedStream.numChannelsRecording == 2 ? 2 : 1);
150 PRETTY_DEBUG <<
"Check if the uncompressed stream has enough data" << std::endl;
151 if (_uncompressedStream.sample.size() < frameSize * _uncompressedStream.numChannelsRecording) {
152 PRETTY_ERROR <<
"Uncompressed stream size is insufficient for encoding" << std::endl;
153 std::cerr <<
"Uncompressed stream size is insufficient for encoding" << std::endl;
156 PRETTY_DEBUG <<
"Max packet size: " << maxPacketSize <<
", frameSize: " << frameSize << std::endl;
157 _compressedStream.data.resize(maxPacketSize);
159 PRETTY_DEBUG <<
"Compressed stream size: " << _compressedStream.data.size() << std::endl;
160 PRETTY_DEBUG <<
"Uncompressed sample data size: " << _uncompressedStream.sample.size() << std::endl;
162 PRETTY_INFO <<
"Compressing the stream..." << std::endl;
163 int compressedSize = opus_encode_float(_encoder, _uncompressedStream.sample.data(), frameSize, _compressedStream.data.data(), maxPacketSize);
164 PRETTY_DEBUG <<
"Compressed size: " << compressedSize << std::endl;
165 if (compressedSize < 0) {
166 PRETTY_ERROR <<
"Opus encode error: " << opus_strerror(compressedSize) << std::endl;
167 std::cerr <<
"Opus encode error: " << opus_strerror(compressedSize) << std::endl;
171 PRETTY_INFO <<
"Setting the compressed stream size..." << std::endl;
172 _compressedStream.size = compressedSize;
173 _compressedStream.data.resize(compressedSize);
174 _hasBeenCompressed =
true;
183 PRETTY_INFO <<
"Decompressing the stream..." << std::endl;
184 if (!_hasBeenCompressed) {
185 PRETTY_ERROR <<
"Compressed stream not set" << std::endl;
186 std::cerr <<
"Compressed stream not set" << std::endl;
187 throw std::runtime_error(
"Compressed stream not set");
190 PRETTY_INFO <<
"Locking the mutex..." << std::endl;
191 std::lock_guard<std::mutex> lock(_mutex);
193 PRETTY_INFO <<
"Initialising the uncompressed stream..." << std::endl;
194 int frameSize = _uncompressedStream.framesPerBuffer;
195 _uncompressedStream.sample.resize(frameSize * _uncompressedStream.numChannelsPlayback);
197 PRETTY_INFO <<
"Decompressing the stream..." << std::endl;
198 int decodedSamples = opus_decode_float(_decoder, _compressedStream.data.data(), _compressedStream.size, _uncompressedStream.sample.data(), frameSize, 0);
199 if (decodedSamples < 0) {
200 PRETTY_ERROR <<
"Opus decode error: " << opus_strerror(decodedSamples) << std::endl;
201 std::cerr <<
"Opus decode error: " << opus_strerror(decodedSamples) << std::endl;
205 _rawStreamSet =
true;
216 PRETTY_INFO <<
"Fetching the compressed stream" << std::endl;
217 if (!_hasBeenCompressed) {
218 PRETTY_ERROR <<
"Compressed stream not set" << std::endl;
219 std::cerr <<
"Compressed stream not set" << std::endl;
220 throw std::runtime_error(
"Compressed stream not set");
223 return _compressedStream;
233 PRETTY_INFO <<
"Setting the compressed stream" << std::endl;
234 std::lock_guard<std::mutex> lock(_mutex);
235 _compressedStream = data;
236 _hasBeenCompressed =
true;
247 PRETTY_INFO <<
"Fetching the uncompressed stream" << std::endl;
248 if (!_rawStreamSet) {
249 PRETTY_ERROR <<
"Uncompressed stream not set" << std::endl;
250 std::cerr <<
"Uncompressed stream not set" << std::endl;
251 throw std::runtime_error(
"Uncompressed stream not set");
254 return _uncompressedStream;
264 PRETTY_INFO <<
"Setting the uncompressed stream" << std::endl;
267 throw std::invalid_argument(
"Invalid sample rate, supported values are 24000 and 48000.");
271 throw std::invalid_argument(
"Invalid number of channels, supported values are 1 (mono) or 2 (stereo).");
274 std::lock_guard<std::mutex> lock(_mutex);
275 _uncompressedStream = data;
276 _rawStreamSet =
true;
288 PRETTY_INFO <<
"Encoding the sound..." << std::endl;
290 const int framesPerBuffer = 480;
291 std::array<unsigned char, 4000> cbits;
297 nbBytes = opus_encode_float(_encoder, sound.data(), framesPerBuffer, cbits.data(), 4000);
300 handleOpusError(nbBytes,
"failed to encode float ");
302 for (
int i = 0; i != nbBytes; i++) {
303 output.push_back(cbits[i]);
350 PRETTY_INFO <<
"Decoding the sound..." << std::endl;
352 const int cbit_length = 4000;
353 std::array<float, cbit_length> cbits;
359 nbBytes = opus_decode_float(_decoder, sound.data(), sound.size(), cbits.data(), cbit_length, 0);
362 handleOpusError(nbBytes,
"failed to decode float ");
364 for (
int i = 0; i != nbBytes; i++) {
365 PRETTY_DEBUG <<
"Decoded sound: " << cbits[i] << std::endl;
366 output.push_back(cbits[i]);
377void Compressor::Manager::handleOpusError(
int errorCode,
const std::string &context)
const
379 PRETTY_INFO <<
"Handling Opus error..." << std::endl;
380 if (errorCode != OPUS_OK) {
381 throw std::runtime_error(context +
" failed: " + opus_strerror(errorCode));
#define PRETTY_ERROR
Error log with details and colour.
#define PRETTY_DEBUG
Debug log with details and colour.
#define PRETTY_INFO
Info log with details and colour.
#define PRETTY_WARNING
Warning log with details and colour.
#define PRETTY_SUCCESS
Success log with details and colour.
This file contains the definition of the Manager class responsible for managing audio compression and...
void decompress()
Decompress the compressed audio stream.
const Audio::Sample & getUncompressedStream() const
Get the uncompressed audio stream.
void decode(std::vector< unsigned char > &sound, std::vector< float > &output)
Decode compressed audio data into raw format.
void compress()
Compress the uncompressed audio stream.
void setUncompressedStream(const Audio::Sample &data)
Set the uncompressed audio stream.
void setMaxPacketSize(const unsigned int maxPacketSize)
Set the maximum packet size for compression.
void encode(std::vector< float > &sound, std::vector< unsigned char > &output)
Encode raw audio data into compressed format.
void setCompressedStream(const Compressor::Packet &data)
Set the compressed audio stream.
const unsigned int getMaxPacketSize() const
Get the maximum packet size for compression.
const Compressor::Packet & getCompressedStream() const
Get the compressed audio stream.
Manager()
Default constructor.
Structure representing an audio sample.
unsigned int numChannelsPlayback
Number of playback channels.
unsigned int sampleRate
Sample rate of the audio in Hz.
Structure representing a packet of compressed audio data.