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