2 ** Copyright (C) 2018-2021 Arthur Taylor <art@ified.ca>
3 ** Copyright (C) 2002-2016 Erik de Castro Lopo <erikd@mega-nerd.com>
4 ** Copyright (C) 2002-2005 Michael Smith <msmith@xiph.org>
5 ** Copyright (C) 2007 John ffitch
7 ** This program is free software ; you can redistribute it and/or modify
8 ** it under the terms of the GNU Lesser General Public License as published by
9 ** the Free Software Foundation ; either version 2.1 of the License, or
10 ** (at your option) any later version.
12 ** This program is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY ; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ** GNU Lesser General Public License for more details.
17 ** You should have received a copy of the GNU Lesser General Public License
18 ** along with this program ; if not, write to the Free Software
19 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 ** Much of this code is based on the examples in libvorbis from the
24 ** XIPHOPHORUS Company http://www.xiph.org/ which has a BSD-style Licence
25 ** Copyright (c) 2002, Xiph.org Foundation
27 ** Redistribution and use in source and binary forms, with or without
28 ** modification, are permitted provided that the following conditions
31 ** - Redistributions of source code must retain the above copyright
32 ** notice, this list of conditions and the following disclaimer.
34 ** - Redistributions in binary form must reproduce the above copyright
35 ** notice, this list of conditions and the following disclaimer in the
36 ** documentation and/or other materials provided with the distribution.
38 ** - Neither the name of the Xiph.org Foundation nor the names of its
39 ** contributors may be used to endorse or promote products derived from
40 ** this software without specific prior written permission.
42 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43 ** ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
45 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
46 ** OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
48 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE,
49 ** DATA, OR PROFITS ; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
50 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
52 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
67 #include "sf_unistd.h"
74 #if HAVE_EXTERNAL_XIPH_LIBS
78 #include <vorbis/codec.h>
81 #include <dlfcn.h> /* for dlopen */
83 #include <vorbis/vorbisenc.h>
88 /* How many seconds in the future to not bother bisection searching for. */
89 #define VORBIS_SEEK_THRESHOLD 2
91 typedef int convert_func (SF_PRIVATE *psf, int, void *, int, int, float **) ;
93 static int vorbis_read_header (SF_PRIVATE *psf) ;
94 static int vorbis_write_header (SF_PRIVATE *psf, int calc_length) ;
95 static int vorbis_close (SF_PRIVATE *psf) ;
96 static int vorbis_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
97 static int vorbis_byterate (SF_PRIVATE *psf) ;
98 static int vorbis_calculate_granulepos (SF_PRIVATE *psf, uint64_t *gp_out) ;
99 static int vorbis_skip (SF_PRIVATE *psf, uint64_t target_gp) ;
100 static int vorbis_seek_trysearch (SF_PRIVATE *psf, uint64_t target_gp) ;
101 static sf_count_t vorbis_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
102 static sf_count_t vorbis_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
103 static sf_count_t vorbis_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
104 static sf_count_t vorbis_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
105 static sf_count_t vorbis_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
106 static sf_count_t vorbis_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
107 static sf_count_t vorbis_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
108 static sf_count_t vorbis_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
109 static sf_count_t vorbis_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
110 static sf_count_t vorbis_read_sample (SF_PRIVATE *psf, void *ptr, sf_count_t lens, convert_func *transfn) ;
111 static int vorbis_rnull (SF_PRIVATE *psf, int samples, void *vptr, int off , int channels, float **pcm) ;
119 /* See https://xiph.org/vorbis/doc/v-comment.html */
120 static STR_PAIRS vorbis_metatypes [] =
121 { { SF_STR_TITLE, "Title" },
122 { SF_STR_COPYRIGHT, "Copyright" },
123 { SF_STR_SOFTWARE, "Software" },
124 { SF_STR_ARTIST, "Artist" },
125 { SF_STR_COMMENT, "Comment" },
126 { SF_STR_DATE, "Date" },
127 { SF_STR_ALBUM, "Album" },
128 { SF_STR_LICENSE, "License" },
129 { SF_STR_TRACKNUMBER, "Tracknumber" },
130 { SF_STR_GENRE, "Genre" },
134 { /* Current granule position. */
136 /* Struct that stores all the static vorbis bitstream settings */
138 /* Struct that stores all the bitstream user comments */
139 vorbis_comment vcomment ;
140 /* Central working state for the packet->PCM decoder */
141 vorbis_dsp_state vdsp ;
142 /* Local working space for packet->PCM decode */
143 vorbis_block vblock ;
144 /* Encoding quality in range [0.0, 1.0]. */
146 /* Offset of the first samples' granule position. */
148 /* Last valid samples' granule position. */
150 /* File offset of the start of the last page. */
151 sf_count_t last_page ;
153 /* func ptr for encoder */
159 vorbis_read_header (SF_PRIVATE *psf)
160 { OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
161 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
162 int printed_metadata_msg = 0 ;
164 sf_count_t last_page ;
165 sf_count_t saved_offset ;
168 ** The first page of the Ogg stream we are told to try and open as Vorbis
169 ** has already been loaded into odata->ostream by ogg_open().
171 ** Extract the initial header from the first page and verify that the
172 ** Ogg bitstream is in fact Vorbis data.
175 vorbis_info_init (&vdata->vinfo) ;
176 vorbis_comment_init (&vdata->vcomment) ;
178 if (!odata->opacket.b_o_s)
179 { psf_log_printf (psf, "Vorbis: First packet does not have a beginning-of-stream bit.\n") ;
180 return SFE_MALFORMED_FILE ;
183 if (ogg_stream_packetpeek (&odata->ostream, NULL))
184 { psf_log_printf (psf, "Vorbis: First page contains extraneous packets!\n") ;
185 return SFE_MALFORMED_FILE ;
188 if (vorbis_synthesis_headerin (&vdata->vinfo, &vdata->vcomment, &odata->opacket) < 0)
189 { /* Error case ; not a vorbis header. */
190 psf_log_printf (psf, "Found Vorbis in stream header, but vorbis_synthesis_headerin failed.\n") ;
191 return SFE_MALFORMED_FILE ;
195 ** At this point, we're sure we're Vorbis. We've set up the logical (Ogg)
196 ** bitstream decoder. Get the comment and codebook headers and set up the
199 ** The next two packets in order are the comment and codebook headers.
200 ** They're likely large and may span multiple pages. Thus we read
201 ** and submit data until we get our two packets, watching that no
202 ** pages are missing. If a page is missing, error out ; losing a
203 ** header page is the only place where missing data is fatal.
206 i = 0 ; /* Count of number of packets read */
208 { nn = ogg_stream_packetout (&odata->ostream, &odata->opacket) ;
211 { nn = ogg_stream_next_page (psf, odata) ;
213 { psf_log_printf (psf, "End of file before finding all Vorbis headers!\n") ;
214 return SFE_MALFORMED_FILE ;
217 { psf_log_printf (psf, "Error reading file while finding Vorbis headers!\n") ;
224 { /* A hole while reading headers. This could be bad. */
225 psf_log_printf (psf, "Corrupt secondary header. Exiting.\n") ;
226 return SFE_MALFORMED_FILE ;
229 vorbis_synthesis_headerin (&vdata->vinfo, &vdata->vcomment, &odata->opacket) ;
233 /* Check for extraneous packets in the last headers page. */
234 while (ogg_stream_packetout (&odata->ostream, &odata->opacket) == 1)
238 psf_log_printf (psf, "Vorbis: stream has extraneous header packets.\n") ;
240 psf_log_printf (psf, "Bitstream is %d channel, %D Hz\n", vdata->vinfo.channels, vdata->vinfo.rate) ;
241 psf_log_printf (psf, "Encoded by : %s\n", vdata->vcomment.vendor) ;
243 /* Save the offset of the first payload page */
244 psf->dataoffset = ogg_sync_ftell (psf) ;
247 ** Calculate the granule position offset. The first page with a payload
248 ** packet shouldn't end in a continued packet. The difference between the
249 ** page's granule position and the sum of frames on the page tells us the
250 ** granule position offset.
251 ** See https://xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-132000A.2
253 ogg_stream_unpack_page (psf, odata) ;
254 vorbis_calculate_granulepos (psf, &vdata->pcm_start) ;
255 vdata->gp = vdata->pcm_start ;
258 ** Find the end of the stream, save it. Only works if the file is seekable.
260 vdata->pcm_end = (uint64_t) -1 ;
261 psf->datalength = psf->filelength ;
263 { saved_offset = ogg_sync_ftell (psf) ;
264 last_page = ogg_sync_last_page_before (psf, odata, &vdata->pcm_end, psf->filelength, odata->ostream.serialno) ;
266 { if (!ogg_page_eos (&odata->opage))
267 psf_log_printf (psf, "Ogg: Last page lacks an end-of-stream bit.\n") ;
268 psf->datalength = last_page + odata->opage.header_len + odata->opage.body_len - psf->dataoffset ;
269 if (psf->datalength + psf->dataoffset < psf->filelength)
270 psf_log_printf (psf, "Ogg: Junk after the last page.\n") ;
271 vdata->last_page = last_page ;
274 ogg_sync_fseek (psf, saved_offset, SEEK_SET) ;
277 psf_log_printf (psf, "PCM offset : %D\n", vdata->pcm_start) ;
278 if (vdata->pcm_end != (uint64_t) -1)
279 psf_log_printf (psf, "PCM end : %D\n", vdata->pcm_end) ;
281 psf_log_printf (psf, "PCM end : unknown\n") ;
283 /* Throw the comments plus a few lines about the bitstream we're decoding. */
284 for (i = 0 ; i < ARRAY_LEN (vorbis_metatypes) ; i++)
287 dd = vorbis_comment_query (&vdata->vcomment, vorbis_metatypes [i].name, 0) ;
291 if (printed_metadata_msg == 0)
292 { psf_log_printf (psf, "Metadata :\n") ;
293 printed_metadata_msg = 1 ;
296 psf_store_string (psf, vorbis_metatypes [i].id, dd) ;
297 psf_log_printf (psf, " %-10s : %s\n", vorbis_metatypes [i].name, dd) ;
299 psf_log_printf (psf, "End\n") ;
301 psf->sf.samplerate = vdata->vinfo.rate ;
302 psf->sf.channels = vdata->vinfo.channels ;
303 psf->sf.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS ;
304 psf->sf.frames = (vdata->pcm_end != (uint64_t) -1) ? vdata->pcm_end - vdata->pcm_start : SF_COUNT_MAX ;
306 /* OK, got and parsed all three headers. Initialize the Vorbis
307 ** packet->PCM decoder.
308 ** Central decode state. */
309 vorbis_synthesis_init (&vdata->vdsp, &vdata->vinfo) ;
311 /* Local state for most of the decode so multiple block decodes can
312 ** proceed in parallel. We could init multiple vorbis_block structures
314 vorbis_block_init (&vdata->vdsp, &vdata->vblock) ;
317 } /* vorbis_read_header */
321 #define VORBIS_ENC_SO_NAME "/usr/lib/libvorbisenc.so.2" /* FIXME : Any good way to avoid hardcoding? */
322 #define VORBIS_ENC_INIT_VBR "vorbis_encode_init_vbr"
325 _vorbis_encode_init(SF_PRIVATE *psf)
327 int (*fn) (vorbis_info *, long, long, float);
329 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
332 dl = dlopen(VORBIS_ENC_SO_NAME, RTLD_GLOBAL | RTLD_NOW);
334 psf_log_printf (psf, "failed to dlopen [%s], error [%s]\n", VORBIS_ENC_SO_NAME, dlerror());
342 fn = dlsym(dl, VORBIS_ENC_INIT_VBR);
344 psf_log_printf (psf, "failed to dlsym [%s], error [%s]\n", VORBIS_ENC_INIT_VBR, dlerror());
350 return fn(&vdata->vinfo, psf->sf.channels, psf->sf.samplerate, vdata->quality);
352 #endif /* __TIZEN__ */
355 vorbis_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
357 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
358 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
361 vorbis_info_init (&vdata->vinfo) ;
363 /* The style of encoding should be selectable here, VBR quality mode. */
365 ret = _vorbis_encode_init(psf);
367 ret = vorbis_encode_init_vbr (&vdata->vinfo, psf->sf.channels, psf->sf.samplerate, vdata->quality) ;
371 ret = vorbis_encode_init (&vdata->vinfo, psf->sf.channels, psf->sf.samplerate, -1, 128000, -1) ; /* average bitrate mode */
372 ret = ( vorbis_encode_setup_managed (&vdata->vinfo, psf->sf.channels, psf->sf.samplerate, -1, 128000, -1)
373 || vorbis_encode_ctl (&vdata->vinfo, OV_ECTL_RATEMANAGE_AVG, NULL)
374 || vorbis_encode_setup_init (&vdata->vinfo)
378 return SFE_BAD_OPEN_FORMAT ;
383 vorbis_comment_init (&vdata->vcomment) ;
385 vorbis_comment_add_tag (&vdata->vcomment, "ENCODER", "libsndfile") ;
386 for (k = 0 ; k < SF_MAX_STRINGS ; k++)
387 { const char * name ;
389 if (psf->strings.data [k].type == 0)
392 switch (psf->strings.data [k].type)
393 { case SF_STR_TITLE : name = "TITLE" ; break ;
394 case SF_STR_COPYRIGHT : name = "COPYRIGHT" ; break ;
395 case SF_STR_SOFTWARE : name = "SOFTWARE" ; break ;
396 case SF_STR_ARTIST : name = "ARTIST" ; break ;
397 case SF_STR_COMMENT : name = "COMMENT" ; break ;
398 case SF_STR_DATE : name = "DATE" ; break ;
399 case SF_STR_ALBUM : name = "ALBUM" ; break ;
400 case SF_STR_LICENSE : name = "LICENSE" ; break ;
401 case SF_STR_TRACKNUMBER : name = "Tracknumber" ; break ;
402 case SF_STR_GENRE : name = "Genre" ; break ;
407 vorbis_comment_add_tag (&vdata->vcomment, name, psf->strings.storage + psf->strings.data [k].offset) ;
410 /* set up the analysis state and auxiliary encoding storage */
411 vorbis_analysis_init (&vdata->vdsp, &vdata->vinfo) ;
412 vorbis_block_init (&vdata->vdsp, &vdata->vblock) ;
415 ** Set up our packet->stream encoder.
416 ** Pick a random serial number ; that way we can more likely build
417 ** chained streams just by concatenation.
420 ogg_stream_init (&odata->ostream, psf_rand_int32 ()) ;
422 /* Vorbis streams begin with three headers ; the initial header (with
423 most of the codec setup parameters) which is mandated by the Ogg
424 bitstream spec. The second header holds any comment fields. The
425 third header holds the bitstream codebook. We merely need to
426 make the headers, then pass them to libvorbis one at a time ;
427 libvorbis handles the additional Ogg bitstream constraints */
429 { ogg_packet header ;
430 ogg_packet header_comm ;
431 ogg_packet header_code ;
434 vorbis_analysis_headerout (&vdata->vdsp, &vdata->vcomment, &header, &header_comm, &header_code) ;
435 ogg_stream_packetin (&odata->ostream, &header) ; /* automatically placed in its own page */
436 ogg_stream_packetin (&odata->ostream, &header_comm) ;
437 ogg_stream_packetin (&odata->ostream, &header_code) ;
439 /* This ensures the actual
440 * audio data will start on a new page, as per spec
442 while ((result = ogg_stream_flush (&odata->ostream, &odata->opage)) != 0)
443 { ogg_write_page (psf, &odata->opage) ;
448 } /* vorbis_write_header */
451 vorbis_close (SF_PRIVATE *psf)
452 { OGG_PRIVATE* odata = psf->container_data ;
453 VORBIS_PRIVATE *vdata = psf->codec_data ;
455 if (odata == NULL || vdata == NULL)
458 /* Clean up this logical bitstream ; before exit we shuld see if we're
459 ** followed by another [chained]. */
461 if (psf->file.mode == SFM_WRITE)
463 if (psf->write_current <= 0)
464 vorbis_write_header (psf, 0) ;
466 vorbis_analysis_wrote (&vdata->vdsp, 0) ;
467 while (vorbis_analysis_blockout (&vdata->vdsp, &vdata->vblock) == 1)
470 /* analysis, assume we want to use bitrate management */
471 vorbis_analysis (&vdata->vblock, NULL) ;
472 vorbis_bitrate_addblock (&vdata->vblock) ;
474 while (vorbis_bitrate_flushpacket (&vdata->vdsp, &odata->opacket))
475 { /* weld the packet into the bitstream */
476 ogg_stream_packetin (&odata->ostream, &odata->opacket) ;
478 /* write out pages (if any) */
480 { int result = ogg_stream_pageout (&odata->ostream, &odata->opage) ;
481 if (result == 0) break ;
482 ogg_write_page (psf, &odata->opage) ;
484 /* this could be set above, but for illustrative purposes, I do
485 it here (to show that vorbis does know where the stream ends) */
487 if (ogg_page_eos (&odata->opage)) odata->eos = 1 ;
493 /* ogg_page and ogg_packet structs always point to storage in
494 libvorbis. They are never freed or manipulated directly */
496 vorbis_block_clear (&vdata->vblock) ;
497 vorbis_dsp_clear (&vdata->vdsp) ;
498 vorbis_comment_clear (&vdata->vcomment) ;
499 vorbis_info_clear (&vdata->vinfo) ;
512 ogg_vorbis_open (SF_PRIVATE *psf)
513 { OGG_PRIVATE* odata = psf->container_data ;
514 VORBIS_PRIVATE* vdata ;
518 { psf_log_printf (psf, "%s : odata is NULL???\n", __func__) ;
519 return SFE_INTERNAL ;
522 vdata = calloc (1, sizeof (VORBIS_PRIVATE)) ;
523 psf->codec_data = vdata ;
525 if (psf->file.mode == SFM_RDWR)
526 return SFE_BAD_MODE_RW ;
528 psf_log_printf (psf, "Vorbis library version : %s\n", vorbis_version_string ()) ;
530 if (psf->file.mode == SFM_READ)
531 { if ((error = vorbis_read_header (psf)))
534 psf->read_short = vorbis_read_s ;
535 psf->read_int = vorbis_read_i ;
536 psf->read_float = vorbis_read_f ;
537 psf->read_double = vorbis_read_d ;
540 psf->codec_close = vorbis_close ;
541 if (psf->file.mode == SFM_WRITE)
543 /* Set the default vorbis quality here. */
544 vdata->quality = 0.4 ;
546 psf->write_header = vorbis_write_header ;
547 psf->write_short = vorbis_write_s ;
548 psf->write_int = vorbis_write_i ;
549 psf->write_float = vorbis_write_f ;
550 psf->write_double = vorbis_write_d ;
553 psf->datalength = 0 ;
554 psf->filelength = 0 ;
555 psf->dataoffset = 0 ;
556 psf->strings.flags = SF_STR_ALLOW_START ;
559 psf->seek = vorbis_seek ;
560 psf->command = vorbis_command ;
561 psf->byterate = vorbis_byterate ;
562 psf->sf.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS ;
563 psf->sf.sections = 1 ;
566 } /* ogg_vorbis_open */
569 vorbis_command (SF_PRIVATE *psf, int command, void * data, int datasize)
570 { OGG_PRIVATE* odata = psf->container_data ;
571 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
574 { case SFC_SET_COMPRESSION_LEVEL :
575 if (data == NULL || datasize != sizeof (double))
578 if (psf->have_written)
581 vdata->quality = 1.0 - *((double *) data) ;
584 vdata->quality = SF_MAX (0.0, SF_MIN (1.0, vdata->quality)) ;
586 psf_log_printf (psf, "%s : Setting SFC_SET_VBR_ENCODING_QUALITY to %f.\n", __func__, vdata->quality) ;
589 case SFC_GET_OGG_STREAM_SERIALNO :
590 if (data == NULL || datasize != sizeof (int32_t))
593 *((int32_t *) data) = odata->ostream.serialno ;
601 } /* vorbis_command */
604 vorbis_rnull (SF_PRIVATE *UNUSED (psf), int samples, void *UNUSED (vptr), int UNUSED (off) , int channels, float **UNUSED (pcm))
606 return samples * channels ;
610 vorbis_rshort (SF_PRIVATE *psf, int samples, void *vptr, int off, int channels, float **pcm)
612 short *ptr = (short*) vptr + off ;
614 if (psf->float_int_mult)
616 float inverse = 1.0 / psf->float_max ;
617 for (j = 0 ; j < samples ; j++)
618 for (n = 0 ; n < channels ; n++)
619 ptr [i++] = psf_lrintf ((pcm [n][j] * inverse) * 32767.0f) ;
623 for (j = 0 ; j < samples ; j++)
624 for (n = 0 ; n < channels ; n++)
625 ptr [i++] = psf_lrintf (pcm [n][j] * 32767.0f) ;
628 } /* vorbis_rshort */
631 vorbis_rint (SF_PRIVATE *psf, int samples, void *vptr, int off, int channels, float **pcm)
633 int *ptr = (int*) vptr + off ;
636 if (psf->float_int_mult)
638 float inverse = 1.0 / psf->float_max ;
639 for (j = 0 ; j < samples ; j++)
640 for (n = 0 ; n < channels ; n++)
641 ptr [i++] = psf_lrintf ((pcm [n][j] * inverse) * 2147483647.0f) ;
645 for (j = 0 ; j < samples ; j++)
646 for (n = 0 ; n < channels ; n++)
647 ptr [i++] = psf_lrintf (pcm [n][j] * 2147483647.0f) ;
653 vorbis_rfloat (SF_PRIVATE *UNUSED (psf), int samples, void *vptr, int off, int channels, float **pcm)
655 float *ptr = (float*) vptr + off ;
657 for (j = 0 ; j < samples ; j++)
658 for (n = 0 ; n < channels ; n++)
659 ptr [i++] = pcm [n][j] ;
661 } /* vorbis_rfloat */
664 vorbis_rdouble (SF_PRIVATE *UNUSED (psf), int samples, void *vptr, int off, int channels, float **pcm)
666 double *ptr = (double*) vptr + off ;
668 for (j = 0 ; j < samples ; j++)
669 for (n = 0 ; n < channels ; n++)
670 ptr [i++] = pcm [n][j] ;
672 } /* vorbis_rdouble */
676 vorbis_read_sample (SF_PRIVATE *psf, void *ptr, sf_count_t lens, convert_func *transfn)
677 { VORBIS_PRIVATE *vdata = psf->codec_data ;
678 OGG_PRIVATE *odata = psf->container_data ;
679 int len, samples, i = 0 , nn ;
682 len = lens / psf->sf.channels ;
686 ** pcm is a multichannel float vector. In stereo, for
687 ** example, pcm [0] is left, and pcm [1] is right. samples is
688 ** the size of each channel. Convert the float values
689 ** (-1.<=range<=1.) to whatever PCM format and write it out.
691 while ((samples = vorbis_synthesis_pcmout (&vdata->vdsp, &pcm)) > 0)
692 { if (samples > len) samples = len ;
693 i += transfn (psf, samples, ptr, i, psf->sf.channels, pcm) ;
695 /* tell libvorbis how many samples we actually consumed */
696 vorbis_synthesis_read (&vdata->vdsp, samples) ;
697 vdata->gp += samples ;
702 /* Out of samples, load the next packet. */
703 if (odata->pkt_indx == odata->pkt_len)
704 { /* Page out of packets, load and unpack the next page. */
705 nn = ogg_stream_unpack_page (psf, odata) ;
709 { /* Ran over a hole. gp is now out of date, need to recalculate. */
710 vorbis_synthesis_restart (&vdata->vdsp) ;
711 vorbis_calculate_granulepos (psf, &vdata->gp) ;
715 /* Decode the packet */
716 if (vorbis_synthesis (&vdata->vblock, &(odata->pkt [odata->pkt_indx])) == 0) /* test for success! */
717 vorbis_synthesis_blockin (&vdata->vdsp, &vdata->vblock) ;
722 } /* vorbis_read_sample */
725 vorbis_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t lens)
726 { return vorbis_read_sample (psf, (void*) ptr, lens, vorbis_rshort) ;
727 } /* vorbis_read_s */
730 vorbis_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t lens)
731 { return vorbis_read_sample (psf, (void*) ptr, lens, vorbis_rint) ;
732 } /* vorbis_read_i */
735 vorbis_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t lens)
736 { return vorbis_read_sample (psf, (void*) ptr, lens, vorbis_rfloat) ;
737 } /* vorbis_read_f */
740 vorbis_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t lens)
741 { return vorbis_read_sample (psf, (void*) ptr, lens, vorbis_rdouble) ;
742 } /* vorbis_read_d */
744 /*==============================================================================
748 vorbis_write_samples (SF_PRIVATE *psf, OGG_PRIVATE *odata, VORBIS_PRIVATE *vdata, int in_frames)
750 vorbis_analysis_wrote (&vdata->vdsp, in_frames) ;
753 ** Vorbis does some data preanalysis, then divvies up blocks for
754 ** more involved (potentially parallel) processing. Get a single
755 ** block for encoding now.
757 while (vorbis_analysis_blockout (&vdata->vdsp, &vdata->vblock) == 1)
759 /* analysis, assume we want to use bitrate management */
760 vorbis_analysis (&vdata->vblock, NULL) ;
761 vorbis_bitrate_addblock (&vdata->vblock) ;
763 while (vorbis_bitrate_flushpacket (&vdata->vdsp, &odata->opacket))
765 /* weld the packet into the bitstream */
766 ogg_stream_packetin (&odata->ostream, &odata->opacket) ;
768 /* write out pages (if any) */
770 { int result = ogg_stream_pageout (&odata->ostream, &odata->opage) ;
773 ogg_write_page (psf, &odata->opage) ;
775 /* This could be set above, but for illustrative purposes, I do
776 ** it here (to show that vorbis does know where the stream ends) */
777 if (ogg_page_eos (&odata->opage))
783 vdata->gp += in_frames ;
784 } /* vorbis_write_data */
788 vorbis_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t lens)
791 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
792 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
793 int in_frames = lens / psf->sf.channels ;
794 float **buffer = vorbis_analysis_buffer (&vdata->vdsp, in_frames) ;
795 for (i = 0 ; i < in_frames ; i++)
796 for (m = 0 ; m < psf->sf.channels ; m++)
797 buffer [m][i] = (float) (ptr [j++]) / 32767.0f ;
799 vorbis_write_samples (psf, odata, vdata, in_frames) ;
802 } /* vorbis_write_s */
805 vorbis_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t lens)
807 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
808 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
809 int in_frames = lens / psf->sf.channels ;
810 float **buffer = vorbis_analysis_buffer (&vdata->vdsp, in_frames) ;
811 for (i = 0 ; i < in_frames ; i++)
812 for (m = 0 ; m < psf->sf.channels ; m++)
813 buffer [m][i] = (float) (ptr [j++]) / 2147483647.0f ;
815 vorbis_write_samples (psf, odata, vdata, in_frames) ;
818 } /* vorbis_write_i */
821 vorbis_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t lens)
823 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
824 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
825 int in_frames = lens / psf->sf.channels ;
826 float **buffer = vorbis_analysis_buffer (&vdata->vdsp, in_frames) ;
827 for (i = 0 ; i < in_frames ; i++)
828 for (m = 0 ; m < psf->sf.channels ; m++)
829 buffer [m][i] = ptr [j++] ;
831 vorbis_write_samples (psf, odata, vdata, in_frames) ;
834 } /* vorbis_write_f */
837 vorbis_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t lens)
839 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
840 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
841 int in_frames = lens / psf->sf.channels ;
842 float **buffer = vorbis_analysis_buffer (&vdata->vdsp, in_frames) ;
843 for (i = 0 ; i < in_frames ; i++)
844 for (m = 0 ; m < psf->sf.channels ; m++)
845 buffer [m][i] = (float) ptr [j++] ;
847 vorbis_write_samples (psf, odata, vdata, in_frames) ;
850 } /* vorbis_write_d */
853 vorbis_skip (SF_PRIVATE *psf, uint64_t target)
854 { OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
855 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
857 int thisblock, lastblock, nn ;
858 const int blocksize = vorbis_info_blocksize (&vdata->vinfo, 1) ;
860 /* Read out any samples that may be in the decoder from a seek without a
862 thisblock = vorbis_synthesis_pcmout (&vdata->vdsp, NULL) ;
864 { if ((uint64_t) thisblock + vdata->gp >= target)
865 thisblock = SF_MIN (thisblock, (int) (target - vdata->gp)) ;
867 vorbis_synthesis_read (&vdata->vdsp, thisblock) ;
868 vdata->gp += thisblock ;
869 if (vdata->gp == target)
873 /* Read through packets that are before our target */
875 for ( ; vdata->gp < target ; )
876 { /* Ensure there are unpacked packets. */
877 if (odata->pkt_indx == odata->pkt_len)
878 { /* Page out of packets, load and unpack the next page. */
879 nn = ogg_stream_unpack_page (psf, odata) ;
885 { /* Ran over a hole. gp is now out of date, need to recalculate. */
886 vorbis_synthesis_restart (&vdata->vdsp) ;
887 vorbis_calculate_granulepos (psf, &vdata->gp) ;
888 if (target < vdata->gp)
889 { /* Our target is inside the hole :-( */
895 pkt = &odata->pkt [odata->pkt_indx] ;
896 thisblock = vorbis_packet_blocksize (&vdata->vinfo, pkt) ;
898 { /* Not an audio packet */
904 { vdata->gp += ((lastblock + thisblock) / 4) ;
907 /* Check to see if the block contains our target */
908 if (vdata->gp + ((thisblock + blocksize) / 4) >= target)
911 /* Block is before the target. Track for state, but don't decode. */
913 vorbis_synthesis_trackonly (&vdata->vblock, pkt) ;
914 vorbis_synthesis_blockin (&vdata->vdsp, &vdata->vblock) ;
915 lastblock = thisblock ;
918 /* We are at the correct block, but still need to consume samples to reach
920 vorbis_read_sample (psf, (void *) NULL, (target - vdata->gp) * psf->sf.channels, vorbis_rnull) ;
926 vorbis_seek_trysearch (SF_PRIVATE *psf, uint64_t target_gp)
927 { OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
928 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
929 uint64_t best_gp, search_target_gp ;
932 /* Can't bisect a file we don't know the end of (cannot seek). */
933 if (vdata->pcm_end == (uint64_t) -1)
936 /* If the target is for the near future, don't bother bisecting, just skip
938 if (target_gp >= vdata->gp &&
939 target_gp - vdata->gp < ((unsigned) (VORBIS_SEEK_THRESHOLD) * psf->sf.samplerate))
942 /* Search for a position a half large-block before our target. As Vorbis is
943 ** lapped, every sample position come from two blocks, the "left" half of
944 ** one block and the "right" half of the previous block. The granule
945 ** position of an Ogg page of a Vorbis stream is the sample offset of the
946 ** last finished sample in the stream that can be decoded from a page. A
947 ** page also contains another half-block of samples waiting to be lapped
948 ** with the first half-block of samples from the next page.
950 ** Searching for a sample one half of a large block before our target
951 ** guarantees we always load a page containing the previous half block
952 ** required to decode the target. Downside is we can't use best_gp
953 ** parameter of the page seek function. */
954 search_target_gp = vorbis_info_blocksize (&vdata->vinfo, 1) / 2 ;
955 search_target_gp = search_target_gp < target_gp ? target_gp - search_target_gp : 0 ;
957 ret = ogg_stream_seek_page_search (psf, odata, search_target_gp, vdata->pcm_start,
958 vdata->pcm_end, &best_gp, psf->dataoffset, vdata->last_page, vdata->vinfo.rate) ;
962 ret = ogg_stream_unpack_page (psf, odata) ;
964 { /* Reset the decoder, recalculate position */
965 vorbis_synthesis_restart (&vdata->vdsp) ;
966 ret = vorbis_calculate_granulepos (psf, &vdata->gp) ;
970 } /* vorbis_seek_trysearch */
973 vorbis_seek (SF_PRIVATE *psf, int UNUSED (mode), sf_count_t offset)
974 { OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
975 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
979 if (odata == NULL || vdata == NULL)
983 { psf->error = SFE_BAD_SEEK ;
984 return ((sf_count_t) -1) ;
987 if (psf->file.mode == SFM_READ)
988 { target_gp = (uint64_t) offset + vdata->pcm_start ;
990 ret = vorbis_seek_trysearch (psf, target_gp) ;
992 if (ret < 0 || vdata->gp > target_gp)
993 { /* Search failed (bad data?), reset to the beginning of the stream. */
994 psf_log_printf (psf, "Vorbis: Seek search failed. Reading through stream from start.\n") ;
995 ogg_stream_reset_serialno (&odata->ostream, odata->ostream.serialno) ;
997 odata->pkt_indx = 0 ;
998 ogg_sync_fseek (psf, psf->dataoffset, SEEK_SET) ;
999 vdata->gp = vdata->pcm_start ;
1000 vorbis_synthesis_restart (&vdata->vdsp) ;
1003 vorbis_skip (psf, target_gp) ;
1005 return vdata->gp - vdata->pcm_start ;
1008 psf->error = SFE_BAD_SEEK ;
1009 return ((sf_count_t) -1) ;
1013 vorbis_byterate (SF_PRIVATE *psf)
1015 if (psf->file.mode == SFM_READ)
1016 return (psf->datalength * psf->sf.samplerate) / psf->sf.frames ;
1019 } /* vorbis_byterate */
1022 vorbis_calculate_granulepos (SF_PRIVATE *psf, uint64_t *gp_out)
1023 { OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
1024 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
1027 int thisblock, lastblock, i ;
1030 /* Calculate the granule position when dropped into the middle of a stream
1031 ** with an un-primed decoder.
1033 ** Normally the last unpacked packet contains the granule position of the
1034 ** last completed sample from decoding all the blocks in the page's
1035 ** packets. By calculating how many samples we can decode from the blocks
1036 ** in the page's packets and subtracting it from the final packet's granule
1037 ** position we get the position of the first sample to be output from the
1038 ** decoder after it primes. That is, the current granule position.
1040 ** However, there is an ambiguity if this is the last page of a stream. The
1041 ** last page of a stream may have a granule position of fewer samples than
1042 ** the page actually contains. The excess samples are padding leftovers
1043 ** for and exact sample length file. */
1045 if (odata->pkt_len > 0)
1046 { /* Calculate how many samples can be decoded from blocks in this page,
1047 ** accounting for the fact that blocks are 1/2 lapped. */
1051 for (i = 0 ; i < odata->pkt_len ; i++)
1052 { thisblock = vorbis_packet_blocksize (&vdata->vinfo, &pkt [i]) ;
1054 { if (lastblock != -1)
1055 duration += (lastblock + thisblock) >> 2 ;
1056 lastblock = thisblock ;
1060 pkt = &odata->pkt [odata->pkt_len - 1] ;
1061 last_gp = pkt->granulepos ;
1062 if (last_gp == (uint64_t) -1)
1063 { psf_log_printf (psf, "Vorbis: Ogg page has no granule position, cannot calculate sample position!\n") ;
1064 psf->error = SFE_MALFORMED_FILE ;
1069 { if (last_gp <= duration)
1070 { /* Corner case: One page stream. Ogg/Vorbis spec dictates the
1071 ** granule position offset MUST be zero, hence this first (and
1072 ** only) page must start at 0. */
1077 /* Otherwise, we cannot know where we are without looking at the
1078 ** blocks of the previous page. (The granule position of the
1079 ** previous page is not enough, we need the block sizes.)
1081 ** We avoid this case by never allowing a bisection search to seek
1082 ** beyond the second-to-last page, so the last page is always
1083 ** approached with a known location and never dropped into.
1085 ** The only way we should be able to end up here is if there was a
1086 ** hole in stream just before the last page, in which case all bets
1087 ** are off anyways. */
1088 psf_log_printf (psf, "Vorbis: Cannot calculate ambiguous last page duration. Sample count may be wrong.\n") ;
1091 if (last_gp < duration)
1092 { psf_log_printf (psf, "Vorbis: Granule position is nonsensical! (Missing end-of-stream marker?)\n") ;
1093 psf->error = SFE_MALFORMED_FILE ;
1097 *gp_out = last_gp - duration ;
1102 } /* vorbis_calculate_granulepos */
1104 #else /* HAVE_EXTERNAL_XIPH_LIBS */
1107 ogg_vorbis_open (SF_PRIVATE *psf)
1109 psf_log_printf (psf, "This version of libsndfile was compiled without Ogg/Vorbis support.\n") ;
1110 return SFE_UNIMPLEMENTED ;
1111 } /* ogg_vorbis_open */