1 /*************************************************************************
2     OpusEncoder.cpp  -  sub encoder base class for Opus in an Ogg container
3                              -------------------
4     begin                : Thu Jan 03 2013
5     copyright            : (C) 2013 by Thomas Eschenbacher
6     email                : Thomas.Eschenbacher@gmx.de
7 
8  ***************************************************************************
9  *                                                                         *
10  *   This program is free software; you can redistribute it and/or modify  *
11  *   it under the terms of the GNU General Public License as published by  *
12  *   the Free Software Foundation; either version 2 of the License, or     *
13  *   (at your option) any later version.                                   *
14  *                                                                         *
15  ***************************************************************************
16 
17     parts based on source snippets taken from "opusenc.c", opus-tools-0.1.5
18    -------------------------------------------------------------------------
19    Copyright (C) 2002-2011 Jean-Marc Valin <jmvalin@jmvalin.ca>
20    Copyright (C) 2007-2012 Xiph.Org Foundation <monty@xiph.org/>
21    Copyright (C) 2008-2012 Gregory Maxwell <greg@xiph.org>
22    File: opusenc.c
23 
24    Redistribution and use in source and binary forms, with or without
25    modification, are permitted provided that the following conditions
26    are met:
27 
28    - Redistributions of source code must retain the above copyright
29    notice, this list of conditions and the following disclaimer.
30 
31    - Redistributions in binary form must reproduce the above copyright
32    notice, this list of conditions and the following disclaimer in the
33    documentation and/or other materials provided with the distribution.
34 
35    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
39    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
40    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
41    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
42    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
43    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
44    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
45    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46 
47  ***************************************************************************/
48 
49 #include "config.h"
50 
51 #include <math.h>
52 #include <string.h>
53 #include <new>
54 
55 #include <opus/opus_defines.h>
56 
57 #include <QApplication>
58 #include <QBuffer>
59 #include <QByteArray>
60 #include <QList>
61 #include <QRandomGenerator>
62 #include <QString>
63 #include <QTime>
64 #include <QtGlobal>
65 #include <QtEndian>
66 
67 #include <KLocalizedString>
68 
69 #include "libkwave/BitrateMode.h"
70 #include "libkwave/Connect.h"
71 #include "libkwave/MessageBox.h"
72 #include "libkwave/MultiTrackReader.h"
73 #include "libkwave/Sample.h"
74 #include "libkwave/SampleArray.h"
75 #include "libkwave/Utils.h"
76 #include "libkwave/modules/ChannelMixer.h"
77 #include "libkwave/modules/RateConverter.h"
78 
79 #include "OpusCommon.h"
80 #include "OpusEncoder.h"
81 
82 /** lowest supported bitrate */
83 #define BITRATE_MIN 500
84 
85 /** highest supported bitrate */
86 #define BITRATE_MAX 256000
87 
88 /** lowest (reasonable) supported sample rate */
89 #define SAMPLE_RATE_MIN 1000
90 
91 /** highest (reasonable) supported sample rate */
92 #define SAMPLE_RATE_MAX 512000
93 
94 /** default encoder complexity */
95 #define DEFAULT_COMPLEXITY 10
96 
97 /***************************************************************************/
OpusEncoder()98 Kwave::OpusEncoder::OpusEncoder()
99     :m_comments_map(),
100      m_info(),
101      m_downmix(DOWNMIX_AUTO),
102      m_bitrate(0),
103      m_coding_rate(0),
104      m_encoder_channels(0),
105      m_channel_mixer(Q_NULLPTR),
106      m_rate_converter(Q_NULLPTR),
107      m_frame_size(0),
108      m_extra_out(0),
109      m_opus_header(),
110      m_max_frame_bytes(0),
111      m_packet_buffer(Q_NULLPTR),
112      m_encoder(Q_NULLPTR),
113      m_encoder_input(Q_NULLPTR),
114      m_last_queue_element(Q_NULLPTR),
115      m_buffer(Q_NULLPTR)
116 {
117 
118     memset(&m_opus_header, 0x00, sizeof(m_opus_header));
119     memset(&m_opus_header.map, 0xFF, sizeof(m_opus_header.map));
120 }
121 
122 /***************************************************************************/
~OpusEncoder()123 Kwave::OpusEncoder::~OpusEncoder()
124 {
125 }
126 
127 /***************************************************************************/
setupDownMix(QWidget * widget,unsigned int tracks,int bitrate)128 bool Kwave::OpusEncoder::setupDownMix(QWidget *widget, unsigned int tracks,
129                                       int bitrate)
130 {
131     // get "downmix" setting, default is "auto"
132     m_downmix = DOWNMIX_AUTO; // currently not user configurable
133 
134     if ((m_downmix == DOWNMIX_AUTO) &&
135 	(bitrate > 0) && (bitrate < (32000 * Kwave::toInt(tracks))))
136     {
137 	if (tracks > 8) {
138 	    // downmix from more than 8 channels to mono
139 	    if (Kwave::MessageBox::warningContinueCancel(
140 		widget,
141 		i18n("Surround bitrate would be less than 32kBit/sec per "
142 		      "channel, this file should be mixed down to mono."),
143 		QString(), QString(), QString(),
144 		_("opus_accept_down_mix_on_export")) != KMessageBox::Continue)
145 	    {
146 		return false;
147 	    }
148 	    m_downmix = DOWNMIX_MONO;
149 	} else if (tracks > 2) {
150 	    // downmix from more than stereo to stereo
151 	    if (Kwave::MessageBox::warningContinueCancel(
152 		widget,
153 		i18n("Surround bitrate would be less than 32kBit/sec per "
154 		      "channel, this file should be mixed down to stereo."),
155 		QString(), QString(), QString(),
156 		_("opus_accept_down_mix_on_export")) != KMessageBox::Continue)
157 	    {
158 		return false;
159 	    }
160 	    m_downmix = DOWNMIX_STEREO;
161 	}
162     }
163     if (m_downmix == DOWNMIX_AUTO) // if still "auto"
164 	m_downmix = DOWNMIX_OFF;   // then switch it off
165 
166     switch (m_downmix) {
167 	case DOWNMIX_MONO:   m_encoder_channels = 1;      break;
168 	case DOWNMIX_STEREO: m_encoder_channels = 2;      break;
169 	default:             m_encoder_channels = tracks; break;
170     }
171 
172     if (m_encoder_channels != tracks) {
173 	// create a channel mixer
174 	m_channel_mixer = new(std::nothrow)
175 	    Kwave::ChannelMixer(tracks, m_encoder_channels);
176 	Q_ASSERT(m_channel_mixer);
177 	if (!m_channel_mixer || !m_channel_mixer->init()) {
178 	    qWarning("creating channel mixer failed");
179 	    return false;
180 	}
181 
182 	// connect it to the end of the current preprocessing queue
183 	// (normally this is the original sample source)
184 	if (!Kwave::connect(
185 	    *m_last_queue_element, SIGNAL(output(Kwave::SampleArray)),
186 	    *m_channel_mixer,      SLOT(input(Kwave::SampleArray))))
187 	{
188 	    qWarning("connecting the channel mixer failed");
189 	    return false;
190 	}
191 	m_last_queue_element = m_channel_mixer;
192     }
193 
194     return true;
195 }
196 
197 /***************************************************************************/
setupBitrate(QWidget * widget,unsigned int tracks)198 bool Kwave::OpusEncoder::setupBitrate(QWidget *widget, unsigned int tracks)
199 {
200     int bitrate_nominal = m_info.contains(Kwave::INF_BITRATE_NOMINAL) ?
201         QVariant(m_info.get(Kwave::INF_BITRATE_NOMINAL)).toInt() : -1;
202     int bitrate_lower = m_info.contains(Kwave::INF_BITRATE_LOWER) ?
203         QVariant(m_info.get(Kwave::INF_BITRATE_LOWER)).toInt() : -1;
204     int bitrate_upper = m_info.contains(Kwave::INF_BITRATE_UPPER) ?
205         QVariant(m_info.get(Kwave::INF_BITRATE_UPPER)).toInt() : -1;
206 
207     // prefer bitrates in this order:
208     // nominal -> upper -> lower -> "auto" (-1)
209     int bitrate = -1;
210     if (bitrate_nominal > 0) bitrate = bitrate_nominal;
211     else if (bitrate_upper   > 0) bitrate = bitrate_upper;
212     else if (bitrate_lower   > 0) bitrate = bitrate_lower;
213 
214     if ((bitrate > 0) && ((bitrate > (BITRATE_MAX * Kwave::toInt(tracks)))
215         || (bitrate < BITRATE_MIN)))
216     {
217 	int bitrate_new =
218 	    qBound<int>(BITRATE_MIN, bitrate, BITRATE_MAX * tracks);
219 
220 	if (Kwave::MessageBox::warningContinueCancel(
221 	    widget,
222 	    i18nc("%1=original bitrate, %2=new/limited bitrate",
223 	          "Bitrate %1 kBit/sec is out of range, "
224 	          "limited to %2 kBit/sec",
225 	           bitrate / 1000,
226 	           bitrate_new / 1000),
227 	    QString(), QString(), QString(),
228 	    _("opus_bitrate_limit"))  != KMessageBox::Continue)
229 	{
230 	    return false;
231 	}
232     }
233 
234     if (bitrate > 0)
235 	qDebug("    OpusEncoder: bitrate %d bits/sec (configured)", bitrate);
236     m_bitrate = bitrate;
237     return true;
238 }
239 
240 /***************************************************************************/
setupCodingRate(QWidget * widget,unsigned int tracks,double rate)241 bool Kwave::OpusEncoder::setupCodingRate(QWidget *widget,
242                                          unsigned int tracks, double rate)
243 {
244     Q_UNUSED(widget)
245 
246     Q_ASSERT(!m_rate_converter);
247 
248     int rate_orig = Kwave::toInt(rate);
249     int rate_supp = Kwave::opus_next_sample_rate(rate_orig);
250 
251     m_coding_rate = rate_supp;
252 
253     if (rate_orig == rate_supp) {
254    	qDebug("    OpusEncoder: using sample rate %d", rate_orig);
255 	return true; // no conversion needed :-)
256     }
257 
258     double rate_from = static_cast<double>(rate_orig);
259     double rate_to   = static_cast<double>(rate_supp);
260     double ratio     = rate_to / rate_from;
261 
262     qDebug("    OpusEncoder: converting sample rate: %d -> %d",
263            rate_orig, rate_supp);
264 
265     // range check: conversion ration must be between 1/256 and 256
266     if ((ratio < (1.0 / 256.0)) || (ratio > 256.0)) {
267 	int lowest  = qMin<int>(SAMPLE_RATE_MIN,
268 	                        Kwave::toInt(ceil( rate_to / 256.0)));
269 	int highest = qMax<int>(Kwave::toInt(floor(rate_to * 256.0)),
270 	                        SAMPLE_RATE_MAX);
271 	Kwave::MessageBox::sorry(
272 	    widget,
273 	    i18nc("%1=requested sample rate, "
274 	          "%2=lowest supported, %3=highest supported",
275 	          "Sample rate %1 samples/sec is out of range,\n"
276 	          "supported are %2 ... %3 samples/sec.",
277 	           rate_supp, lowest, highest),
278 	    QString()
279 	);
280 	return false;
281     }
282 
283     // create a new rate converter
284     m_rate_converter = new(std::nothrow)
285 	Kwave::MultiTrackSource<Kwave::RateConverter, true>(tracks);
286     Q_ASSERT(m_rate_converter);
287     if (!m_rate_converter)
288 	return false;
289 
290     m_rate_converter->setAttribute(
291 	SLOT(setRatio(QVariant)),
292 	QVariant(ratio)
293     );
294 
295     // connect the rate converter to the end of the current preprocessing
296     // queue/ (normally this is either the original sample source or
297     // a channel mixer)
298     if (!Kwave::connect(
299 	*m_last_queue_element, SIGNAL(output(Kwave::SampleArray)),
300 	*m_rate_converter,     SLOT(input(Kwave::SampleArray))))
301     {
302 	qWarning("connecting the rate converter failed");
303 	return false;
304     }
305     m_last_queue_element = m_rate_converter;
306 
307     return true;
308 }
309 
310 /***************************************************************************/
setupEncoder(QWidget * widget,unsigned int tracks,double rate)311 bool Kwave::OpusEncoder::setupEncoder(QWidget *widget, unsigned int tracks,
312                                       double rate)
313 {
314     // get the frame size in ms if present,
315     // otherwise fall back to the default of 20ms
316     // (supported values are 2.5, 5, 10, 20, 40, or 60 ms)
317     qreal ms_per_frame = 20.0; // default is 20ms
318     if (m_info.contains(INF_OPUS_FRAME_LEN)) {
319 	double len = m_info.get(INF_OPUS_FRAME_LEN).toDouble();
320 	if (len >= 60)
321 	    ms_per_frame = 60.0;
322 	else if (len >= 40)
323 	    ms_per_frame = 40.0;
324 	else if (len >= 20)
325 	    ms_per_frame = 20.0;
326 	else if (len >= 5)
327 	    ms_per_frame = 5;
328 	else
329 	    ms_per_frame = 2.5;
330    	qDebug("    OpusEncoder: %0.1f ms/frame", ms_per_frame);
331     } else {
332 	ms_per_frame = 20.0; // <- default
333    	qDebug("    OpusEncoder: %0.1f ms/frame (default)", ms_per_frame);
334     }
335 
336     // calculate the frame size in samples from the frame duration in ms
337     // = frame_length [ms] * bitrate [bits/sec] / 1000 [ms/sec]
338     m_frame_size = Kwave::toUint(
339 	(ms_per_frame * m_coding_rate) / 1000);
340 
341     if (tracks > 255) {
342 	qWarning("too many tracks: %u, supported: 255", tracks);
343 	return false; // more than 255 tracks are not supported
344     }
345 
346     // fill out all header fields
347     m_opus_header.channels        = static_cast<quint8>(tracks);
348     m_opus_header.preskip         = 0;
349     m_opus_header.sample_rate     = static_cast<quint32>(rate);
350     m_opus_header.gain            = 0;
351     m_opus_header.channel_mapping = 255;
352     m_opus_header.streams         = static_cast<quint8>(tracks);
353     m_opus_header.coupled         = 0;
354 
355     // determine channel mapping and coupling
356     quint8 force_narrow = 0x00;
357     if (tracks <= 8) {
358 	/* apply a mapping as done in opusenc.c from opus-tools-0.1.5 */
359 	static const quint8 opusenc_streams[8][10]= {
360 	    /*       Coupled,   NB_bitmap, mapping...*/
361 	    /* 1 */ {0,         0,         0                      },
362 	    /* 2 */ {1,         0,         0, 1                   },
363 	    /* 3 */ {1,         0,         0, 2, 1                },
364 	    /* 4 */ {2,         0,         0, 1, 2, 3             },
365 	    /* 5 */ {2,         0,         0, 4, 1, 2, 3          },
366 	    /* 6 */ {2,    1 << 3,         0, 4, 1, 2, 3, 5       },
367 	    /* 7 */ {2,    1 << 4,         0, 4, 1, 2, 3, 5, 6    },
368 	    /* 8 */ {3,    1 << 4,         0, 6, 1, 2, 3, 4, 5, 7 }
369 	};
370 	for (unsigned int i = 0; i < tracks; i++)
371 	    m_opus_header.map[i] = opusenc_streams[tracks - 1][i + 2];
372 	force_narrow = opusenc_streams[tracks - 1][1];
373 	m_opus_header.coupled         = opusenc_streams[tracks - 1][0];
374 	m_opus_header.streams         = static_cast<quint8>(
375 	    tracks - m_opus_header.coupled);
376 	m_opus_header.channel_mapping = (m_opus_header.streams > 1);
377 
378    	qDebug("    OpusEncoder: %d stream(s) / %d coupled (mapping=%d)",
379 	       m_opus_header.streams, m_opus_header.coupled,
380 	       m_opus_header.channel_mapping);
381     } else {
382 	/* map all channels 1:1 */
383 	for (quint8 i = 0; i < m_opus_header.channels; ++i)
384 	    m_opus_header.map[i] = i;
385    	qDebug("    OpusEncoder: mapping channels 1:1");
386     }
387 
388     // allocate a packet buffer
389     m_max_frame_bytes = ((1275 * 3) + 7) * m_opus_header.streams;
390     qDebug("    OpusEncoder: max frame size %u bytes", m_max_frame_bytes);
391     Q_ASSERT(!m_packet_buffer);
392     m_packet_buffer = static_cast<unsigned char *>(malloc(m_max_frame_bytes));
393     if (!m_packet_buffer) {
394 	Kwave::MessageBox::error(widget, i18n("Out of memory"));
395 	return false;
396     }
397 
398     // initialize the Opus encoder:
399     // frame sizes < 10ms can only use the MDCT modes,
400     // so we switch on RESTRICTED_LOWDELAY to save the extra 2.5ms of codec
401     // lookahead when we'll be using only small frames
402 
403     int err = OPUS_ALLOC_FAIL;
404     Q_ASSERT(!m_encoder);
405     m_encoder = opus_multistream_encoder_create(
406 	m_coding_rate,
407 	tracks,
408 	m_opus_header.streams,
409 	m_opus_header.coupled,
410 	m_opus_header.map,
411 	(ms_per_frame < 10.0) ? OPUS_APPLICATION_RESTRICTED_LOWDELAY :
412 	                        OPUS_APPLICATION_AUDIO,
413 	&err
414     );
415     if (err != OPUS_OK) {
416 	Kwave::MessageBox::error(widget, Kwave::opus_error(err),
417 	     i18n("Opus encoder failed"));
418 	return false;
419     }
420 
421     if (force_narrow) {
422 	for (unsigned int i = 0; i < m_opus_header.streams; i++ ) {
423 	    if (force_narrow & (1 << i)) {
424                 ::OpusEncoder *oe = Q_NULLPTR;
425 
426 		opus_multistream_encoder_ctl(
427 		    m_encoder,
428 		    OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST, i, &oe
429 		);
430 
431 		int err_ctl = opus_encoder_ctl(oe,
432 		    OPUS_SET_MAX_BANDWIDTH_REQUEST, OPUS_BANDWIDTH_NARROWBAND);
433 
434 		if (err_ctl != OPUS_OK) {
435 		    Kwave::MessageBox::error(widget, Kwave::opus_error(err_ctl),
436 			i18n("Opus encoder failed"));
437 		    return false;
438 		}
439 	    }
440 	}
441     }
442 
443     // allocate a buffer to be used as input of the encoder
444     m_encoder_input = static_cast<float *>(
445 	malloc(sizeof(float) * m_frame_size * tracks));
446     if (!m_encoder_input) {
447 	Kwave::MessageBox::error(widget, i18n("Out of memory"));
448 	return false;
449     }
450 
451     return true;
452 }
453 
454 /***************************************************************************/
setupBitrateMode(QWidget * widget)455 bool Kwave::OpusEncoder::setupBitrateMode(QWidget *widget)
456 {
457     const bool with_cvbr = false;
458     int err;
459 
460     // determine a reasonable bitrate in case we still use "autodetect"
461     if (m_bitrate < 0) {
462 	m_bitrate = (64000 * m_opus_header.streams) +
463 	            (32000 * m_opus_header.coupled);
464 	m_bitrate = qBound<int>(500, m_bitrate, 256000);
465 	qDebug("    OpusEncoder: bitrate %d bits/sec (auto)", m_bitrate);
466     }
467 
468     err = opus_multistream_encoder_ctl(m_encoder, OPUS_SET_BITRATE(
469 	static_cast<opus_int32>(m_bitrate)));
470     if (err != OPUS_OK) {
471 	Kwave::MessageBox::error(widget,
472 	    i18n("Opus encoder failed setting bitrate: '%1'",
473 	         Kwave::opus_error(err)));
474 	return false;
475     }
476 
477     int bitrate_mode = m_info.get(INF_BITRATE_MODE).toInt();
478     bool with_hard_cbr = (bitrate_mode == BITRATE_MODE_CBR_HARD);
479 
480     err = opus_multistream_encoder_ctl(m_encoder, OPUS_SET_VBR(
481 	static_cast<opus_int32>(with_hard_cbr ? 0 : 1)));
482     if (err != OPUS_OK) {
483 	Kwave::MessageBox::error(widget,
484 	    i18n("Opus encoder failed configuring VBR mode: '%1'",
485 	         Kwave::opus_error(err)));
486 	return false;
487     }
488 
489     if (!with_hard_cbr ) {
490         err = opus_multistream_encoder_ctl(m_encoder, OPUS_SET_VBR_CONSTRAINT(
491 	    static_cast<opus_int32>(with_cvbr ? 1 : 0)));
492 	if (err != OPUS_OK) {
493 	    Kwave::MessageBox::error(widget,
494 		i18n("Opus encoder failed configuring VBR constraint: '%1'",
495 		    Kwave::opus_error(err)));
496 	    return false;
497 	}
498     }
499 
500     return true;
501 }
502 
503 /***************************************************************************/
open(QWidget * widget,const Kwave::FileInfo & info,Kwave::MultiTrackReader & src)504 bool Kwave::OpusEncoder::open(QWidget *widget, const Kwave::FileInfo &info,
505                               Kwave::MultiTrackReader &src)
506 {
507     // get info: tracks, sample rate, bitrate(s)
508     m_info = info;
509     const unsigned int src_tracks  = m_info.tracks();
510     const double       sample_rate = m_info.rate();
511     int err;
512 
513     // reset everything to defaults
514     m_downmix            = DOWNMIX_AUTO;
515     m_bitrate            = -1;
516     m_coding_rate        = 0;
517     m_extra_out          = 0;
518     m_frame_size         = 0;
519     memset(&m_opus_header, 0x00, sizeof(m_opus_header));
520     memset(&m_opus_header.map, 0xFF, sizeof(m_opus_header.map));
521     m_max_frame_bytes    = 0;
522     m_last_queue_element = &src;
523 
524     // get the desired bitrate
525     if (!setupBitrate(widget, src_tracks))
526 	return false;
527 
528     // determine the down mixing mode
529     // and set up the mixer if necessary
530     if (!setupDownMix(widget, src_tracks, m_bitrate))
531 	return false;
532 
533     // determine the decoding sample rate
534     // and set up the rate converter if necessary
535     if (!setupCodingRate(widget, m_encoder_channels, sample_rate))
536 	return false;
537 
538     // set up mapping, packet size and encoder
539     if (!setupEncoder(widget, m_encoder_channels, sample_rate))
540 	return false;
541 
542     // set up bitrate mode (e.g. VBR, ABR, ...)
543     if (!setupBitrateMode(widget))
544 	return false;
545 
546     // create a sample buffer at the end of the filter chain
547     m_buffer = new(std::nothrow)
548 	Kwave::MultiTrackSink<Kwave::SampleBuffer, true>(m_encoder_channels);
549     Q_ASSERT(m_buffer);
550     if (!m_buffer) {
551 	qWarning("cannot create sample buffer");
552 	return false;
553     }
554     if (!Kwave::connect(
555 	*m_last_queue_element, SIGNAL(output(Kwave::SampleArray)),
556 	*m_buffer,             SLOT(input(Kwave::SampleArray))) )
557     {
558 	qWarning("failed to connect sample buffer");
559 	return false;
560     }
561 
562     // set up the encoder complexity (ignore errors)
563     opus_int32 complexity = DEFAULT_COMPLEXITY;
564     err = opus_multistream_encoder_ctl(m_encoder,
565 	OPUS_SET_COMPLEXITY(complexity));
566     if (err != OPUS_OK) {
567 	qWarning("OpusEncoder: failed setting encoder complexity: '%s'",
568 	         DBG(Kwave::opus_error(err)));
569     }
570 
571     // set up the expected loss [percent] (ignore errors)
572     opus_int32 expect_loss = 0;
573     err = opus_multistream_encoder_ctl(m_encoder,
574 	OPUS_SET_PACKET_LOSS_PERC(expect_loss));
575     if (err != OPUS_OK) {
576 	qWarning("OpusEncoder: failed setting expected loss: '%s'",
577 	         DBG(Kwave::opus_error(err)));
578     }
579 
580 #ifdef OPUS_SET_LSB_DEPTH
581     // set up the LSB depth
582     opus_int32 bits = qBound<unsigned int>(8, m_info.bits(), 24);
583     err = opus_multistream_encoder_ctl(m_encoder, OPUS_SET_LSB_DEPTH(bits));
584     if (err != OPUS_OK) {
585 	qWarning("OpusEncoder: failed setting LSB depth loss: '%s'",
586 	         DBG(Kwave::opus_error(err)));
587     }
588 #endif /* OPUS_SET_LSB_DEPTH */
589 
590     // get the lookahead value
591     opus_int32 lookahead;
592     err = opus_multistream_encoder_ctl(m_encoder,
593 	OPUS_GET_LOOKAHEAD(&lookahead));
594     if (err != OPUS_OK) {
595 	Kwave::MessageBox::error(widget,
596 	    i18n("Opus encoder failed getting lookahead value: '%1'",
597 	         Kwave::opus_error(err)));
598 	return false;
599     }
600 
601     // regardless of the rate we're coding at the ogg timestamping/skip is
602     //  always timed at 48000 kBit/s
603     m_opus_header.preskip = static_cast<quint16>(
604 	lookahead * (48000.0 / m_coding_rate));
605     qDebug("    OpusEncoder: preskip=%d", m_opus_header.preskip);
606 
607     /* Extra samples that need to be read to compensate for the pre-skip */
608     m_extra_out = lookahead;
609 
610     // set up our packet->stream encoder
611     // pick a random serial number; that way we can more likely build
612     // chained streams just by concatenation
613     QRandomGenerator rnd(QTime::currentTime().msec());
614     ogg_stream_init(&m_os, rnd.generate());
615 
616     return true;
617 }
618 
619 /***************************************************************************/
_writeInt(QBuffer & buffer,quint32 value)620 static inline void _writeInt(QBuffer &buffer, quint32 value)
621 {
622     quint32 x = qToLittleEndian<quint32>(value);
623     buffer.write(reinterpret_cast<const char *>(&x), sizeof(x));
624 }
625 
626 /***************************************************************************/
writeOpusHeader(QIODevice & dst)627 bool Kwave::OpusEncoder::writeOpusHeader(QIODevice &dst)
628 {
629     Kwave::opus_header_t header;
630     unsigned int len;
631 
632     // create an Opus header, using correct byte order
633     memset(&header, 0x00, sizeof(header));
634     memset(&header.map, 0xFF, sizeof(header.map));
635 
636     memcpy(&(header.magic[0]), "OpusHead", 8);
637     header.version     = 1;
638     header.channels    = m_opus_header.channels;
639     header.preskip     = qToLittleEndian<quint16>(m_opus_header.preskip);
640     header.sample_rate = qToLittleEndian<quint32>(m_opus_header.sample_rate);
641     header.gain        = qToLittleEndian<quint16>(m_opus_header.gain);
642     header.channel_mapping = m_opus_header.channel_mapping;
643     len = 19; // bytes so far
644     if (m_opus_header.channel_mapping) {
645 	header.streams = m_opus_header.streams;
646 	header.coupled = m_opus_header.coupled;
647 	len += 2;
648 
649 	for (quint8 i = 0; i < m_opus_header.channels; ++i)
650 	    header.map[i] = m_opus_header.map[i];
651 	len += m_opus_header.channels;
652     }
653 
654     // write the header into the ogg stream
655     m_op.packet     = reinterpret_cast<unsigned char *>(&header);
656     m_op.bytes      = len;
657     m_op.b_o_s      = 1;
658     m_op.e_o_s      = 0;
659     m_op.granulepos = 0;
660     m_op.packetno   = 0;
661     ogg_stream_packetin(&m_os, &m_op);
662 
663     while (ogg_stream_flush(&m_os, &m_og)) {
664 	dst.write(reinterpret_cast<char *>(m_og.header),
665 	          m_og.header_len);
666 	dst.write(reinterpret_cast<char *>(m_og.body),
667 	          m_og.body_len);
668     }
669 
670     return true;
671 }
672 
673 /***************************************************************************/
writeOpusTags(QIODevice & dst)674 bool Kwave::OpusEncoder::writeOpusTags(QIODevice &dst)
675 {
676     QBuffer buffer;
677 
678     buffer.open(QBuffer::ReadWrite);
679 
680     // let the header start with the magic string "OpusTags"
681     buffer.write("OpusTags", 8);
682 
683     // write the vendor string == name + version of the encoder library
684     const char *opus_version = opus_get_version_string();
685     quint32 len = quint32(strlen(opus_version));
686     _writeInt(buffer, len);
687     buffer.write(opus_version, len);
688 
689     // iterate over all known properties and collect them in a list
690     QList<QByteArray> tags;
691     len = 0;
692 
693     for (VorbisCommentMap::const_iterator it(m_comments_map.constBegin());
694          it != m_comments_map.constEnd(); ++it)
695     {
696 	const QString       &key     = it.key();
697 	Kwave::FileProperty property = it.value();
698 	if (!m_info.contains(property)) continue; // skip if not present
699 
700 	// convert the value into a byte array,  UTF-8 encoded
701 	QString str = key + _("=") + m_info.get(property).toString();
702 	QByteArray v = str.toUtf8();
703 
704 	// make sure that the "ENCODER" tag is at the start of the list
705 	if ((property == INF_SOFTWARE) && (!tags.isEmpty()))
706 	    tags.prepend(v);
707 	else
708 	    tags.append(v);
709 
710 	len += (4 + v.size()); // sum up the data length
711     }
712 
713     // write the number of user tags
714     _writeInt(buffer, tags.count());
715 
716     // serialize the tags into the buffer
717     foreach (const QByteArray &tag, tags) {
718 	_writeInt(buffer, tag.size());
719 	buffer.write(tag);
720     }
721 
722     m_op.packet     = reinterpret_cast<unsigned char *>(buffer.buffer().data());
723     m_op.bytes      = static_cast<long int>(buffer.size());
724     m_op.b_o_s      = 0;
725     m_op.e_o_s      = 0;
726     m_op.granulepos = 0;
727     m_op.packetno   = 1;
728     ogg_stream_packetin(&m_os, &m_op);
729 
730     while (ogg_stream_flush(&m_os, &m_og)) {
731 	if (!writeOggPage(dst)) return false;
732     }
733 
734     return true;
735 }
736 
737 /***************************************************************************/
writeHeader(QIODevice & dst)738 bool Kwave::OpusEncoder::writeHeader(QIODevice &dst)
739 {
740     if (!writeOpusHeader(dst))
741 	return false;
742 
743     if (!writeOpusTags(dst))
744 	return false;
745 
746     return true;
747 }
748 
749 /***************************************************************************/
writeOggPage(QIODevice & dst)750 bool Kwave::OpusEncoder::writeOggPage(QIODevice &dst)
751 {
752     qint64 n;
753 
754     n = dst.write(reinterpret_cast<char *>(m_og.header), m_og.header_len);
755     if (n != m_og.header_len) {
756 	qWarning("OpusEncoder: I/O error writing header, len=%u, written=%u",
757 	          static_cast<unsigned int>(n),
758 	          static_cast<unsigned int>(m_og.header_len));
759 	return false; // write error ?
760     }
761 
762     n = dst.write(reinterpret_cast<char *>(m_og.body),   m_og.body_len);
763     if (n != m_og.body_len) {
764 	qWarning("OpusEncoder: I/O error writing body, len=%u, written=%u",
765 	          static_cast<unsigned int>(n),
766 	          static_cast<unsigned int>(m_og.body_len));
767 	return false; // write error ?
768     }
769 
770     // update the progress bar
771     QApplication::processEvents();
772 
773     return true;
774 }
775 
776 /***************************************************************************/
fillInBuffer(Kwave::MultiTrackReader & src)777 unsigned int Kwave::OpusEncoder::fillInBuffer(Kwave::MultiTrackReader &src)
778 {
779     unsigned int min_count = m_frame_size + 1; // will be used as "invalid"
780 
781     for (unsigned int t = 0; t < m_encoder_channels; ++t) {
782 	Kwave::SampleBuffer *buf = m_buffer->at(t);
783 	Q_ASSERT(buf);
784 	if (!buf) return 0;
785 
786 	unsigned int count = 0;
787 	unsigned int rest  = m_frame_size;
788 	while (rest) {
789 
790 	    // while buffer is empty and source is not at eof:
791 	    // trigger the start of the chain to produce some data
792 	    while (!buf->available() && !src.eof())
793 		src.goOn();
794 	    const unsigned int avail = buf->available();
795 	    if (!avail) break; // reached EOF
796 
797 	    // while there is something in the current buffer
798 	    // and some rest is still to do
799 	    unsigned int len = qMin<unsigned int>(rest, avail);
800 	    const sample_t *s = buf->get(len);
801 	    Q_ASSERT(s);
802 	    if (!s) break;
803 
804 	    // fill the frame data
805 	    rest  -= len;
806 	    count += len;
807 	    float *p = m_encoder_input + t;
808 	    while (len--) {
809 		*p = sample2float(*(s++));
810 		p += m_encoder_channels;
811 	    }
812 	}
813 	if (count < min_count) min_count = count;
814     }
815 
816     // take the minimum number of samples if valid, otherwise zero (eof?)
817     unsigned int n = (min_count <= m_frame_size) ? min_count : 0;
818 
819     // if we were not able to fill a complete frame, we probably are at eof
820     // and have some space to pad with extra samples to compensate preskip
821     unsigned int extra_out = m_extra_out;
822     while ((n < m_frame_size) && extra_out) {
823 	Q_ASSERT(src.eof());
824 	for (unsigned int t = 0; t < m_encoder_channels; ++t) {
825 	    m_encoder_input[(n * m_encoder_channels) + t] = 0.0;
826 	}
827 	extra_out--;
828 	n++;
829     }
830 
831     return n;
832 }
833 
834 /***************************************************************************/
encode(Kwave::MultiTrackReader & src,QIODevice & dst)835 bool Kwave::OpusEncoder::encode(Kwave::MultiTrackReader &src,
836                                 QIODevice &dst)
837 {
838     long int     eos             =  0;
839     opus_int64   nb_encoded      =  0;
840     opus_int64   nb_samples      = -1;
841     opus_int64   total_bytes     =  0;
842     opus_int64   total_samples   =  0;
843     ogg_int64_t  enc_granulepos  =  0;
844     ogg_int64_t  last_granulepos =  0;
845     ogg_int32_t  packet_id       =  1;
846     int          last_segments   =  0;
847     const int    max_ogg_delay   =  48000; /* 48kHz samples */
848 
849     Q_ASSERT(m_encoder);
850     Q_ASSERT(m_encoder_input);
851 
852     Q_UNUSED(dst)
853 
854     /* Main encoding loop (one frame per iteration) */
855     while (!m_op.e_o_s && !src.isCanceled()) {
856 	int size_segments = 0;
857 
858 	packet_id++;
859 
860 	if (nb_samples < 0) {
861 	    nb_samples = fillInBuffer(src);
862 	    total_samples += nb_samples;
863 	    m_op.e_o_s = (nb_samples < m_frame_size) ? 1 : 0;
864 	}
865 	m_op.e_o_s |= eos; // eof from last pass
866 
867 	// pad the rest of the frame with zeroes if necessary
868 	if (nb_samples < m_frame_size ) {
869 	    const unsigned int pad_from =
870 		Kwave::toUint(nb_samples * m_encoder_channels);
871 	    const unsigned int pad_to   =
872 		Kwave::toUint(m_frame_size * m_encoder_channels);
873 	    for (unsigned int pos = pad_from; pos < pad_to; pos++ )
874 		m_encoder_input[pos] = 0;
875 	}
876 
877 	/* encode current frame */
878 	int nbBytes = opus_multistream_encode_float(
879 	    m_encoder,
880 	    m_encoder_input,
881 	    m_frame_size,
882 	    m_packet_buffer,
883 	    m_max_frame_bytes
884 	);
885 	if (nbBytes < 0 ) {
886 	    qWarning("Opus encoder failed: '%s'",
887 		    DBG(Kwave::opus_error(nbBytes)));
888 	    return false;
889 	}
890 
891 	nb_encoded     += m_frame_size;
892 	enc_granulepos += m_frame_size * 48000 / m_coding_rate;
893 	total_bytes    += nbBytes;
894 	size_segments   = (nbBytes + 255) / 255;
895 
896 	// flush early if adding this packet would make us end up with a
897 	// continued page which we wouldn't have otherwise
898 	while (( ((size_segments <= 255) &&
899 		(last_segments + size_segments > 255)) ||
900 		(enc_granulepos - last_granulepos > max_ogg_delay)) &&
901 #ifdef HAVE_OGG_STREAM_FLUSH_FILL
902 		ogg_stream_flush_fill(&m_os, &m_og, 255 * 255))
903 #else /* HAVE_OGG_STREAM_FLUSH_FILL */
904 		ogg_stream_flush(&m_os, &m_og))
905 #endif /* HAVE_OGG_STREAM_FLUSH_FILL */
906 	{
907 	    if (ogg_page_packets(&m_og) != 0)
908 		last_granulepos = ogg_page_granulepos(&m_og);
909 
910 	    last_segments -= m_og.header[26];
911 
912 	    if (!writeOggPage(dst)) {
913 		qWarning("Opus encoder: I/O error");
914 		return false;
915 	    }
916 	}
917 
918         // the downside of early reading is if the input is an exact
919         // multiple of the frame_size you'll get an extra frame that needs
920         // to get cropped off. The downside of late reading is added delay.
921         // If your ogg_delay is 120ms or less we'll assume you want the
922         // low delay behavior.
923         if ((!m_op.e_o_s ) && (max_ogg_delay > 5760)) {
924             nb_samples = fillInBuffer(src);
925             total_samples += nb_samples;
926             if (nb_samples < m_frame_size) eos = 1;
927             if (nb_samples == 0) m_op.e_o_s = 1;
928         } else {
929             nb_samples = -1;
930         }
931 
932         m_op.packet     = m_packet_buffer;
933         m_op.packetno   = packet_id;
934         m_op.bytes      = nbBytes;
935         m_op.b_o_s      = 0;
936         m_op.granulepos = enc_granulepos;
937         if (m_op.e_o_s) {
938             // compute the final GP as ceil(len*48k/input_rate). When a
939             // resampling decoder does the matching floor(len*input/48k)
940             // conversion the length will be exactly the same as the input.
941             sample_index_t length = m_info.length();
942 	    double         rate   = m_info.rate();
943 	    m_op.granulepos = static_cast<ogg_int64_t>(
944 		ceil((static_cast<double>(length) * 48000.0) / rate) +
945 		m_opus_header.preskip);
946         }
947         ogg_stream_packetin(&m_os, &m_op);
948         last_segments += size_segments;
949 
950         // If the stream is over or we're sure that the delayed flush will
951         // fire, go ahead and flush now to avoid adding delay.
952         while ((m_op.e_o_s || (enc_granulepos +
953 	        ((m_frame_size * 48000) / m_coding_rate ) -
954 	         last_granulepos > max_ogg_delay) || (last_segments >= 255)) ?
955 #ifdef HAVE_OGG_STREAM_FLUSH_FILL
956                 ogg_stream_flush_fill(&m_os, &m_og, 255 * 255) :
957                 ogg_stream_pageout_fill(&m_os, &m_og, 255 * 255))
958 #else /* HAVE_OGG_STREAM_FLUSH_FILL */
959                 /*Libogg > 1.2.2 allows us to achieve lower overhead by
960                   producing larger pages. For 20ms frames this is only relevant
961                   above ~32kbit/sec.*/
962                 ogg_stream_flush(&m_os, &m_og) :
963                 ogg_stream_pageout(&m_os, &m_og))
964 #endif /* HAVE_OGG_STREAM_FLUSH_FILL */
965 	{
966             if (ogg_page_packets(&m_og) != 0)
967                 last_granulepos = ogg_page_granulepos(&m_og);
968 
969             last_segments -= m_og.header[26];
970 	    if (!writeOggPage(dst)) {
971 		qWarning("Opus encoder: I/O error");
972 		return false;
973 	    }
974         }
975     }
976 
977     return true;
978 }
979 
980 /***************************************************************************/
close()981 void Kwave::OpusEncoder::close()
982 {
983     if (m_channel_mixer) delete m_channel_mixer;
984     m_channel_mixer = Q_NULLPTR;
985 
986     if (m_rate_converter) delete m_rate_converter;
987     m_rate_converter = Q_NULLPTR;
988 
989     if (m_buffer) delete m_buffer;
990     m_buffer = Q_NULLPTR;
991 
992     if (m_encoder) opus_multistream_encoder_destroy(m_encoder);
993     m_encoder = Q_NULLPTR;
994 
995     ogg_stream_clear(&m_os);
996 
997     if (m_packet_buffer) free(m_packet_buffer);
998     m_packet_buffer = Q_NULLPTR;
999 
1000     if (m_encoder_input) free(m_encoder_input);
1001     m_encoder_input = Q_NULLPTR;
1002 
1003     m_last_queue_element = Q_NULLPTR;
1004 }
1005 
1006 /***************************************************************************/
1007 /***************************************************************************/
1008