• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 ** Copyright (C) 2013-2020 Erik de Castro Lopo <erikd@mega-nerd.com>
3 ** Copyright (C) 2018 Arthur Taylor <art@ified.ca>
4 **
5 ** This program is free software ; you can redistribute it and/or modify
6 ** it under the terms of the GNU Lesser General Public License as published by
7 ** the Free Software Foundation ; either version 2.1 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY ; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
13 ** GNU Lesser General Public License for more details.
14 **
15 ** You should have received a copy of the GNU Lesser General Public License
16 ** along with this program ; if not, write to the Free Software
17 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19 
20 /*
21 ** This file contains code based on OpusFile and Opus-Tools, both by
22 ** Xiph.Org. COPYING from each is identical and is as follows:
23 **
24 ** Copyright (c) 1994-2013 Xiph.Org Foundation and contributors
25 **
26 ** Redistribution and use in source and binary forms, with or without
27 ** modification, are permitted provided that the following conditions
28 ** are met:
29 **
30 ** - Redistributions of source code must retain the above copyright
31 ** notice, this list of conditions and the following disclaimer.
32 **
33 ** - Redistributions in binary form must reproduce the above copyright
34 ** notice, this list of conditions and the following disclaimer in the
35 ** documentation and/or other materials provided with the distribution.
36 **
37 ** - Neither the name of the Xiph.Org Foundation nor the names of its
38 ** contributors may be used to endorse or promote products derived from
39 ** this software without specific prior written permission.
40 **
41 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
42 ** ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
43 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
44 ** A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION
45 ** OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
46 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
47 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
48 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
49 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
51 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 */
53 
54 /*
55 ** TODO:
56 **  - Channel mapping modification / reporting
57 **	 - connect psf->channel_map and Opus channel mapping somehow?
58 **  - Gain parameters and their mappings
59 */
60 
61 /*
62 ** Opus Sample, Frame, and Samples/Channel Terminology
63 **
64 ** libsndfile refers to one PCM value as a 'sample,' and a group of samples of
65 ** the same sample time, one for each channel, as a 'frame.' This differs from
66 ** Opus, which has no corresponding name for sample, and refers to a group of
67 ** PCM values, one per channel (aka libsndfile frames) as 'samples.'
68 ** Further, Opus has an object called a 'frame' that is made up of multiple
69 ** Opus-samples.
70 ** All this means that one has to be careful with what is meant by each term.
71 ** In an attempt to avoid ambiguity, this file adopts the following terms:
72 **  - Samples shall refer to discrete PCM values, regardless of any channel
73 **	considerations. This is the same as what libsndfile calls samples.
74 **  - Samples/channel shall refer to groups of samples, one for each channel.
75 **	This is what Opus calles samples, and what libsndfile calles frames. It
76 **	has the advantage that its name is also the formula to calculate it.
77 **
78 **
79 ** Opus vs OggOpus
80 **
81 ** In this file a distinction is made between Opus and OggOpus. Opus refers to
82 ** the codec alone, support for which is by libopus. OggOpus refers to an Opus
83 ** payload encapsulated in an Ogg stream. This is also know as an "Opus file."
84 ** The OggOpus spec includes information on header and granule position
85 ** interpretation, which is outside of the scope of the Opus spec. As such, an
86 ** attempt here is made to refer to either Opus or OggOpus depending on which
87 ** spec is being referenced. See https://wiki.xiph.org/OggOpus
88 **
89 **
90 ** Opus Sample Rates
91 **
92 ** Opus only supports a fixed number of sample rates: 48kHz, 24kHz, 16kHz,
93 ** 12kHz, 8kHz. Audio may be decoded or encoded at any of these rates,
94 ** independent of the rate it was encoded at or to be decoded at respectively.
95 ** Other sample rates must be converted to one of these rates.
96 **
97 ** As 44.1kHz (CD sample rate) and 22.5kHz are popular sample rates, and to
98 ** support any other sample rate there may be, the Opus header includes a field
99 ** to save the input (original) sample rate before converting it to a supported
100 ** one. Implementations are recommended by the Opus spec to do a sample rate
101 ** conversion at encode, but decode at 48kHz if outputting to hardware, or do
102 ** the reverse sample rate conversion if outputting to file.
103 **
104 ** Heretofore libsndfile does not contain a sample rate converter, so doing the
105 ** sample rate conversion is not supported. Instead audio must be provided by
106 ** the user at a supported rate. However, the input sample rate field can be
107 ** set and retrieved by the user using sf_command(). At decode we choose to
108 ** decode at the lowest valid rate that is greater than or equal to the input
109 ** sample rate.
110 **
111 **
112 ** OggOpus Granule Positions
113 **
114 ** Ogg streams include a strictly increasing granule position value. The
115 ** interpretation of this value is dependent on the payload type. For Opus
116 ** streams the granule position is the count of samples in the stream when
117 ** encoding/decoding at 48kHz. Note that the actual position of the output
118 ** sample relative to the granule position is offset by the preskip amount.
119 ** That is, if a packet ends with a granule position of x, the last sample
120 ** output when decoding is actually sample (x - preskip).
121 **
122 ** Further, to allow for clipping off of the front of a stream without
123 ** rewriting all following granule positions, an Opus stream granule position
124 ** may be offset by a constant amount. This amount is evident by comparing the
125 ** granule position of the first page of an Opus stream on which an audio
126 ** packet completes is greater than the sum of the samples of all audio
127 ** packets completed on the page. Only the first such page is allows to have an
128 ** 'excessive' granule position, and only if it is not also the last page of
129 ** the stream (e_o_s bit is not set.)
130 **
131 ** The granule position is an unsigned 64-bit integer, with the special value
132 ** of UINT64_MAX/-1 being treated as invalid. However, as not all platforms
133 ** support unsigned 64-bit integers, libOgg uses signed 64-bit integers for the
134 ** granule position.
135 **
136 ** Remembering that signed integer overflow/underflow is explicitly undefined
137 ** in C, and as we already assume support for unsigned 64-bit integers, the
138 ** easiest way to deal with this problem is to modify granule positions as
139 ** unsigned integers.
140 */
141 
142 
143 #include "sfconfig.h"
144 
145 #include <stdio.h>
146 #include <fcntl.h>
147 #include <string.h>
148 #include <ctype.h>
149 #include <time.h>
150 #include <math.h>
151 
152 #if HAVE_UNISTD_H
153 #include <unistd.h>
154 #else
155 #include "sf_unistd.h"
156 #endif
157 
158 #include "sndfile.h"
159 #include "sfendian.h"
160 #include "common.h"
161 
162 #if HAVE_EXTERNAL_XIPH_LIBS
163 
164 #include <ogg/ogg.h>
165 #include <opus/opus.h>
166 #include <opus/opus_multistream.h>
167 
168 #include "ogg.h"
169 #include "ogg_vcomment.h"
170 
171 #define OGG_OPUS_COMMENT_PAD (512) /* Same as oggenc default */
172 
173 /*
174 ** When encoding, we can choose the size of the Opus frames.
175 ** Valid values are 2.5, 5, 10, 20, 40, and 60 milliseconds.
176 **
177 ** Frames smaller than 10ms can't use CELT (MDCT) mode.
178 ** Frames larger than 20ms "are only interesting at fairly low bitrates."
179 **
180 ** We choose the suggested default of 20ms for high-fidelity audio, however,
181 ** maybe this could be user-selected, or triggered by bitrate command.
182 ** default for non-realtime of 20ms. While longer packets reduce the overhead
183 ** data somewhat, it also decreases the quality.
184 */
185 #define OGG_OPUS_ENCODE_PACKET_LEN(samplerate) ((20 * (samplerate)) / 1000)
186 
187 /*
188 ** The pre-roll is how long it takes for the decoder to converge. It converges
189 ** pretty quickly, to within -40db within 80ms. However, this also depends on
190 ** the signal. From experimentation, use the conservative pre-roll amount of
191 ** 660ms after which the output is 32-bit-exact with high probability.
192 */
193 #define OGG_OPUS_PREROLL (660 * 48) /* 660 milliseconds (33 packets of 20ms) */
194 
195 typedef struct
196 {	uint8_t version ;
197 
198 	/* Number of channels, 1...255 */
199 	uint8_t channels ;
200 
201 	/* Encoder latency, the amount to skip before valid data comes out. */
202 	uint16_t preskip ;
203 
204 	/* The sample rate of a the encoded source, as it may have been converted. */
205 	int32_t input_samplerate ;
206 
207 	/* 'baked-in' gain to apply, dB S7.8 format. Should be zero when possible. */
208 	int16_t gain ;
209 
210 	/* Channel mapping type. See OggOpus spec */
211 	uint8_t channel_mapping ;
212 
213 	/* The rest is only used if channel_mapping != 0 */
214 	/* How many streams are there? */
215 	uint8_t nb_streams ;
216 
217 	/* How man of those streams are coupled? (aka stereo) */
218 	uint8_t nb_coupled ;
219 
220 	/* Mapping of opus streams to output channels */
221 	uint8_t stream_map [255] ;
222 } OpusHeader ;
223 
224 typedef struct
225 {	uint32_t serialno ;
226 	OpusHeader header ;
227 
228 	/* Encode: Granule position after the previous packet.
229 	 * Decode: Granule position after the current packet */
230 	uint64_t pkt_pos ;
231 
232 	/* Encode: Granule position at the end of the previous page.
233 	 * Decode: Granule position at the end of the current page. */
234 	uint64_t pg_pos ;
235 
236 	/* integer coefficient of (current sample rate) / 48000Hz */
237 	int sr_factor ;
238 
239 	/* Current position in buffer expressed as samples/channel */
240 	int loc ;
241 
242 	/* Current data fill (decode) or target (encode) of buffer expressed in samples/channel */
243 	int len ;
244 
245 	/* Size of the buffer storage, in sizeof (float) * channels */
246 	int buffersize ;
247 
248 	/* Samples, either decoded from a packet, or assembling for encode. */
249 	float *buffer ;
250 
251 	union {
252 		/* decode only members */
253 		struct {
254 			OpusMSDecoder *state ;
255 			uint64_t gp_start ;
256 			uint64_t gp_end ;
257 			sf_count_t last_offset ;
258 		} decode ;
259 
260 		/* encode only members */
261 		struct {
262 			OpusMSEncoder *state ;
263 
264 			/* How many Ogg page segments are in Ogg page currently being assembled. */
265 			int last_segments ;
266 
267 			int bitrate ;
268 			unsigned long latency ;
269 
270 			/* Least significant bit of the source (aka bitwidth) */
271 			int lsb ;
272 			int lsb_last ;
273 		} encode ;
274 	} u ;
275 } OPUS_PRIVATE ;
276 
277 /*-----------------------------------------------------------------------------------------------
278 ** Private function prototypes.
279 */
280 
281 static int			ogg_opus_close (SF_PRIVATE *psf) ;
282 static void			opus_print_header (SF_PRIVATE *psf, OpusHeader *h) ;
283 static int			opus_read_header_packet (SF_PRIVATE *psf, OpusHeader *h, ogg_packet *opacket) ;
284 static int			ogg_opus_read_header (SF_PRIVATE * psf) ;
285 static int			ogg_opus_setup_decoder (SF_PRIVATE *psf, int input_samplerate) ;
286 
287 static int			ogg_opus_setup_encoder (SF_PRIVATE *psf, OGG_PRIVATE *odata, OPUS_PRIVATE *oopus) ;
288 static int			ogg_opus_write_header (SF_PRIVATE * psf, int calc_length) ;
289 static void			ogg_opus_flush (SF_PRIVATE *psf) ;
290 static int			ogg_opus_unpack_next_page (SF_PRIVATE *psf, OGG_PRIVATE *odata, OPUS_PRIVATE *oopus) ;
291 static int			ogg_opus_calculate_page_duration (OGG_PRIVATE *odata) ;
292 static int			ogg_opus_read_refill (SF_PRIVATE *psf, OGG_PRIVATE *odata, OPUS_PRIVATE *oopus) ;
293 static int			ogg_opus_write_out (SF_PRIVATE *psf, OGG_PRIVATE *odata, OPUS_PRIVATE *oopus) ;
294 
295 static sf_count_t	ogg_opus_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
296 static sf_count_t	ogg_opus_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
297 static sf_count_t	ogg_opus_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
298 static sf_count_t	ogg_opus_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
299 
300 static sf_count_t	ogg_opus_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
301 static sf_count_t	ogg_opus_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
302 static sf_count_t	ogg_opus_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
303 static sf_count_t	ogg_opus_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
304 
305 static sf_count_t	ogg_opus_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
306 static sf_count_t	ogg_opus_null_read (SF_PRIVATE *psf, sf_count_t offset) ;
307 static sf_count_t	ogg_opus_page_seek_manual (SF_PRIVATE *psf, uint64_t target_gp) ;
308 static int			ogg_opus_page_seek_search (SF_PRIVATE *psf, uint64_t target_gp) ;
309 
310 static int			ogg_opus_analyze_file (SF_PRIVATE *psf) ;
311 static int			ogg_opus_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
312 static int			ogg_opus_byterate (SF_PRIVATE *psf) ;
313 
314 /*-----------------------------------------------------------------------------------------------
315 */
316 
317 static vorbiscomment_ident opustags_ident =	{ "OpusTags", 8 } ;
318 
319 /*-----------------------------------------------------------------------------------------------
320 ** Exported functions.
321 */
322 
323 int
ogg_opus_open(SF_PRIVATE * psf)324 ogg_opus_open (SF_PRIVATE *psf)
325 {	OGG_PRIVATE* odata = psf->container_data ;
326 	OPUS_PRIVATE* oopus = calloc (1, sizeof (OPUS_PRIVATE)) ;
327 	int	error = 0 ;
328 
329 	if (odata == NULL)
330 	{	psf_log_printf (psf, "%s : odata is NULL???\n", __func__) ;
331 		free (oopus) ;
332 		return SFE_INTERNAL ;
333 		} ;
334 
335 	psf->codec_data = oopus ;
336 	if (oopus == NULL)
337 		return SFE_MALLOC_FAILED ;
338 
339 	if (psf->file.mode == SFM_RDWR)
340 		return SFE_BAD_MODE_RW ;
341 
342 	psf_log_printf (psf, "Opus library version: %s\n", opus_get_version_string ()) ;
343 
344 	psf->codec_close = ogg_opus_close ;
345 	if (psf->file.mode == SFM_READ)
346 	{	if ((error = ogg_opus_read_header (psf)))
347 			return error ;
348 		if ((error = ogg_opus_analyze_file (psf)))
349 			return error ;
350 
351 		psf->read_short		= ogg_opus_read_s ;
352 		psf->read_int		= ogg_opus_read_i ;
353 		psf->read_float		= ogg_opus_read_f ;
354 		psf->read_double	= ogg_opus_read_d ;
355 		} ;
356 
357 	if (psf->file.mode == SFM_WRITE)
358 	{	if ((error = ogg_opus_setup_encoder (psf, odata, oopus)))
359 			return error ;
360 
361 		psf->write_header	= ogg_opus_write_header ;
362 		psf->write_short	= ogg_opus_write_s ;
363 		psf->write_int		= ogg_opus_write_i ;
364 		psf->write_float	= ogg_opus_write_f ;
365 		psf->write_double	= ogg_opus_write_d ;
366 
367 		psf->sf.frames = SF_COUNT_MAX ; /* Unknown really */
368 		psf->strings.flags = SF_STR_ALLOW_START ;
369 		psf->datalength = 0 ;
370 		psf->dataoffset = 0 ; /* will be updated */
371 		} ;
372 
373 	psf->seek = ogg_opus_seek ;
374 	psf->command = ogg_opus_command ;
375 	psf->byterate = ogg_opus_byterate ;
376 	psf->sf.format = SF_FORMAT_OGG | SF_FORMAT_OPUS ;
377 
378 	return error ;
379 } /* ogg_opus_open */
380 
381 /*==============================================================================
382 ** Private functions.
383 */
384 
385 static int
ogg_opus_close(SF_PRIVATE * psf)386 ogg_opus_close (SF_PRIVATE *psf)
387 {	OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
388 	OPUS_PRIVATE *oopus = (OPUS_PRIVATE *) psf->codec_data ;
389 
390 	if (!oopus)
391 		return 0 ;
392 
393 	if (psf->file.mode == SFM_WRITE)
394 	{	if (psf->have_written)
395 			ogg_opus_flush (psf) ;
396 		else {
397 			/* Write a header... it is expected. */
398 			ogg_opus_write_header (psf, 0) ;
399 			} ;
400 		ogg_packet_clear (&odata->opacket) ;
401 		if (oopus->u.encode.state)
402 		{	opus_multistream_encoder_destroy (oopus->u.encode.state) ;
403 			oopus->u.encode.state = NULL ;
404 			} ;
405 		}
406 	else if (psf->file.mode == SFM_READ)
407 	{	if (oopus->u.decode.state)
408 		{	opus_multistream_decoder_destroy (oopus->u.decode.state) ;
409 			oopus->u.decode.state = NULL ;
410 			} ;
411 		} ;
412 
413 	psf->codec_data = NULL ;
414 	if (oopus->buffer)
415 		free (oopus->buffer) ;
416 	free (oopus) ;
417 
418 	return 0 ;
419 } /* ogg_opus_close */
420 
421 static void
opus_print_header(SF_PRIVATE * psf,OpusHeader * h)422 opus_print_header (SF_PRIVATE *psf, OpusHeader *h)
423 {	psf_log_printf (psf, "Opus Header Metadata\n") ;
424 	psf_log_printf (psf, "  OggOpus version  : %d\n", (int) h->version) ;
425 	psf_log_printf (psf, "  Channels         : %d\n", (int) h->channels) ;
426 	psf_log_printf (psf, "  Preskip          : %d samples @48kHz\n", (int) h->preskip) ;
427 	psf_log_printf (psf, "  Input Samplerate : %d Hz\n", (int) h->input_samplerate) ;
428 	psf_log_printf (psf, "  Gain             : %d.%d\n", (int) arith_shift_right (h->gain & 0xF0, 8), h->gain & 0x0F) ;
429 	psf_log_printf (psf, "  Channel Mapping  : ") ;
430 	switch (h->channel_mapping)
431 	{	case 0 :	psf_log_printf (psf, "0 (mono or stereo)\n") ; break ;
432 		case 1 :	psf_log_printf (psf, "1 (surround, AC3 channel order)\n") ; break ;
433 		case 255 :	psf_log_printf (psf, "255 (no channel order)\n") ; break ;
434 		default :	psf_log_printf (psf, "%d (unknown or unsupported)\n", (int) h->channel_mapping) ; break ;
435 		} ;
436 
437 	if (h->channel_mapping > 0)
438 	{	int i ;
439 		psf_log_printf (psf, "   streams total   : %d\n", (int) h->nb_streams) ;
440 		psf_log_printf (psf, "   streams coupled : %d\n", (int) h->nb_coupled) ;
441 		psf_log_printf (psf, "   stream mapping : [") ;
442 		for (i = 0 ; i < h->channels - 1 ; i++)
443 			psf_log_printf (psf, "%d,", (int) (h->stream_map [i])) ;
444 		psf_log_printf (psf, "%d]\n", (int) (h->stream_map [i])) ;
445 		} ;
446 } /* opus_print_header */
447 
448 static int
opus_read_header_packet(SF_PRIVATE * psf,OpusHeader * h,ogg_packet * opacket)449 opus_read_header_packet (SF_PRIVATE *psf, OpusHeader *h, ogg_packet *opacket)
450 {	int count, i ;
451 
452 	/*
453 	** Opus headers are 19 bytes, in the case of type 0 channel mapping,
454 	** or 19 + 2 + (1 * channel count) bytes for other channel mappings, to a
455 	** maximum of 276 (255 channels).
456 	*/
457 
458 	if (opacket->bytes < 19 || opacket->bytes > 276)
459 		return SFE_MALFORMED_FILE ;
460 
461 	if (memcmp (opacket->packet, "OpusHead", 8) != 0)
462 		return SFE_MALFORMED_FILE ;
463 
464 	/*
465 	** Copy the header page into the binheader so we can use binheader
466 	** functions to safely unpack it.
467 	*/
468 	count = psf_binheader_writef (psf, "ob", BHWo (0), BHWv (opacket->packet), BHWz (opacket->bytes)) ;
469 	psf->header.end = count ;
470 
471 	count = psf_binheader_readf (psf, "ep1", 8, &h->version) ;
472 	if (! (h->version == 1 || h->version == 0))
473 	{	psf_log_printf (psf, "Opus : Unknown / unsupported embedding scheme version: %d.\n", (int) h->version) ;
474 		return SFE_UNIMPLEMENTED ;
475 		} ;
476 
477 	count += psf_binheader_readf (psf, "e12421", &h->channels, &h->preskip,
478 		&h->input_samplerate, &h->gain, &h->channel_mapping) ;
479 
480 	if (h->channel_mapping == 0)
481 	{	if (h->channels > 2)
482 			return SFE_MALFORMED_FILE ;
483 
484 		/*
485 		** Setup the stream mapping, so we can use the multistream decoder,
486 		** rather than have to deal with two decoder pointer types
487 		*/
488 		h->nb_streams = 1 ;
489 		h->nb_coupled = h->channels - 1 ;
490 		h->stream_map [0] = 0 ;
491 		h->stream_map [1] = 1 ;
492 		}
493 	else
494 	{	if (opacket->bytes < 19 + 2 + h->channels)
495 			return SFE_MALFORMED_FILE ;
496 
497 		if (h->channel_mapping == 1 && h->channels > 8)
498 			return SFE_MALFORMED_FILE ;
499 
500 		count += psf_binheader_readf (psf, "11", &h->nb_streams, &h->nb_coupled) ;
501 
502 		if (h->nb_streams < 1 ||
503 			h->nb_coupled > h->nb_streams ||
504 			h->nb_coupled + h->nb_streams > 255)
505 			return SFE_MALFORMED_FILE ;
506 
507 		for (i = 0 ; i < h->channels ; i++)
508 		{	count += psf_binheader_readf (psf, "1", &(h->stream_map [i])) ;
509 			if (h->stream_map [i] > h->nb_streams + h->nb_coupled && h->stream_map [i] != 255)
510 				return SFE_MALFORMED_FILE ;
511 			} ;
512 		} ;
513 
514 	if (count != opacket->bytes)
515 	{	/* OggOpus spec mandates that this is a hard error. */
516 		psf_log_printf (psf, "Opus : Error, extra data in Ogg Opus header.\n") ;
517 		return SFE_MALFORMED_FILE ;
518 		} ;
519 
520 	opus_print_header (psf, h) ;
521 
522 	return 0 ;
523 } /* ogg_opus_read_header_packet */
524 
525 static int
ogg_opus_read_header(SF_PRIVATE * psf)526 ogg_opus_read_header (SF_PRIVATE *psf)
527 {	OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
528 	OPUS_PRIVATE *oopus = (OPUS_PRIVATE *) psf->codec_data ;
529 	int error ;
530 
531 	/*
532 	** First page is already loaded by the ogg container code when it
533 	** classified the stream, no need to re-load it now.
534 	*/
535 
536 	if (ogg_page_packets (&odata->opage) != 1 || !ogg_page_bos (&odata->opage))
537 		return SFE_MALFORMED_FILE ;
538 
539 	oopus->serialno = ogg_page_serialno (&odata->opage) ;
540 	if ((error = opus_read_header_packet (psf, &oopus->header, &odata->opacket)))
541 		return error ;
542 
543 	/*
544 	** The comment header MUST be next. It is one packet, that packet MUST begin
545 	** on the second page of the stream, but it MAY span multiple pages.
546 	*/
547 
548 	while (ogg_stream_packetout (&odata->ostream, &odata->opacket) != 1)
549 	{	if (ogg_stream_next_page (psf, odata) != 1)
550 		{	/* out of data... technically that's malformed. */
551 			return psf->error ? psf->error : SFE_MALFORMED_FILE ;
552 			} ;
553 		} ;
554 
555 	if ((error = vorbiscomment_read_tags (psf, &odata->opacket, &opustags_ident)))
556 		return error ;
557 
558 	return ogg_opus_setup_decoder (psf, oopus->header.input_samplerate) ;
559 } /* ogg_opus_read_header */
560 
561 static int
ogg_opus_setup_decoder(SF_PRIVATE * psf,int input_samplerate)562 ogg_opus_setup_decoder (SF_PRIVATE *psf, int input_samplerate)
563 {	OPUS_PRIVATE *oopus = (OPUS_PRIVATE *) psf->codec_data ;
564 	OpusMSDecoder *decoder ;
565 	int sr_factor ;
566 	int error ;
567 
568 	/*
569 	** Decide what sample rate to decode at. We choose the lowest valid rate
570 	** that is greater or equal to the original rate.
571 	**
572 	** Opus documentation recommends always decoding at 48000Hz if the file is
573 	** being decoded for playback, since most hardware will resample it back to
574 	** 48000Hz anyways. We don't know if that's true, maybe the user is
575 	** decoding for editing or transcoding purposes.
576 	*/
577 	if (input_samplerate > 24000)
578 		sr_factor = 1 ;
579 	else if (input_samplerate > 16000)
580 		sr_factor = 2 ;
581 	else if (input_samplerate > 12000)
582 		sr_factor = 3 ;
583 	else if (input_samplerate > 8000)
584 		sr_factor = 4 ;
585 	else
586 		sr_factor = 6 ;
587 
588 	decoder = opus_multistream_decoder_create (
589 		48000 / sr_factor,
590 		oopus->header.channels,
591 		oopus->header.nb_streams,
592 		oopus->header.nb_coupled,
593 		oopus->header.stream_map,
594 		&error) ;
595 
596 	if (error != OPUS_OK)
597 	{	psf_log_printf (psf, "Opus : Failed to create multistream decoder: %s\n",
598 			opus_strerror (error)) ;
599 		return SFE_INTERNAL ;
600 		}
601 
602 	/*
603 	** Replace the decoder, if one was already initialized (see
604 	** SFC_GET_ORIGINAL_SAMPLERATE)
605 	*/
606 	if (oopus->u.decode.state)
607 		opus_multistream_decoder_destroy (oopus->u.decode.state) ;
608 	oopus->u.decode.state = decoder ;
609 
610 	oopus->sr_factor = sr_factor ;
611 	psf->sf.samplerate = 48000 / sr_factor ;
612 	psf->sf.channels = oopus->header.channels ;
613 	oopus->loc = oopus->len = 0 ;
614 
615 	/*
616 	** The Opus decoder can do our gain for us. The OggOpus header contains a
617 	** gain field. This field, unlike various gain-related tags, is intended to
618 	** be a perminent baked-in gain applied before any user-configurable gain
619 	** (eg replay-gain.) This is so the gain of track can be set without having
620 	** to re-encode.
621 	**
622 	** Both the header.gain field and the parameter are in the Q7.8 format.
623 	**
624 	** TODO: Make this configurable? Include other gain sources too?
625 	*/
626 	opus_multistream_decoder_ctl (oopus->u.decode.state, OPUS_SET_GAIN (oopus->header.gain)) ;
627 
628 	/*
629 	** Opus packets can vary in length, with the legal values being 2.5, 5, 10,
630 	** 20, 40 or 60ms. The recommended default for non-realtime is 20ms. As
631 	** such, allocate a buffer of that size now, we'll realloc later if a
632 	** larger one is needed.
633 	**
634 	** buffersize is expressed in samples/channel, as that is what opus_decode
635 	** expects.
636 	*/
637 	if (oopus->buffer)
638 	{	free (oopus->buffer) ;
639 		oopus->buffer = NULL ;
640 		} ;
641 	oopus->buffersize = 20 * psf->sf.samplerate / 1000 ;
642 	oopus->buffer = malloc (sizeof (float) * psf->sf.channels * oopus->buffersize) ;
643 	if (oopus->buffer == NULL)
644 		return SFE_MALLOC_FAILED ;
645 
646 	return 0 ;
647 } /* ogg_opus_setup_decoder */
648 
649 static int
ogg_opus_setup_encoder(SF_PRIVATE * psf,OGG_PRIVATE * odata,OPUS_PRIVATE * oopus)650 ogg_opus_setup_encoder (SF_PRIVATE *psf, OGG_PRIVATE *odata, OPUS_PRIVATE *oopus)
651 {	int error ;
652 	int lookahead ;
653 	int nb_streams ;
654 	int nb_coupled ;
655 
656 	/* default page latency value (1000ms) */
657 	oopus->u.encode.latency = 1000 * 48 ;
658 
659 	switch (psf->sf.samplerate)
660 	{	case 8000 :
661 		case 12000 :
662 		case 16000 :
663 		case 24000 :
664 		case 48000 :
665 			oopus->sr_factor = 48000 / psf->sf.samplerate ;
666 			break ;
667 		default :
668 			return SFE_OPUS_BAD_SAMPLERATE ;
669 		} ;
670 
671 	if (psf->sf.channels <= 2)
672 	{	oopus->header.channel_mapping = 0 ;
673 		nb_streams = 1 ;
674 		nb_coupled = psf->sf.channels - 1 ;
675 		oopus->header.stream_map [0] = 0 ;
676 		oopus->header.stream_map [1] = 1 ;
677 
678 		oopus->u.encode.state = opus_multistream_encoder_create (
679 			psf->sf.samplerate,
680 			psf->sf.channels,
681 			nb_streams,
682 			nb_coupled,
683 			oopus->header.stream_map,
684 			OPUS_APPLICATION_AUDIO,
685 			&error) ;
686 		}
687 	else
688 	{	if (psf->sf.channels <= 8)
689 		{	/* Use Vorbis/AC3 channel mappings for surround. */
690 			oopus->header.channel_mapping = 1 ;
691 			}
692 		else
693 		{	/* There is no channel mapping, just audio, in parallel, good luck */
694 			oopus->header.channel_mapping = 255 ;
695 			}
696 
697 		oopus->u.encode.state = opus_multistream_surround_encoder_create (
698 			psf->sf.samplerate,
699 			psf->sf.channels,
700 			oopus->header.channel_mapping,
701 			&nb_streams,
702 			&nb_coupled,
703 			oopus->header.stream_map,
704 			OPUS_APPLICATION_AUDIO,
705 			&error) ;
706 
707 		}
708 
709 	if (error != OPUS_OK)
710 	{	psf_log_printf (psf, "Opus : Error, opus_multistream_encoder_create returned %s\n", opus_strerror (error)) ;
711 		return SFE_BAD_OPEN_FORMAT ;
712 		} ;
713 	oopus->header.nb_streams = nb_streams ;
714 	oopus->header.nb_coupled = nb_coupled ;
715 
716 	opus_multistream_encoder_ctl (oopus->u.encode.state, OPUS_GET_BITRATE (&oopus->u.encode.bitrate)) ;
717 	psf_log_printf (psf, "Encoding at target bitrate of %dbps\n", oopus->u.encode.bitrate) ;
718 
719 	/* TODO: Make configurable? */
720 	error = opus_multistream_encoder_ctl (oopus->u.encode.state, OPUS_SET_COMPLEXITY (10)) ;
721 	if (error != OPUS_OK)
722 	{	/* Non-fatal */
723 		psf_log_printf (psf, "Opus : OPUS_SET_COMPLEXITY returned: %s\n", opus_strerror (error)) ;
724 		}
725 
726 	/*
727 	** Get the encoder delay. This can vary depending on implementation and
728 	** encoder configuration.
729 	** GOTCHA: This returns the preskip at the encoder samplerate, not the
730 	** granulepos rate of 48000Hz needed for header.preskip.
731 	*/
732 	error = opus_multistream_encoder_ctl (oopus->u.encode.state, OPUS_GET_LOOKAHEAD (&lookahead)) ;
733 	if (error != OPUS_OK)
734 	{	psf_log_printf (psf, "Opus : OPUS_GET_LOOKAHEAD returned: %s\n", opus_strerror (error)) ;
735 		return SFE_BAD_OPEN_FORMAT ;
736 		} ;
737 	oopus->header.preskip = lookahead * oopus->sr_factor ;
738 
739 	oopus->len = OGG_OPUS_ENCODE_PACKET_LEN (psf->sf.samplerate) ;
740 	oopus->buffer = malloc (sizeof (float) * psf->sf.channels * oopus->len) ;
741 	if (oopus->buffer == NULL)
742 		return SFE_MALLOC_FAILED ;
743 
744 	/*
745 	** Set up the resident ogg packet structure, ready for writing into.
746 	** 1275 * 3 + 7 bytes of packet per stream is from opusenc from opus-tools
747 	*/
748 	ogg_packet_clear (&odata->opacket) ;
749 	oopus->buffersize = (1275 * 3 + 7) * oopus->header.nb_streams ;
750 	odata->opacket.packet = malloc (oopus->buffersize) ;
751 	odata->opacket.packetno = 2 ;
752 	if (odata->opacket.packet == NULL)
753 		return SFE_MALLOC_FAILED ;
754 
755 	oopus->serialno = psf_rand_int32 () ;
756 	ogg_stream_init (&odata->ostream, oopus->serialno) ;
757 
758 	return 0 ;
759 } /* ogg_opus_setup_encoder */
760 
761 static int
ogg_opus_write_header(SF_PRIVATE * psf,int UNUSED (calc_length))762 ogg_opus_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
763 {	OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
764 	OPUS_PRIVATE *oopus = (OPUS_PRIVATE *) psf->codec_data ;
765 	int nn ;
766 	ogg_packet op ;
767 
768 	oopus->header.version = 1 ;
769 	oopus->header.channels = psf->sf.channels ;
770 
771 	/* FIXME: Allow the user to set this ?! */
772 	oopus->header.gain = 0 ;
773 
774 	if (psf->dataoffset > 0)
775 	{	if (psf->have_written)
776 		{	/*
777 			** Might be possible to deal with this, but it's difficult as we
778 			** have to take Ogg Page header sizes in to account, not just
779 			** packet sizes.
780 			*/
781 			return SFE_UNIMPLEMENTED ;
782 			}
783 		if (psf_is_pipe (psf))
784 			return SFE_NOT_SEEKABLE ;
785 		if (psf_fseek (psf, 0, SEEK_SET) < 0)
786 			return SFE_SEEK_FAILED ;
787 		ogg_stream_reset_serialno (&odata->ostream, oopus->serialno) ;
788 		psf->dataoffset = 0 ;
789 		}
790 	else
791 		opus_print_header (psf, &oopus->header) ;
792 
793 	psf->header.ptr [0] = 0 ;
794 	psf->header.indx = 0 ;
795 
796 	/* Opus Header Marker */
797 	psf_binheader_writef (psf, "eb", BHWv ("OpusHead"), BHWz (8)) ;
798 
799 	/* Ogg Embedding scheme version, Channel Count, Preskip Samples */
800 	psf_binheader_writef (psf, "e112", BHW1 (oopus->header.version), BHW1 (psf->sf.channels), BHW2 (oopus->header.preskip)) ;
801 
802 	/*
803 	** If an original samplerate has not been set by the user command
804 	** SFC_SET_ORIGINAL_SAMPLERATE, write the current samplerate.
805 	*/
806 	if (oopus->header.input_samplerate)
807 		psf_binheader_writef (psf, "e4", BHW4 (oopus->header.input_samplerate)) ;
808 	else
809 		psf_binheader_writef (psf, "e4", BHW4 (psf->sf.samplerate)) ;
810 
811 	/* Input Sample Rate, Gain (S7.8 format), Channel Mapping Type */
812 	psf_binheader_writef (psf, "e21", BHW2 (oopus->header.gain), BHW1 (oopus->header.channel_mapping)) ;
813 
814 	/* Channel mappings, required if not using type 0 (mono/stereo) */
815 	if (oopus->header.channel_mapping > 0)
816 	{	psf_binheader_writef (psf, "11", BHW1 (oopus->header.nb_streams), BHW1 (oopus->header.nb_coupled)) ;
817 		for (nn = 0 ; nn < oopus->header.channels ; nn++)
818 			psf_binheader_writef (psf, "1", BHW1 (oopus->header.stream_map [nn])) ;
819 		} ;
820 
821 	op.packet = psf->header.ptr ;
822 	op.bytes = psf->header.indx ;
823 	op.b_o_s = 1 ;
824 	op.e_o_s = 0 ;
825 	op.granulepos = 0 ;
826 	op.packetno = 1 ;
827 
828 	/* The first page MUST only contain the header, so flush it out now */
829 	ogg_stream_packetin (&odata->ostream, &op) ;
830 	for ( ; (nn = ogg_stream_flush (&odata->ostream, &odata->opage)) ; )
831 	{	if (! (nn = ogg_write_page (psf, &odata->opage)))
832 		{	psf_log_printf (psf, "Opus : Failed to write header!\n") ;
833 			if (psf->error)
834 				return psf->error ;
835 			return SFE_INTERNAL ;
836 			} ;
837 		psf->dataoffset += nn ;
838 		}
839 
840 	/*
841 	** Metadata Tags (manditory)
842 	**
843 	** All tags must be in one packet, which may span pages, and these pages
844 	** must not contain any other packets, so flush. The vendor string should
845 	** be the libopus library version, as it is doing the actual encoding. We
846 	** put the libsndfile identifier in the ENCODER tag.
847 	**
848 	** See: https://wiki.xiph.org/VorbisComment#ENCODER
849 	*/
850 	vorbiscomment_write_tags (psf, &op, &opustags_ident, opus_get_version_string (), - (OGG_OPUS_COMMENT_PAD)) ;
851 	op.packetno = 2 ;
852 	ogg_stream_packetin (&odata->ostream, &op) ;
853 	for ( ; (nn = ogg_stream_flush (&odata->ostream, &odata->opage)) ; )
854 	{	if (! (nn = ogg_write_page (psf, &odata->opage)))
855 		{	psf_log_printf (psf, "Opus : Failed to write comments!\n") ;
856 			if (psf->error)
857 				return psf->error ;
858 			return SFE_INTERNAL ;
859 			} ;
860 		psf->dataoffset += nn ;
861 		}
862 
863 	return 0 ;
864 } /* ogg_opus_write_header */
865 
866 static void
ogg_opus_flush(SF_PRIVATE * psf)867 ogg_opus_flush (SF_PRIVATE *psf)
868 {	OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
869 	OPUS_PRIVATE *oopus = (OPUS_PRIVATE *) psf->codec_data ;
870 	uint64_t last_granulepos ;
871 	int nbytes ;
872 	int len ;
873 	int last_packet ;
874 
875 	/*
876 	** Need to flush both samples waiting for a complete packet and samples
877 	** currently 'inside' the encoder because of its latency. In the case of
878 	** the latter, we need to encode an equivalent amount of silence to push
879 	** them out.
880 	**
881 	** Note that the last packet's granule position might be less than the
882 	** total number of samples completed in it. This is how Ogg embedded Opus
883 	** encodes the amount of appended padding to truncate for gapless playback.
884 	*/
885 
886 	last_granulepos = oopus->pkt_pos + (oopus->sr_factor * oopus->loc) + oopus->header.preskip ;
887 	last_packet = SF_FALSE ;
888 	memset (&(oopus->buffer [oopus->loc * psf->sf.channels]), 0, sizeof (float) * psf->sf.channels * (oopus->len - oopus->loc)) ;
889 
890 	for (last_packet = SF_FALSE ; last_packet == SF_FALSE ; )
891 	{	oopus->pkt_pos += oopus->len * oopus->sr_factor ;
892 		if (oopus->pkt_pos >= last_granulepos)
893 		{	last_packet = SF_TRUE ;
894 			/*
895 			** Try to shorten the last packet to the smallest valid packet size
896 			** to minimize padding samples.
897 			*/
898 			len = (oopus->len * oopus->sr_factor) - (oopus->pkt_pos - last_granulepos) ;
899 			if (len <= 120) /* 2.5 ms */
900 				len = 120 / oopus->sr_factor ;
901 			else if (len <= 240) /* 5 ms */
902 				len = 240 / oopus->sr_factor ;
903 			else if (len <= 480) /* 10 ms */
904 				len = 480 / oopus->sr_factor ;
905 			else
906 				len = oopus->len ;
907 			}
908 		else
909 			len = oopus->len ;
910 
911 		nbytes = opus_multistream_encode_float (oopus->u.encode.state, oopus->buffer,
912 					len, odata->opacket.packet, oopus->buffersize) ;
913 
914 		if (nbytes < 0)
915 		{	psf_log_printf (psf, "Opus : opus_multistream_encode_float returned: %s\n", opus_strerror (nbytes)) ;
916 			break ;
917 			}
918 
919 		odata->opacket.bytes = nbytes ;
920 		odata->opacket.packetno++ ;
921 		if (last_packet)
922 		{	odata->opacket.granulepos = (ogg_int64_t) last_granulepos ;
923 			odata->opacket.e_o_s = 1 ;
924 			}
925 		else
926 			odata->opacket.granulepos = (ogg_int64_t) oopus->pkt_pos ;
927 
928 		ogg_stream_packetin (&odata->ostream, &odata->opacket) ;
929 		while (ogg_stream_pageout (&odata->ostream, &odata->opage))
930 			ogg_write_page (psf, &odata->opage) ;
931 		} ;
932 
933 	while (ogg_stream_flush (&odata->ostream, &odata->opage))
934 		ogg_write_page (psf, &odata->opage) ;
935 } /* ogg_opus_flush */
936 
937 static int
ogg_opus_calculate_page_duration(OGG_PRIVATE * odata)938 ogg_opus_calculate_page_duration (OGG_PRIVATE *odata)
939 {	int i, samples, duration ;
940 	ogg_packet *ppkt ;
941 
942 	duration = 0 ;
943 	for (i = 0 , ppkt = odata->pkt ; i < odata->pkt_len ; i++, ppkt++)
944 	{	/* Use 48kHz to get the sample count for use with granule positions. */
945 		samples = opus_packet_get_nb_samples (ppkt->packet, ppkt->bytes, 48000) ;
946 		if (samples > 0)
947 			duration += samples ;
948 		} ;
949 	return duration ;
950 } /* ogg_opus_calculate_page_duration */
951 
952 static int
ogg_opus_unpack_next_page(SF_PRIVATE * psf,OGG_PRIVATE * odata,OPUS_PRIVATE * oopus)953 ogg_opus_unpack_next_page (SF_PRIVATE *psf, OGG_PRIVATE *odata, OPUS_PRIVATE *oopus)
954 {	int nn ;
955 
956 	nn = ogg_stream_unpack_page (psf, odata) ;
957 
958 	if (nn == 1)
959 	{	oopus->pkt_pos = oopus->pg_pos ;
960 		oopus->pg_pos = odata->pkt [odata->pkt_len - 1].granulepos ;
961 		}
962 	else if (nn == 2)
963 	{	uint64_t gp, last_page ;
964 
965 		/* Found a hole. Need to recalculated pkt_pos from pg_pos */
966 		last_page = oopus->pg_pos ;
967 		oopus->pg_pos = odata->pkt [odata->pkt_len - 1].granulepos ;
968 		gp = ogg_opus_calculate_page_duration (odata) ;
969 		oopus->pkt_pos = oopus->pg_pos - gp ;
970 		psf_log_printf (psf, "Opus : Hole found appears to be of length %D samples.\n",
971 				(oopus->pkt_pos - last_page) / (uint64_t) oopus->sr_factor) ;
972 		/*
973 		** Could save the hole size here, and have ogg_opus_read_refill()
974 		** do packet loss concealment until the hole is gone, but libopus does
975 		** PLC by generating white-noise for the duration of the hole. That is
976 		** the correct thing for use in telephony, but it isn't generally
977 		** appropriate here. It actually sounds better with no PLC, as the
978 		** lapped nature of full-width Opus means the two edges of the hole
979 		** will be blended together.
980 		*/
981 		return 1 ;
982 		}
983 
984 	return nn ;
985 } /* ogg_opus_unpack_next_page */
986 
987 static int
ogg_opus_read_refill(SF_PRIVATE * psf,OGG_PRIVATE * odata,OPUS_PRIVATE * oopus)988 ogg_opus_read_refill (SF_PRIVATE *psf, OGG_PRIVATE *odata, OPUS_PRIVATE *oopus)
989 {	uint64_t pkt_granulepos ;
990 	int nn, nsamp ;
991 	ogg_packet *ppkt ;
992 
993 	if (odata->pkt_indx == odata->pkt_len)
994 	{	nn = ogg_opus_unpack_next_page (psf, odata, oopus) ;
995 		if (nn <= 0)
996 			return nn ;
997 		}
998 
999 	if (odata->pkt_indx == odata->pkt_len)
1000 		return 0 ;
1001 
1002 	ppkt = odata->pkt + odata->pkt_indx ;
1003 	nsamp = opus_multistream_decode_float (oopus->u.decode.state,
1004 				ppkt->packet, ppkt->bytes, oopus->buffer, oopus->buffersize, 0) ;
1005 
1006 	if (nsamp == OPUS_BUFFER_TOO_SMALL)
1007 	{	nsamp = opus_packet_get_nb_samples (ppkt->packet, ppkt->bytes, psf->sf.samplerate) ;
1008 		psf_log_printf (psf, "Growing decode buffer to hold %d samples from %d\n",
1009 			nsamp, oopus->buffersize) ;
1010 		if (nsamp > 5760)
1011 		{	psf_log_printf (psf, "Packet is larger than maximum allowable of 120ms!? Skipping.\n") ;
1012 			return 0 ;
1013 			} ;
1014 		oopus->buffersize = nsamp ;
1015 
1016 		free (oopus->buffer) ;
1017 		oopus->buffer = NULL ;
1018 		oopus->buffer = malloc (sizeof (float) * oopus->buffersize * psf->sf.channels) ;
1019 		if (oopus->buffer == NULL)
1020 		{	psf->error = SFE_MALLOC_FAILED ;
1021 			oopus->buffersize = 0 ;
1022 			return -1 ;
1023 			} ;
1024 
1025 		nsamp = opus_multistream_decode_float (oopus->u.decode.state,
1026 				ppkt->packet, ppkt->bytes, oopus->buffer, oopus->buffersize, 0) ;
1027 		} ;
1028 	odata->pkt_indx ++ ;
1029 
1030 	if (nsamp < 0)
1031 	{	psf_log_printf (psf, "Opus : opus_multistream_decode returned: %s\n",
1032 			opus_strerror (nsamp)) ;
1033 		psf->error = SFE_INTERNAL ;
1034 		return nsamp ;
1035 		} ;
1036 
1037 	/*
1038 	** Check for if this decoded packet is the last of the stream, in
1039 	** which case a page granule position which is shorter than the
1040 	** sample count of all packets in the page indicates that the last
1041 	** samples are padding and should be dropped.
1042 	*/
1043 	pkt_granulepos = oopus->pkt_pos + (nsamp * oopus->sr_factor) ;
1044 	if (pkt_granulepos <= oopus->pg_pos)
1045 	{	oopus->len = nsamp ;
1046 		}
1047 	else
1048 	{	if (ogg_page_eos (&odata->opage))
1049 		{	/*
1050 			** Possible for pg_pos < pkt_pos if there is a trailing
1051 			** packet. It's not supposed to happen, but could.
1052 			*/
1053 			oopus->len = SF_MAX ((int) (oopus->pg_pos - oopus->pkt_pos) / oopus->sr_factor, 0) ;
1054 			}
1055 		else
1056 		{	/*
1057 			** From https://wiki.xiph.org/OggOpus#Granule_Position
1058 			**	A decoder MUST reject as invalid any stream where the granule
1059 			**	position is smaller than the number of samples contained in
1060 			**	packets that complete on the first page with a completed
1061 			**	packet, unless that page has the 'end of stream' flag set. It
1062 			**	MAY defer this action until it decodes the last packet
1063 			**	completed on that page.
1064 			*/
1065 			psf_log_printf (psf, "Opus : Mid-stream page's granule position %D is less than total samples of %D\n", oopus->pg_pos, pkt_granulepos) ;
1066 			psf->error = SFE_MALFORMED_FILE ;
1067 			return -1 ;
1068 			} ;
1069 		} ;
1070 
1071 	if (oopus->len > oopus->buffersize)
1072 	{	free (oopus->buffer) ;
1073 		oopus->buffersize = oopus->len ;
1074 		oopus->buffer = malloc (sizeof (float) * oopus->buffersize * psf->sf.channels) ;
1075 		if (oopus->buffer == NULL)
1076 		{	psf->error = SFE_MALLOC_FAILED ;
1077 			oopus->buffersize = 0 ;
1078 			return -1 ;
1079 			} ;
1080 		} ;
1081 
1082 	/*
1083 	** Check for if this decoded packet contains samples from before the pre-
1084 	** skip point, indicating that these samples are padding to get the decoder
1085 	** to converge and should be dropped.
1086 	*/
1087 	if (oopus->pkt_pos < (unsigned) oopus->header.preskip)
1088 		oopus->loc = SF_MIN ((oopus->header.preskip - (int) oopus->pkt_pos) / oopus->sr_factor, oopus->len) ;
1089 	else
1090 		oopus->loc = 0 ;
1091 
1092 	oopus->pkt_pos = pkt_granulepos ;
1093 
1094 	return nsamp ;
1095 } /* ogg_opus_read_refill */
1096 
1097 static int
ogg_opus_write_out(SF_PRIVATE * psf,OGG_PRIVATE * odata,OPUS_PRIVATE * oopus)1098 ogg_opus_write_out (SF_PRIVATE *psf, OGG_PRIVATE *odata, OPUS_PRIVATE *oopus)
1099 {	int nbytes ;
1100 
1101 	if (oopus->u.encode.lsb != oopus->u.encode.lsb_last)
1102 		opus_multistream_encoder_ctl (oopus->u.encode.state, OPUS_SET_LSB_DEPTH (oopus->u.encode.lsb)) ;
1103 
1104 	nbytes = opus_multistream_encode_float (oopus->u.encode.state,
1105 		oopus->buffer, oopus->len,
1106 		odata->opacket.packet, oopus->buffersize) ;
1107 
1108 	if (nbytes < 0)
1109 	{	psf_log_printf (psf, "Opus : Error, opus_multistream_encode_float returned: %s\n", opus_strerror (nbytes)) ;
1110 		psf->error = SFE_INTERNAL ;
1111 		return nbytes ;
1112 		} ;
1113 
1114 	oopus->u.encode.last_segments += (nbytes + 255) / 255 ;
1115 	oopus->pkt_pos += oopus->len * oopus->sr_factor ;
1116 	odata->opacket.bytes = nbytes ;
1117 	odata->opacket.granulepos = oopus->pkt_pos ;
1118 	odata->opacket.packetno++ ;
1119 
1120 	/*
1121 	** Decide whether to flush the Ogg page *before* adding the new packet to
1122 	** it. Check both for if there is more than 1 second of audio (our default
1123 	** Ogg page latency, this latency can be modified using sf_command())
1124 	** or if adding the packet would cause a continued page,
1125 	** in which case we might as well make a new page anyways.
1126 	*/
1127 	for ( ; ; )
1128 	{	if (oopus->pkt_pos - oopus->pg_pos >= oopus->u.encode.latency || oopus->u.encode.last_segments >= 255)
1129 			nbytes = ogg_stream_flush_fill (&odata->ostream, &odata->opage, 255 * 255) ;
1130 		else
1131 			nbytes = ogg_stream_pageout_fill (&odata->ostream, &odata->opage, 255 * 255) ;
1132 		if (nbytes > 0)
1133 		{	oopus->u.encode.last_segments -= ogg_page_segments (&odata->opage) ;
1134 			oopus->pg_pos = oopus->pkt_pos ;
1135 			ogg_write_page (psf, &odata->opage) ;
1136 			}
1137 		else
1138 			break ;
1139 		} ;
1140 
1141 	ogg_stream_packetin (&odata->ostream, &odata->opacket) ;
1142 	oopus->loc = 0 ;
1143 	oopus->u.encode.lsb_last = oopus->u.encode.lsb ;
1144 	oopus->u.encode.lsb = 0 ;
1145 
1146 	return 1 ;
1147 } /* ogg_opus_write_out */
1148 
1149 static sf_count_t
ogg_opus_read_s(SF_PRIVATE * psf,short * ptr,sf_count_t len)1150 ogg_opus_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
1151 {	OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
1152 	OPUS_PRIVATE *oopus = (OPUS_PRIVATE *) psf->codec_data ;
1153 	sf_count_t total = 0 ;
1154 	sf_count_t readlen, i ;
1155 	float *iptr ;
1156 
1157 	while (total < len)
1158 	{	if (oopus->loc == oopus->len)
1159 		{	if (ogg_opus_read_refill (psf, odata, oopus) <= 0)
1160 				return total ;
1161 			} ;
1162 
1163 		readlen = SF_MIN (len - total, (sf_count_t) (oopus->len - oopus->loc) * psf->sf.channels) ;
1164 		if (readlen > 0)
1165 		{	iptr = oopus->buffer + oopus->loc * psf->sf.channels ;
1166 			i = total ;
1167 			total += readlen ;
1168 
1169 			if (psf->float_int_mult)
1170 			{	float inverse = 1.0 / psf->float_max ;
1171 				for ( ; i < total ; i++)
1172 				{	ptr [i] = psf_lrintf (((*(iptr++)) * inverse) * 32767.0f) ;
1173 					} ;
1174 				}
1175 			else
1176 			{	for ( ; i < total ; i++)
1177 				{	ptr [i] = psf_lrintf ((*(iptr++)) * 32767.0f) ;
1178 					} ;
1179 				} ;
1180 			oopus->loc += (readlen / psf->sf.channels) ;
1181 			} ;
1182 		} ;
1183 	return total ;
1184 } /* ogg_opus_read_s */
1185 
1186 static sf_count_t
ogg_opus_read_i(SF_PRIVATE * psf,int * ptr,sf_count_t len)1187 ogg_opus_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
1188 {	OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
1189 	OPUS_PRIVATE *oopus = (OPUS_PRIVATE *) psf->codec_data ;
1190 	sf_count_t total = 0 ;
1191 	sf_count_t readlen, i ;
1192 	float *iptr ;
1193 
1194 	while (total < len)
1195 	{	if (oopus->loc == oopus->len)
1196 		{	if (ogg_opus_read_refill (psf, odata, oopus) <= 0)
1197 				return total ;
1198 			} ;
1199 
1200 		readlen = SF_MIN (len - total, (sf_count_t) (oopus->len - oopus->loc) * psf->sf.channels) ;
1201 		if (readlen > 0)
1202 		{	iptr = oopus->buffer + oopus->loc * psf->sf.channels ;
1203 			i = total ;
1204 			total += readlen ;
1205 
1206 			if (psf->float_int_mult)
1207 			{	float inverse = 1.0 / psf->float_max ;
1208 				for ( ; i < total ; i++)
1209 				{	ptr [i] = psf_lrintf (((*(iptr++)) * inverse) * 2147483647.0f) ;
1210 					}
1211 				}
1212 			else
1213 			{	for ( ; i < total ; i++)
1214 				{	ptr [i] = psf_lrintf ((*(iptr++)) * 2147483647.0f) ;
1215 					}
1216 				} ;
1217 			oopus->loc += (readlen / psf->sf.channels) ;
1218 			} ;
1219 		} ;
1220 	return total ;
1221 } /* ogg_opus_read_i */
1222 
1223 static sf_count_t
ogg_opus_read_f(SF_PRIVATE * psf,float * ptr,sf_count_t len)1224 ogg_opus_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
1225 {	OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
1226 	OPUS_PRIVATE *oopus = (OPUS_PRIVATE *) psf->codec_data ;
1227 	sf_count_t total = 0 ;
1228 	sf_count_t readlen ;
1229 
1230 	while (total < len)
1231 	{	if (oopus->loc == oopus->len)
1232 		{	if (ogg_opus_read_refill (psf, odata, oopus) <= 0)
1233 				return total ;
1234 			} ;
1235 
1236 		readlen = SF_MIN (len - total, (sf_count_t) (oopus->len - oopus->loc) * psf->sf.channels) ;
1237 		if (readlen > 0)
1238 		{	memcpy (&(ptr [total]), &(oopus->buffer [oopus->loc * psf->sf.channels]), sizeof (float) * readlen) ;
1239 			total += readlen ;
1240 			oopus->loc += (readlen / psf->sf.channels) ;
1241 			} ;
1242 		} ;
1243 	return total ;
1244 } /* ogg_opus_read_f */
1245 
1246 static sf_count_t
ogg_opus_read_d(SF_PRIVATE * psf,double * ptr,sf_count_t len)1247 ogg_opus_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
1248 {	OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
1249 	OPUS_PRIVATE *oopus = (OPUS_PRIVATE *) psf->codec_data ;
1250 	sf_count_t total = 0 ;
1251 	sf_count_t readlen, i ;
1252 	float *fptr ;
1253 
1254 	while (total < len)
1255 	{	if (oopus->loc >= oopus->len)
1256 		{	if (ogg_opus_read_refill (psf, odata, oopus) <= 0)
1257 				return total ;
1258 			} ;
1259 
1260 		readlen = SF_MIN (len - total, (sf_count_t) (oopus->len - oopus->loc) * psf->sf.channels) ;
1261 
1262 		if (readlen > 0)
1263 		{	fptr = oopus->buffer + oopus->loc * psf->sf.channels ;
1264 			i = total ;
1265 			total += readlen ;
1266 			for ( ; i < total ; i++)
1267 			{	ptr [i] = *fptr++ ;
1268 				} ;
1269 			oopus->loc += readlen / psf->sf.channels ;
1270 			} ;
1271 		} ;
1272 	return total ;
1273 } /* ogg_opus_read_d */
1274 
1275 static sf_count_t
ogg_opus_write_s(SF_PRIVATE * psf,const short * ptr,sf_count_t len)1276 ogg_opus_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
1277 {	OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
1278 	OPUS_PRIVATE *oopus = (OPUS_PRIVATE *) psf->codec_data ;
1279 	sf_count_t total, i ;
1280 	int writelen ;
1281 	float *optr ;
1282 
1283 	if (oopus->u.encode.lsb < 16)
1284 		oopus->u.encode.lsb = 16 ;
1285 
1286 	for (total = 0 ; total < len ; )
1287 	{	if (oopus->loc >= oopus->len)
1288 		{	/* Need to encode the buffer */
1289 			if (ogg_opus_write_out (psf, odata, oopus) <= 0)
1290 				return total ;
1291 			} ;
1292 
1293 		writelen = SF_MIN (len - total, (sf_count_t) (oopus->len - oopus->loc) * psf->sf.channels) ;
1294 		if (writelen)
1295 		{	optr = oopus->buffer + oopus->loc * psf->sf.channels ;
1296 			i = total ;
1297 			total += writelen ;
1298 			for ( ; i < total ; i++)
1299 			{	*optr++ = (float) (ptr [i]) / 32767.0f ;
1300 				}
1301 			oopus->loc += (writelen / psf->sf.channels) ;
1302 			} ;
1303 		} ;
1304 	return total ;
1305 } /* ogg_opus_write_s */
1306 
1307 static sf_count_t
ogg_opus_write_i(SF_PRIVATE * psf,const int * ptr,sf_count_t len)1308 ogg_opus_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
1309 {	OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
1310 	OPUS_PRIVATE *oopus = (OPUS_PRIVATE *) psf->codec_data ;
1311 	sf_count_t total, i ;
1312 	int writelen ;
1313 	float *optr ;
1314 
1315 	if (oopus->u.encode.lsb < 24)
1316 		oopus->u.encode.lsb = 24 ;
1317 
1318 	for (total = 0 ; total < len ; )
1319 	{	if (oopus->loc >= oopus->len)
1320 		{	/* Need to encode the buffer */
1321 			if (ogg_opus_write_out (psf, odata, oopus) <= 0)
1322 				return total ;
1323 			} ;
1324 
1325 		writelen = SF_MIN (len - total, (sf_count_t) (oopus->len - oopus->loc) * psf->sf.channels) ;
1326 		if (writelen)
1327 		{	optr = oopus->buffer + oopus->loc * psf->sf.channels ;
1328 			i = total ;
1329 			total += writelen ;
1330 			for ( ; i < total ; i++)
1331 			{	*optr++ = (float) (ptr [i]) / 2147483647.0f ;
1332 				} ;
1333 			oopus->loc += (writelen / psf->sf.channels) ;
1334 			} ;
1335 		} ;
1336 	return total ;
1337 } /* ogg_opus_write_i */
1338 
1339 static sf_count_t
ogg_opus_write_f(SF_PRIVATE * psf,const float * ptr,sf_count_t len)1340 ogg_opus_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
1341 {	OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
1342 	OPUS_PRIVATE *oopus = (OPUS_PRIVATE *) psf->codec_data ;
1343 	sf_count_t total ;
1344 	int writelen ;
1345 
1346 	if (oopus->u.encode.lsb < 24)
1347 		oopus->u.encode.lsb = 24 ;
1348 
1349 	for (total = 0 ; total < len ; )
1350 	{	if (oopus->loc >= oopus->len)
1351 		{	/* Need to encode the buffer */
1352 			if (ogg_opus_write_out (psf, odata, oopus) <= 0)
1353 				return total ;
1354 			} ;
1355 
1356 		writelen = SF_MIN (len - total, (sf_count_t) (oopus->len - oopus->loc) * psf->sf.channels) ;
1357 		if (writelen)
1358 		{	memcpy (&(oopus->buffer [oopus->loc * psf->sf.channels]), &(ptr [total]), sizeof (float) * writelen) ;
1359 			total += writelen ;
1360 			oopus->loc += (writelen / psf->sf.channels) ;
1361 			} ;
1362 		} ;
1363 	return total ;
1364 } /* ogg_opus_write_f */
1365 
1366 static sf_count_t
ogg_opus_write_d(SF_PRIVATE * psf,const double * ptr,sf_count_t len)1367 ogg_opus_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
1368 {	OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
1369 	OPUS_PRIVATE *oopus = (OPUS_PRIVATE *) psf->codec_data ;
1370 	sf_count_t total, i ;
1371 	int writelen ;
1372 	float *optr ;
1373 
1374 	if (oopus->u.encode.lsb < 24)
1375 		oopus->u.encode.lsb = 24 ;
1376 
1377 	for (total = 0 ; total < len ; )
1378 	{	if (oopus->loc >= oopus->len)
1379 		{	/* Need to encode the buffer */
1380 			if (ogg_opus_write_out (psf, odata, oopus) <= 0)
1381 				return total ;
1382 			} ;
1383 
1384 		writelen = SF_MIN (len - total, (sf_count_t) (oopus->len - oopus->loc) * psf->sf.channels) ;
1385 		if (writelen)
1386 		{	optr = oopus->buffer + oopus->loc * psf->sf.channels ;
1387 			i = total ;
1388 			total += writelen ;
1389 			for ( ; i < total ; i++)
1390 			{	*optr++ = (float) (ptr [i]) ;
1391 				} ;
1392 			oopus->loc += (writelen / psf->sf.channels) ;
1393 			} ;
1394 		} ;
1395 	return total ;
1396 } /* ogg_opus_write_d */
1397 
1398 static int
ogg_opus_analyze_file(SF_PRIVATE * psf)1399 ogg_opus_analyze_file (SF_PRIVATE *psf)
1400 {	OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
1401 	OPUS_PRIVATE *oopus = (OPUS_PRIVATE *) psf->codec_data ;
1402 	uint64_t gp ;
1403 	sf_count_t saved_offset, last_page ;
1404 	int error ;
1405 
1406 	psf->sf.sections = 1 ;
1407 	psf->sf.frames	= SF_COUNT_MAX ;
1408 	oopus->u.decode.gp_end = (uint64_t) -1 ;
1409 	oopus->u.decode.last_offset = SF_COUNT_MAX ;
1410 
1411 	psf->dataoffset = ogg_sync_ftell (psf) ;
1412 	if (psf->filelength != SF_COUNT_MAX)
1413 		psf->datalength = psf->filelength - psf->dataoffset ;
1414 	else
1415 		psf->datalength = SF_COUNT_MAX ;
1416 
1417 	/*
1418 	** Calculate the start granule position offset
1419 	**
1420 	** OggOpus streams are allowed to start with a granule position other than
1421 	** zero. This allows for cutting the beginning off of streams without
1422 	** having to modify all following granule positions, or for recording/
1423 	** joining a live stream in the middle. To figure out the offset, we need
1424 	** to sum up how many samples are in all the packets that complete in the
1425 	** page and subtract it from the page granule position.
1426 	**
1427 	** If this is the last page of the steam (EOS set), this is not possible,
1428 	** as the granule position may be /less/ than the number of samples, to
1429 	** indicate how many samples are end-padding. In this case the granule
1430 	** position offset of the file must be 0, as otherwise it is considered
1431 	** malformed.
1432 	*/
1433 	error = ogg_opus_unpack_next_page (psf, odata, oopus) ;
1434 	if (error < 0 && psf->error)
1435 		return psf->error ;
1436 
1437 	gp = ogg_opus_calculate_page_duration (odata) ;
1438 	if (gp <= 0)
1439 	{	psf_log_printf (psf, "Opus : Page duration of zero!\n") ;
1440 		return SFE_MALFORMED_FILE ;
1441 		} ;
1442 
1443 	if (!ogg_page_eos (&odata->opage))
1444 	{	if (gp > oopus->pg_pos)
1445 		{	psf_log_printf (psf, "Opus : First data page's granule position is less than total number of samples on the page!\n") ;
1446 			return SFE_MALFORMED_FILE ;
1447 			}
1448 		oopus->pkt_pos = oopus->pg_pos - gp ;
1449 		}
1450 	else if (gp < oopus->pg_pos)
1451 	{	psf_log_printf (psf, "Opus : First data page is also the last, and granule position has an (ambigious) offset.\n") ;
1452 		return SFE_MALFORMED_FILE ;
1453 		} ;
1454 	oopus->u.decode.gp_start = oopus->pkt_pos ;
1455 
1456 	if (!psf->sf.seekable)
1457 		return 0 ;
1458 
1459 	/*
1460 	** Find the last page and fetch the last granule position.
1461 	** First, save were we are now.
1462 	*/
1463 	saved_offset = ogg_sync_ftell (psf) ;
1464 
1465 	/* This uses the sync page buffer, the stream page buffer is untouched. */
1466 	last_page = ogg_sync_last_page_before (psf, odata, &oopus->u.decode.gp_end, psf->filelength, oopus->serialno) ;
1467 	if (last_page > 0)
1468 	{	if (!ogg_page_eos (&odata->opage))
1469 			psf_log_printf (psf, "Ogg : Last page lacks an end-of-stream bit.\n") ;
1470 		if (last_page + odata->opage.header_len + odata->opage.body_len < psf->filelength)
1471 			psf_log_printf (psf, "Ogg : Junk after the last page.\n") ;
1472 		oopus->u.decode.last_offset = last_page ;
1473 
1474 		if (oopus->u.decode.gp_end != (uint64_t) -1)
1475 		{	psf->sf.frames = (oopus->u.decode.gp_end - oopus->u.decode.gp_start
1476 				- oopus->header.preskip) / oopus->sr_factor ;
1477 			} ;
1478 		} ;
1479 
1480 
1481 	psf_log_printf (psf, "  Granule pos offset  : %D\n", oopus->u.decode.gp_start) ;
1482 	if (oopus->u.decode.gp_end != (uint64_t) -1)
1483 		psf_log_printf (psf, "  Last Granule pos : %D\n", oopus->u.decode.gp_end) ;
1484 
1485 	/* Go back to where we left off. */
1486 	ogg_sync_fseek (psf, saved_offset, SEEK_SET) ;
1487 	return 0 ;
1488 } /* ogg_opus_analyze_file */
1489 
1490 /*
1491 ** ogg_opus_null_read
1492 **
1493 ** Decode samples, doing nothing with them, until the desired granule position
1494 ** is reached.
1495 */
1496 static sf_count_t
ogg_opus_null_read(SF_PRIVATE * psf,sf_count_t offset)1497 ogg_opus_null_read (SF_PRIVATE *psf, sf_count_t offset)
1498 {	OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
1499 	OPUS_PRIVATE *oopus = (OPUS_PRIVATE *) psf->codec_data ;
1500 	sf_count_t total ;
1501 
1502 	total = (oopus->pkt_pos / oopus->sr_factor) - (oopus->len - oopus->loc) ;
1503 	for ( ; total < offset ; )
1504 	{	sf_count_t readlen = SF_MIN ((int) (offset - total), (oopus->len - oopus->loc)) ;
1505 		if (readlen > 0)
1506 		{	total += readlen ;
1507 			oopus->loc += readlen ;
1508 			} ;
1509 		if (oopus->loc == oopus->len)
1510 		{	if (ogg_opus_read_refill (psf, odata, oopus) <= 0)
1511 				return total ;
1512 			/*
1513 			** Ignore pre-skip skipping. The preskip was accounted for in the
1514 			** arugment to offset, so we need to count it.
1515 			*/
1516 			oopus->loc = 0 ;
1517 			} ;
1518 		} ;
1519 	return total ;
1520 } /* ogg_opus_null_read */
1521 
1522 /*
1523 ** ogg_opus_page_seek_search
1524 **
1525 ** Search within the file for the page with the highest granule position at or
1526 ** before our target.
1527 */
1528 static int
ogg_opus_page_seek_search(SF_PRIVATE * psf,uint64_t target_gp)1529 ogg_opus_page_seek_search (SF_PRIVATE *psf, uint64_t target_gp)
1530 {	OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
1531 	OPUS_PRIVATE *oopus = (OPUS_PRIVATE *) psf->codec_data ;
1532 	uint64_t pcm_start ;
1533 	uint64_t pcm_end ;
1534 	uint64_t best_gp ;
1535 	sf_count_t begin ;
1536 	sf_count_t end ;
1537 	sf_count_t old_pos ;
1538 	int ret ;
1539 
1540 	best_gp = pcm_start = oopus->u.decode.gp_start ;
1541 	pcm_end = oopus->u.decode.gp_end ;
1542 	begin = psf->dataoffset ;
1543 	end = oopus->u.decode.last_offset ;
1544 
1545 	/* Search the Ogg stream for such a page */
1546 	old_pos = ogg_sync_ftell (psf) ;
1547 	ret = ogg_stream_seek_page_search (psf, odata, target_gp, pcm_start, pcm_end, &best_gp, begin, end, 48000) ;
1548 	if (ret != 0)
1549 	{	ogg_sync_fseek (psf, old_pos, SEEK_SET) ;
1550 		return ret ;
1551 		} ;
1552 
1553 	/* Load the page that contains our pre-roll target */
1554 	oopus->loc = 0 ;
1555 	oopus->len = 0 ;
1556 	if ((ret = ogg_opus_unpack_next_page (psf, odata, oopus)) != 1)
1557 		return ret ;
1558 	oopus->pkt_pos = best_gp ;
1559 
1560 	/* Reset the decoder (gain settings survive the reset) */
1561 	opus_multistream_decoder_ctl (oopus->u.decode.state, OPUS_RESET_STATE) ;
1562 
1563 	return 0 ;
1564 } /* ogg_opus_page_seek_search */
1565 
1566 /*
1567 ** ogg_opus_page_seek_manual
1568 **
1569 ** Seek to the beginning of the Ogg stream and read pages until we find one with
1570 ** a granule position at or before our target.
1571 */
1572 static sf_count_t
ogg_opus_page_seek_manual(SF_PRIVATE * psf,uint64_t target_gp)1573 ogg_opus_page_seek_manual (SF_PRIVATE *psf, uint64_t target_gp)
1574 {	OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
1575 	OPUS_PRIVATE *oopus = (OPUS_PRIVATE *) psf->codec_data ;
1576 	sf_count_t pos ;
1577 	int nn ;
1578 
1579 	if (oopus->pg_pos > target_gp)
1580 	{	ogg_stream_reset (&odata->ostream) ;
1581 		pos = ogg_sync_fseek (psf, psf->dataoffset, SEEK_SET) ;
1582 		if (pos < 0)
1583 			return pos ;
1584 		oopus->pg_pos = oopus->u.decode.gp_start ;
1585 		opus_multistream_decoder_ctl (oopus->u.decode.state, OPUS_RESET_STATE) ;
1586 		} ;
1587 
1588 	while (oopus->pg_pos < target_gp)
1589 	{	nn = ogg_opus_unpack_next_page (psf, odata, oopus) ;
1590 		if (nn <= 0)
1591 			return nn ;
1592 		} ;
1593 
1594 	return 1 ;
1595 } /* ogg_opus_page_seek_manual */
1596 
1597 static sf_count_t
ogg_opus_seek(SF_PRIVATE * psf,int mode,sf_count_t offset)1598 ogg_opus_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
1599 {	OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
1600 	OPUS_PRIVATE *oopus = (OPUS_PRIVATE *) psf->codec_data ;
1601 	uint64_t target_gp, current_gp ;
1602 	int ret ;
1603 
1604 	/* Only support seeking in read mode. */
1605 	if (mode != SFM_READ || psf->file.mode != SFM_READ)
1606 	{	psf->error = SFE_BAD_SEEK ;
1607 		return PSF_SEEK_ERROR ;
1608 		} ;
1609 
1610 	/* Figure out the current position granule pos. Use the start of the
1611 	 * current buffer, to avoid backwards seeking if the target is on the page
1612 	 * but before the current locaiton. */
1613 	oopus->loc = 0 ;
1614 	current_gp = oopus->pkt_pos - (uint64_t) (oopus->len * oopus->sr_factor) ;
1615 
1616 	/* Calculate the target granule pos. This includes the decoder delay and
1617 	 * the file granule position offset. */
1618 	target_gp = offset * oopus->sr_factor ;
1619 	target_gp += oopus->u.decode.gp_start ;
1620 	target_gp += oopus->header.preskip ;
1621 
1622 	/* Check if we need to do a page seek. */
1623 	if (target_gp < current_gp || target_gp - current_gp > OGG_OPUS_PREROLL)
1624 	{	uint64_t preroll_gp ;
1625 
1626 		/* For a page seek, use an earlier target granule pos, giving the
1627 		 * decoder samples to converge before the actual target. */
1628 		if (target_gp >= OGG_OPUS_PREROLL + oopus->u.decode.gp_start + (uint64_t) oopus->header.preskip)
1629 		{	preroll_gp = target_gp - OGG_OPUS_PREROLL ;
1630 			}
1631 		else
1632 		{	preroll_gp = oopus->u.decode.gp_start + (uint64_t) oopus->header.preskip ;
1633 			} ;
1634 
1635 		if (oopus->u.decode.gp_end == (uint64_t) -1)
1636 		{	/*
1637 			** Don't know the end of the file. Could be a chained file we don't yet
1638 			** support. Oh well, just do it manually.
1639 			*/
1640 			ogg_opus_page_seek_manual (psf, preroll_gp) ;
1641 			}
1642 		else
1643 		{	ret = ogg_opus_page_seek_search (psf, preroll_gp) ;
1644 			if (ret < 0)
1645 			{	/*
1646 				** Page seek failed, what to do? Could be bad data. We can
1647 				** either fall-back to manual seeking or bail. Manaul seeking
1648 				** from the beginning has the advantage of finding where the
1649 				** file goes bad.
1650 				*/
1651 				ret = ogg_opus_page_seek_manual (psf, preroll_gp) ;
1652 				if (ret < 0)
1653 				{	/*
1654 					** If were here, and there is no error, we can be pretty
1655 					** sure that it's the file that is to blame.
1656 					*/
1657 					if (!psf->error)
1658 						psf->error = SFE_MALFORMED_FILE ;
1659 					return ret ;
1660 					} ;
1661 				} ;
1662 			} ;
1663 
1664 		/*
1665 		** Skip over packets on the found page that are before our pre-roll
1666 		** target to avoid unnecessary decoding, and make decoder convergence
1667 		** independent of page boundaries for more visible errors.
1668 		*/
1669 		for ( ; odata->pkt_indx != odata->pkt_len ; )
1670 		{	ogg_packet *ppkt = &odata->pkt [odata->pkt_indx] ;
1671 			int nsamp = opus_packet_get_nb_samples (ppkt->packet, ppkt->bytes, 48000) ;
1672 			if (oopus->pkt_pos + nsamp < preroll_gp)
1673 			{	oopus->pkt_pos += nsamp ;
1674 				odata->pkt_indx++ ;
1675 				}
1676 			else
1677 				break ;
1678 			} ;
1679 		} ;
1680 
1681 	/*
1682 	** We've seeked or skipped through pages until just before our target,
1683 	** now decode until we hit it.
1684 	*/
1685 	offset = ogg_opus_null_read (psf, target_gp / oopus->sr_factor) ;
1686 	return offset - ((oopus->header.preskip + oopus->u.decode.gp_start) / oopus->sr_factor) ;
1687 
1688 } /* ogg_opus_seek */
1689 
1690 static int
ogg_opus_command(SF_PRIVATE * psf,int command,void * data,int datasize)1691 ogg_opus_command (SF_PRIVATE *psf, int command, void *data, int datasize)
1692 {	OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
1693 	OPUS_PRIVATE *oopus = (OPUS_PRIVATE *) psf->codec_data ;
1694 	double quality ;
1695 	double latency ;
1696 	int error ;
1697 
1698 	switch (command)
1699 	{	case SFC_SET_CHANNEL_MAP_INFO :
1700 			/* TODO: figure this out */
1701 			break ;
1702 
1703 		case SFC_SET_OGG_PAGE_LATENCY :
1704 			/*
1705 			** Argument: double, range 50 to 1600.
1706 			** Average length of OGG page in ms.
1707 			** This length drive the flush of pages.
1708 			*/
1709 			if (data == NULL || datasize != SIGNED_SIZEOF (double))
1710 				return SFE_BAD_COMMAND_PARAM ;
1711 
1712 			latency = *((double *) data) ;
1713 			if (latency < 50)
1714 				latency = 50 ;
1715 
1716 			if (latency > 1600)
1717 				latency = 1600 ;
1718 
1719 			oopus->u.encode.latency = ((unsigned long) latency) * 48 ;
1720 			break ;
1721 
1722 		case SFC_SET_COMPRESSION_LEVEL :
1723 			/*
1724 			** Argument: double, range 0.0 (lest compressed, best quality) to
1725 			** 1.0 (most compressed, worst quality)
1726 			*/
1727 			if (data == NULL || datasize != SIGNED_SIZEOF (double))
1728 				return SFE_BAD_COMMAND_PARAM ;
1729 
1730 			/* Usable bitrate range is  [6, 256] kbps per channel. */
1731 			quality = *((double *) data) ;
1732 			oopus->u.encode.bitrate = (int) (((1.0 - quality) * (250000.0)) + 6000.0) * psf->sf.channels ;
1733 			if (opus_multistream_encoder_ctl (oopus->u.encode.state, OPUS_SET_BITRATE (oopus->u.encode.bitrate)) == OPUS_OK)
1734 			{	psf_log_printf (psf, "User changed encoding target bitrate to %dbps\n", oopus->u.encode.bitrate) ;
1735 				return SF_TRUE ;
1736 				}
1737 			psf_log_printf (psf, "Failed to set user encoding target bitrate of %dbps\n", oopus->u.encode.bitrate) ;
1738 			return SF_FALSE ;
1739 			break ;
1740 
1741 		case SFC_SET_ORIGINAL_SAMPLERATE :
1742 			if (data == NULL || datasize != SIGNED_SIZEOF (int))
1743 				return SFE_BAD_COMMAND_PARAM ;
1744 			/*
1745 			** Only allow changing the input samplerate if at the beginning
1746 			** of the stream, because while it might be possible to change
1747 			** samplerate mid-decode, or to re-write the header for encode,
1748 			** ain't nobody got time to implement and test that.
1749 			*/
1750 			if (psf->file.mode == SFM_WRITE)
1751 			{	if (psf->have_written)
1752 					return SF_FALSE ;
1753 				oopus->header.input_samplerate = *((int *) data) ;
1754 				}
1755 			else {
1756 				if (oopus->pkt_pos > oopus->u.decode.gp_start || oopus->loc > 0)
1757 					return SF_FALSE ;
1758 				if ((error = ogg_opus_setup_decoder (psf, *((int *) data))))
1759 					return error ;
1760 				odata->pkt_indx = 0 ;
1761 				/* Adjust file frames count. */
1762 				if (oopus->u.decode.gp_end != (uint64_t) -1)
1763 					psf->sf.frames = (oopus->u.decode.gp_end - oopus->u.decode.gp_start
1764 						- oopus->header.preskip) / oopus->sr_factor ;
1765 				} ;
1766 			return SF_TRUE ;
1767 
1768 		case SFC_GET_ORIGINAL_SAMPLERATE :
1769 			if (data == NULL || datasize != SIGNED_SIZEOF (int))
1770 				return SFE_BAD_COMMAND_PARAM ;
1771 			*((int *) data) = oopus->header.input_samplerate ;
1772 			return SF_TRUE ;
1773 
1774 		case SFC_GET_OGG_STREAM_SERIALNO :
1775 			if (data == NULL || datasize != sizeof (int32_t))
1776 				return SF_FALSE ;
1777 
1778 			*((int32_t *) data) = odata->ostream.serialno ;
1779 			return SF_TRUE ;
1780 
1781 		default :
1782 			break ;
1783 	}
1784 
1785 	return SF_FALSE ;
1786 } /* ogg_opus_command */
1787 
1788 static int
ogg_opus_byterate(SF_PRIVATE * psf)1789 ogg_opus_byterate (SF_PRIVATE *psf)
1790 {	OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
1791 	OPUS_PRIVATE *oopus = (OPUS_PRIVATE *) psf->codec_data ;
1792 
1793 	if (psf->file.mode == SFM_READ)
1794 	{	if (odata->pkt_indx == odata->pkt_len)
1795 		{	if (ogg_opus_unpack_next_page (psf, odata, oopus) < 0)
1796 				return -1 ;
1797 			} ;
1798 
1799 		if (odata->pkt_indx < odata->pkt_len)
1800 		{	ogg_packet *ppkt = &odata->pkt [odata->pkt_indx] ;
1801 			return (ppkt->bytes * 8000) / opus_packet_get_nb_samples (ppkt->packet, ppkt->bytes, 8000) ;
1802 			} ;
1803 
1804 		if (psf->datalength != SF_COUNT_MAX)
1805 			return (psf->datalength * psf->sf.samplerate) / psf->sf.frames ;
1806 		} ;
1807 
1808 	if (psf->file.mode == SFM_WRITE && oopus->u.encode.state != NULL)
1809 		return (oopus->u.encode.bitrate + 7) / 8 ;
1810 
1811 	return -1 ;
1812 } /* ogg_opus_byterate */
1813 
1814 #else /* HAVE_EXTERNAL_XIPH_LIBS */
1815 
1816 int
ogg_opus_open(SF_PRIVATE * psf)1817 ogg_opus_open (SF_PRIVATE *psf)
1818 {
1819 	psf_log_printf (psf, "This version of libsndfile was compiled without Ogg/Opus support.\n") ;
1820 	return SFE_UNIMPLEMENTED ;
1821 } /* ogg_opus_open */
1822 
1823 #endif
1824