xref: /third_party/libsnd/src/ogg_opus.c (revision b815c7f3)
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
195typedef 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
224typedef 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
281static int			ogg_opus_close (SF_PRIVATE *psf) ;
282static void			opus_print_header (SF_PRIVATE *psf, OpusHeader *h) ;
283static int			opus_read_header_packet (SF_PRIVATE *psf, OpusHeader *h, ogg_packet *opacket) ;
284static int			ogg_opus_read_header (SF_PRIVATE * psf) ;
285static int			ogg_opus_setup_decoder (SF_PRIVATE *psf, int input_samplerate) ;
286
287static int			ogg_opus_setup_encoder (SF_PRIVATE *psf, OGG_PRIVATE *odata, OPUS_PRIVATE *oopus) ;
288static int			ogg_opus_write_header (SF_PRIVATE * psf, int calc_length) ;
289static void			ogg_opus_flush (SF_PRIVATE *psf) ;
290static int			ogg_opus_unpack_next_page (SF_PRIVATE *psf, OGG_PRIVATE *odata, OPUS_PRIVATE *oopus) ;
291static int			ogg_opus_calculate_page_duration (OGG_PRIVATE *odata) ;
292static int			ogg_opus_read_refill (SF_PRIVATE *psf, OGG_PRIVATE *odata, OPUS_PRIVATE *oopus) ;
293static int			ogg_opus_write_out (SF_PRIVATE *psf, OGG_PRIVATE *odata, OPUS_PRIVATE *oopus) ;
294
295static sf_count_t	ogg_opus_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
296static sf_count_t	ogg_opus_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
297static sf_count_t	ogg_opus_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
298static sf_count_t	ogg_opus_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
299
300static sf_count_t	ogg_opus_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
301static sf_count_t	ogg_opus_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
302static sf_count_t	ogg_opus_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
303static sf_count_t	ogg_opus_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
304
305static sf_count_t	ogg_opus_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
306static sf_count_t	ogg_opus_null_read (SF_PRIVATE *psf, sf_count_t offset) ;
307static sf_count_t	ogg_opus_page_seek_manual (SF_PRIVATE *psf, uint64_t target_gp) ;
308static int			ogg_opus_page_seek_search (SF_PRIVATE *psf, uint64_t target_gp) ;
309
310static int			ogg_opus_analyze_file (SF_PRIVATE *psf) ;
311static int			ogg_opus_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
312static int			ogg_opus_byterate (SF_PRIVATE *psf) ;
313
314/*-----------------------------------------------------------------------------------------------
315*/
316
317static vorbiscomment_ident opustags_ident =	{ "OpusTags", 8 } ;
318
319/*-----------------------------------------------------------------------------------------------
320** Exported functions.
321*/
322
323int
324ogg_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
385static int
386ogg_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
421static void
422opus_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
448static int
449opus_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
525static int
526ogg_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
561static int
562ogg_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
649static int
650ogg_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
761static int
762ogg_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
866static void
867ogg_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
937static int
938ogg_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
952static int
953ogg_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
987static int
988ogg_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
1097static int
1098ogg_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
1149static sf_count_t
1150ogg_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
1186static sf_count_t
1187ogg_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
1223static sf_count_t
1224ogg_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
1246static sf_count_t
1247ogg_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
1275static sf_count_t
1276ogg_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
1307static sf_count_t
1308ogg_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
1339static sf_count_t
1340ogg_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
1366static sf_count_t
1367ogg_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
1398static int
1399ogg_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*/
1496static sf_count_t
1497ogg_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*/
1528static int
1529ogg_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*/
1572static sf_count_t
1573ogg_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
1597static sf_count_t
1598ogg_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
1690static int
1691ogg_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
1788static int
1789ogg_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
1816int
1817ogg_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