2 ** Copyright (C) 2002-2014 Erik de Castro Lopo <erikd@mega-nerd.com>
3 ** Copyright (C) 2002-2005 Michael Smith <msmith@xiph.org>
4 ** Copyright (C) 2007 John ffitch
6 ** This program is free software ; you can redistribute it and/or modify
7 ** it under the terms of the GNU Lesser General Public License as published by
8 ** the Free Software Foundation ; either version 2.1 of the License, or
9 ** (at your option) any later version.
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY ; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU Lesser General Public License for more details.
16 ** You should have received a copy of the GNU Lesser General Public License
17 ** along with this program ; if not, write to the Free Software
18 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 ** Much of this code is based on the examples in libvorbis from the
23 ** XIPHOPHORUS Company http://www.xiph.org/ which has a BSD-style Licence
24 ** Copyright (c) 2002, Xiph.org Foundation
26 ** Redistribution and use in source and binary forms, with or without
27 ** modification, are permitted provided that the following conditions
30 ** - Redistributions of source code must retain the above copyright
31 ** notice, this list of conditions and the following disclaimer.
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.
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.
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.
71 #if HAVE_EXTERNAL_LIBS
74 #include <vorbis/codec.h>
75 #include <vorbis/vorbisenc.h>
79 typedef int convert_func (SF_PRIVATE *psf, int, void *, int, int, float **) ;
81 static int vorbis_read_header (SF_PRIVATE *psf, int log_data) ;
82 static int vorbis_write_header (SF_PRIVATE *psf, int calc_length) ;
83 static int vorbis_close (SF_PRIVATE *psf) ;
84 static int vorbis_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
85 static int vorbis_byterate (SF_PRIVATE *psf) ;
86 static sf_count_t vorbis_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
87 static sf_count_t vorbis_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
88 static sf_count_t vorbis_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
89 static sf_count_t vorbis_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
90 static sf_count_t vorbis_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
91 static sf_count_t vorbis_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
92 static sf_count_t vorbis_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
93 static sf_count_t vorbis_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
94 static sf_count_t vorbis_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
95 static sf_count_t vorbis_read_sample (SF_PRIVATE *psf, void *ptr, sf_count_t lens, convert_func *transfn) ;
96 static sf_count_t vorbis_length (SF_PRIVATE *psf) ;
103 static STR_PAIRS vorbis_metatypes [] =
104 { { SF_STR_TITLE, "Title" },
105 { SF_STR_COPYRIGHT, "Copyright" },
106 { SF_STR_SOFTWARE, "Software" },
107 { SF_STR_ARTIST, "Artist" },
108 { SF_STR_COMMENT, "Comment" },
109 { SF_STR_DATE, "Date" },
110 { SF_STR_ALBUM, "Album" },
111 { SF_STR_LICENSE, "License" },
112 { SF_STR_TRACKNUMBER, "Tracknumber" },
113 { SF_STR_GENRE, "Genre" },
117 { /* Count current location */
119 /* Struct that stores all the static vorbis bitstream settings */
121 /* Struct that stores all the bitstream user comments */
122 vorbis_comment vcomment ;
123 /* Ventral working state for the packet->PCM decoder */
124 vorbis_dsp_state vdsp ;
125 /* Local working space for packet->PCM decode */
126 vorbis_block vblock ;
128 /* Encoding quality in range [0.0, 1.0]. */
133 vorbis_read_header (SF_PRIVATE *psf, int log_data)
135 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
136 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
143 /* Weird stuff happens if these aren't called. */
144 ogg_stream_reset (&odata->ostream) ;
145 ogg_sync_reset (&odata->osync) ;
148 ** Grab some data at the head of the stream. We want the first page
149 ** (which is guaranteed to be small and only contain the Vorbis
150 ** stream initial header) We need the first page to get the stream
154 /* Expose the buffer */
155 buffer = ogg_sync_buffer (&odata->osync, 4096L) ;
157 /* Grab the part of the header that has already been read. */
158 memcpy (buffer, psf->header, psf->headindex) ;
159 bytes = psf->headindex ;
161 /* Submit a 4k block to libvorbis' Ogg layer */
162 bytes += psf_fread (buffer + psf->headindex, 1, 4096 - psf->headindex, psf) ;
163 ogg_sync_wrote (&odata->osync, bytes) ;
165 /* Get the first page. */
166 if ((nn = ogg_sync_pageout (&odata->osync, &odata->opage)) != 1)
168 /* Have we simply run out of data? If so, we're done. */
172 /* Error case. Must not be Vorbis data */
173 psf_log_printf (psf, "Input does not appear to be an Ogg bitstream.\n") ;
174 return SFE_MALFORMED_FILE ;
178 ** Get the serial number and set up the rest of decode.
179 ** Serialno first ; use it to set up a logical stream.
181 ogg_stream_clear (&odata->ostream) ;
182 ogg_stream_init (&odata->ostream, ogg_page_serialno (&odata->opage)) ;
184 if (ogg_stream_pagein (&odata->ostream, &odata->opage) < 0)
185 { /* Error ; stream version mismatch perhaps. */
186 psf_log_printf (psf, "Error reading first page of Ogg bitstream data\n") ;
187 return SFE_MALFORMED_FILE ;
190 if (ogg_stream_packetout (&odata->ostream, &odata->opacket) != 1)
191 { /* No page? must not be vorbis. */
192 psf_log_printf (psf, "Error reading initial header packet.\n") ;
193 return SFE_MALFORMED_FILE ;
197 ** This function (vorbis_read_header) gets called multiple times, so the OGG
198 ** and vorbis structs have to be cleared every time we pass through to
199 ** prevent memory leaks.
201 vorbis_block_clear (&vdata->vblock) ;
202 vorbis_dsp_clear (&vdata->vdsp) ;
203 vorbis_comment_clear (&vdata->vcomment) ;
204 vorbis_info_clear (&vdata->vinfo) ;
207 ** Extract the initial header from the first page and verify that the
208 ** Ogg bitstream is in fact Vorbis data.
210 ** I handle the initial header first instead of just having the code
211 ** read all three Vorbis headers at once because reading the initial
212 ** header is an easy way to identify a Vorbis bitstream and it's
213 ** useful to see that functionality seperated out.
215 vorbis_info_init (&vdata->vinfo) ;
216 vorbis_comment_init (&vdata->vcomment) ;
218 if (vorbis_synthesis_headerin (&vdata->vinfo, &vdata->vcomment, &odata->opacket) < 0)
219 { /* Error case ; not a vorbis header. */
220 psf_log_printf (psf, "Found Vorbis in stream header, but vorbis_synthesis_headerin failed.\n") ;
221 return SFE_MALFORMED_FILE ;
225 ** Common Ogg metadata fields?
226 ** TITLE, VERSION, ALBUM, TRACKNUMBER, ARTIST, PERFORMER, COPYRIGHT, LICENSE,
227 ** ORGANIZATION, DESCRIPTION, GENRE, DATE, LOCATION, CONTACT, ISRC,
233 for (k = 0 ; k < ARRAY_LEN (vorbis_metatypes) ; k++)
236 dd = vorbis_comment_query (&vdata->vcomment, vorbis_metatypes [k].name, 0) ;
239 psf_store_string (psf, vorbis_metatypes [k].id, dd) ;
244 ** At this point, we're sure we're Vorbis. We've set up the logical (Ogg)
245 ** bitstream decoder. Get the comment and codebook headers and set up the
248 ** The next two packets in order are the comment and codebook headers.
249 ** They're likely large and may span multiple pages. Thus we reead
250 ** and submit data until we get our two pacakets, watching that no
251 ** pages are missing. If a page is missing, error out ; losing a
252 ** header page is the only place where missing data is fatal.
255 i = 0 ; /* Count of number of packets read */
257 { int result = ogg_sync_pageout (&odata->osync, &odata->opage) ;
259 { /* Need more data */
260 buffer = ogg_sync_buffer (&odata->osync, 4096) ;
261 bytes = psf_fread (buffer, 1, 4096, psf) ;
263 if (bytes == 0 && i < 2)
264 { psf_log_printf (psf, "End of file before finding all Vorbis headers!\n") ;
265 return SFE_MALFORMED_FILE ;
267 nn = ogg_sync_wrote (&odata->osync, bytes) ;
269 else if (result == 1)
271 ** Don't complain about missing or corrupt data yet. We'll
272 ** catch it at the packet output phase.
274 ** We can ignore any errors here as they'll also become apparent
277 nn = ogg_stream_pagein (&odata->ostream, &odata->opage) ;
279 { result = ogg_stream_packetout (&odata->ostream, &odata->opacket) ;
283 { /* Uh oh ; data at some point was corrupted or missing!
284 ** We can't tolerate that in a header. Die. */
285 psf_log_printf (psf, "Corrupt secondary header. Exiting.\n") ;
286 return SFE_MALFORMED_FILE ;
289 vorbis_synthesis_headerin (&vdata->vinfo, &vdata->vcomment, &odata->opacket) ;
296 { int printed_metadata_msg = 0 ;
299 psf_log_printf (psf, "Bitstream is %d channel, %D Hz\n", vdata->vinfo.channels, vdata->vinfo.rate) ;
300 psf_log_printf (psf, "Encoded by : %s\n", vdata->vcomment.vendor) ;
302 /* Throw the comments plus a few lines about the bitstream we're decoding. */
303 for (k = 0 ; k < ARRAY_LEN (vorbis_metatypes) ; k++)
306 dd = vorbis_comment_query (&vdata->vcomment, vorbis_metatypes [k].name, 0) ;
310 if (printed_metadata_msg == 0)
311 { psf_log_printf (psf, "Metadata :\n") ;
312 printed_metadata_msg = 1 ;
315 psf_store_string (psf, vorbis_metatypes [k].id, dd) ;
316 psf_log_printf (psf, " %-10s : %s\n", vorbis_metatypes [k].name, dd) ;
319 psf_log_printf (psf, "End\n") ;
322 psf->sf.samplerate = vdata->vinfo.rate ;
323 psf->sf.channels = vdata->vinfo.channels ;
324 psf->sf.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS ;
326 /* OK, got and parsed all three headers. Initialize the Vorbis
327 ** packet->PCM decoder.
328 ** Central decode state. */
329 vorbis_synthesis_init (&vdata->vdsp, &vdata->vinfo) ;
331 /* Local state for most of the decode so multiple block decodes can
332 ** proceed in parallel. We could init multiple vorbis_block structures
334 vorbis_block_init (&vdata->vdsp, &vdata->vblock) ;
339 } /* vorbis_read_header */
342 vorbis_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
344 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
345 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
348 vorbis_info_init (&vdata->vinfo) ;
350 /* The style of encoding should be selectable here, VBR quality mode. */
351 ret = vorbis_encode_init_vbr (&vdata->vinfo, psf->sf.channels, psf->sf.samplerate, vdata->quality) ;
354 ret = vorbis_encode_init (&vdata->vinfo, psf->sf.channels, psf->sf.samplerate, -1, 128000, -1) ; /* average bitrate mode */
355 ret = ( vorbis_encode_setup_managed (&vdata->vinfo, psf->sf.channels, psf->sf.samplerate, -1, 128000, -1)
356 || vorbis_encode_ctl (&vdata->vinfo, OV_ECTL_RATEMANAGE_AVG, NULL)
357 || vorbis_encode_setup_init (&vdata->vinfo)
361 return SFE_BAD_OPEN_FORMAT ;
366 vorbis_comment_init (&vdata->vcomment) ;
368 vorbis_comment_add_tag (&vdata->vcomment, "ENCODER", "libsndfile") ;
369 for (k = 0 ; k < SF_MAX_STRINGS ; k++)
370 { const char * name ;
372 if (psf->strings.data [k].type == 0)
375 switch (psf->strings.data [k].type)
376 { case SF_STR_TITLE : name = "TITLE" ; break ;
377 case SF_STR_COPYRIGHT : name = "COPYRIGHT" ; break ;
378 case SF_STR_SOFTWARE : name = "SOFTWARE" ; break ;
379 case SF_STR_ARTIST : name = "ARTIST" ; break ;
380 case SF_STR_COMMENT : name = "COMMENT" ; break ;
381 case SF_STR_DATE : name = "DATE" ; break ;
382 case SF_STR_ALBUM : name = "ALBUM" ; break ;
383 case SF_STR_LICENSE : name = "LICENSE" ; break ;
384 case SF_STR_TRACKNUMBER : name = "Tracknumber" ; break ;
385 case SF_STR_GENRE : name = "Genre" ; break ;
390 vorbis_comment_add_tag (&vdata->vcomment, name, psf->strings.storage + psf->strings.data [k].offset) ;
393 /* set up the analysis state and auxiliary encoding storage */
394 vorbis_analysis_init (&vdata->vdsp, &vdata->vinfo) ;
395 vorbis_block_init (&vdata->vdsp, &vdata->vblock) ;
398 ** Set up our packet->stream encoder.
399 ** Pick a random serial number ; that way we can more likely build
400 ** chained streams just by concatenation.
403 ogg_stream_init (&odata->ostream, psf_rand_int32 ()) ;
405 /* Vorbis streams begin with three headers ; the initial header (with
406 most of the codec setup parameters) which is mandated by the Ogg
407 bitstream spec. The second header holds any comment fields. The
408 third header holds the bitstream codebook. We merely need to
409 make the headers, then pass them to libvorbis one at a time ;
410 libvorbis handles the additional Ogg bitstream constraints */
412 { ogg_packet header ;
413 ogg_packet header_comm ;
414 ogg_packet header_code ;
417 vorbis_analysis_headerout (&vdata->vdsp, &vdata->vcomment, &header, &header_comm, &header_code) ;
418 ogg_stream_packetin (&odata->ostream, &header) ; /* automatically placed in its own page */
419 ogg_stream_packetin (&odata->ostream, &header_comm) ;
420 ogg_stream_packetin (&odata->ostream, &header_code) ;
422 /* This ensures the actual
423 * audio data will start on a new page, as per spec
425 while ((result = ogg_stream_flush (&odata->ostream, &odata->opage)) != 0)
426 { psf_fwrite (odata->opage.header, 1, odata->opage.header_len, psf) ;
427 psf_fwrite (odata->opage.body, 1, odata->opage.body_len, psf) ;
432 } /* vorbis_write_header */
435 vorbis_close (SF_PRIVATE *psf)
436 { OGG_PRIVATE* odata = psf->container_data ;
437 VORBIS_PRIVATE *vdata = psf->codec_data ;
439 if (odata == NULL || vdata == NULL)
442 /* Clean up this logical bitstream ; before exit we shuld see if we're
443 ** followed by another [chained]. */
445 if (psf->file.mode == SFM_WRITE)
447 if (psf->write_current <= 0)
448 vorbis_write_header (psf, 0) ;
450 vorbis_analysis_wrote (&vdata->vdsp, 0) ;
451 while (vorbis_analysis_blockout (&vdata->vdsp, &vdata->vblock) == 1)
454 /* analysis, assume we want to use bitrate management */
455 vorbis_analysis (&vdata->vblock, NULL) ;
456 vorbis_bitrate_addblock (&vdata->vblock) ;
458 while (vorbis_bitrate_flushpacket (&vdata->vdsp, &odata->opacket))
459 { /* weld the packet into the bitstream */
460 ogg_stream_packetin (&odata->ostream, &odata->opacket) ;
462 /* write out pages (if any) */
464 { int result = ogg_stream_pageout (&odata->ostream, &odata->opage) ;
465 if (result == 0) break ;
466 psf_fwrite (odata->opage.header, 1, odata->opage.header_len, psf) ;
467 psf_fwrite (odata->opage.body, 1, odata->opage.body_len, psf) ;
469 /* this could be set above, but for illustrative purposes, I do
470 it here (to show that vorbis does know where the stream ends) */
472 if (ogg_page_eos (&odata->opage)) odata->eos = 1 ;
478 /* ogg_page and ogg_packet structs always point to storage in
479 libvorbis. They are never freed or manipulated directly */
481 vorbis_block_clear (&vdata->vblock) ;
482 vorbis_dsp_clear (&vdata->vdsp) ;
483 vorbis_comment_clear (&vdata->vcomment) ;
484 vorbis_info_clear (&vdata->vinfo) ;
490 ogg_vorbis_open (SF_PRIVATE *psf)
491 { OGG_PRIVATE* odata = psf->container_data ;
492 VORBIS_PRIVATE* vdata = calloc (1, sizeof (VORBIS_PRIVATE)) ;
496 { psf_log_printf (psf, "%s : odata is NULL???\n", __func__) ;
497 return SFE_INTERNAL ;
500 psf->codec_data = vdata ;
502 if (psf->file.mode == SFM_RDWR)
503 return SFE_BAD_MODE_RW ;
505 psf_log_printf (psf, "Vorbis library version : %s\n", vorbis_version_string ()) ;
507 if (psf->file.mode == SFM_READ)
508 { /* Call this here so it only gets called once, so no memory is leaked. */
509 ogg_sync_init (&odata->osync) ;
511 if ((error = vorbis_read_header (psf, 1)))
514 psf->read_short = vorbis_read_s ;
515 psf->read_int = vorbis_read_i ;
516 psf->read_float = vorbis_read_f ;
517 psf->read_double = vorbis_read_d ;
518 psf->sf.frames = vorbis_length (psf) ;
521 psf->codec_close = vorbis_close ;
522 if (psf->file.mode == SFM_WRITE)
524 /* Set the default vorbis quality here. */
525 vdata->quality = 0.4 ;
527 psf->write_header = vorbis_write_header ;
528 psf->write_short = vorbis_write_s ;
529 psf->write_int = vorbis_write_i ;
530 psf->write_float = vorbis_write_f ;
531 psf->write_double = vorbis_write_d ;
533 psf->sf.frames = SF_COUNT_MAX ; /* Unknown really */
534 psf->strings.flags = SF_STR_ALLOW_START ;
537 psf->seek = vorbis_seek ;
538 psf->command = vorbis_command ;
539 psf->byterate = vorbis_byterate ;
541 /* FIXME, FIXME, FIXME : Hack these here for now and correct later. */
542 psf->sf.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS ;
543 psf->sf.sections = 1 ;
545 psf->datalength = 1 ;
546 psf->dataoffset = 0 ;
550 } /* ogg_vorbis_open */
553 vorbis_command (SF_PRIVATE *psf, int command, void * data, int datasize)
554 { VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
557 { case SFC_SET_COMPRESSION_LEVEL :
558 if (data == NULL || datasize != sizeof (double))
561 if (psf->have_written)
564 vdata->quality = 1.0 - *((double *) data) ;
567 vdata->quality = SF_MAX (0.0, SF_MIN (1.0, vdata->quality)) ;
569 psf_log_printf (psf, "%s : Setting SFC_SET_VBR_ENCODING_QUALITY to %f.\n", __func__, vdata->quality) ;
577 } /* vorbis_command */
580 vorbis_rnull (SF_PRIVATE *UNUSED (psf), int samples, void *UNUSED (vptr), int UNUSED (off) , int channels, float **UNUSED (pcm))
582 return samples * channels ;
586 vorbis_rshort (SF_PRIVATE *psf, int samples, void *vptr, int off, int channels, float **pcm)
588 short *ptr = (short*) vptr + off ;
590 if (psf->float_int_mult)
592 float inverse = 1.0 / psf->float_max ;
593 for (j = 0 ; j < samples ; j++)
594 for (n = 0 ; n < channels ; n++)
595 ptr [i++] = lrintf ((pcm [n][j] * inverse) * 32767.0f) ;
599 for (j = 0 ; j < samples ; j++)
600 for (n = 0 ; n < channels ; n++)
601 ptr [i++] = lrintf (pcm [n][j] * 32767.0f) ;
604 } /* vorbis_rshort */
607 vorbis_rint (SF_PRIVATE *psf, int samples, void *vptr, int off, int channels, float **pcm)
609 int *ptr = (int*) vptr + off ;
612 if (psf->float_int_mult)
614 float inverse = 1.0 / psf->float_max ;
615 for (j = 0 ; j < samples ; j++)
616 for (n = 0 ; n < channels ; n++)
617 ptr [i++] = lrintf ((pcm [n][j] * inverse) * 2147483647.0f) ;
621 for (j = 0 ; j < samples ; j++)
622 for (n = 0 ; n < channels ; n++)
623 ptr [i++] = lrintf (pcm [n][j] * 2147483647.0f) ;
629 vorbis_rfloat (SF_PRIVATE *UNUSED (psf), int samples, void *vptr, int off, int channels, float **pcm)
631 float *ptr = (float*) vptr + off ;
633 for (j = 0 ; j < samples ; j++)
634 for (n = 0 ; n < channels ; n++)
635 ptr [i++] = pcm [n][j] ;
637 } /* vorbis_rfloat */
640 vorbis_rdouble (SF_PRIVATE *UNUSED (psf), int samples, void *vptr, int off, int channels, float **pcm)
642 double *ptr = (double*) vptr + off ;
644 for (j = 0 ; j < samples ; j++)
645 for (n = 0 ; n < channels ; n++)
646 ptr [i++] = pcm [n][j] ;
648 } /* vorbis_rdouble */
652 vorbis_read_sample (SF_PRIVATE *psf, void *ptr, sf_count_t lens, convert_func *transfn)
654 VORBIS_PRIVATE *vdata = psf->codec_data ;
655 OGG_PRIVATE *odata = psf->container_data ;
656 int len, samples, i = 0 ;
659 len = lens / psf->sf.channels ;
661 while ((samples = vorbis_synthesis_pcmout (&vdata->vdsp, &pcm)) > 0)
662 { if (samples > len) samples = len ;
663 i += transfn (psf, samples, ptr, i, psf->sf.channels, pcm) ;
665 /* tell libvorbis how many samples we actually consumed */
666 vorbis_synthesis_read (&vdata->vdsp, samples) ;
667 vdata->loc += samples ;
669 return i ; /* Is this necessary */
671 goto start0 ; /* Jump into the nasty nest */
672 while (len > 0 && !odata->eos)
674 while (len > 0 && !odata->eos)
675 { int result = ogg_sync_pageout (&odata->osync, &odata->opage) ;
676 if (result == 0) break ; /* need more data */
678 { /* missing or corrupt data at this page position */
679 psf_log_printf (psf, "Corrupt or missing data in bitstream ; continuing...\n") ;
682 { /* can safely ignore errors at this point */
683 ogg_stream_pagein (&odata->ostream, &odata->opage) ;
686 { result = ogg_stream_packetout (&odata->ostream, &odata->opacket) ;
688 break ; /* need more data */
690 { /* missing or corrupt data at this page position */
691 /* no reason to complain ; already complained above */
694 { /* we have a packet. Decode it */
695 if (vorbis_synthesis (&vdata->vblock, &odata->opacket) == 0) /* test for success! */
696 vorbis_synthesis_blockin (&vdata->vdsp, &vdata->vblock) ;
698 ** pcm is a multichannel float vector. In stereo, for
699 ** example, pcm [0] is left, and pcm [1] is right. samples is
700 ** the size of each channel. Convert the float values
701 ** (-1.<=range<=1.) to whatever PCM format and write it out.
704 while ((samples = vorbis_synthesis_pcmout (&vdata->vdsp, &pcm)) > 0)
705 { if (samples > len) samples = len ;
706 i += transfn (psf, samples, ptr, i, psf->sf.channels, pcm) ;
708 /* tell libvorbis how many samples we actually consumed */
709 vorbis_synthesis_read (&vdata->vdsp, samples) ;
710 vdata->loc += samples ;
712 return i ; /* Is this necessary */
716 if (ogg_page_eos (&odata->opage)) odata->eos = 1 ;
722 buffer = ogg_sync_buffer (&odata->osync, 4096) ;
723 bytes = psf_fread (buffer, 1, 4096, psf) ;
724 ogg_sync_wrote (&odata->osync, bytes) ;
725 if (bytes == 0) odata->eos = 1 ;
729 } /* vorbis_read_sample */
732 vorbis_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t lens)
733 { return vorbis_read_sample (psf, (void*) ptr, lens, vorbis_rshort) ;
734 } /* vorbis_read_s */
737 vorbis_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t lens)
738 { return vorbis_read_sample (psf, (void*) ptr, lens, vorbis_rint) ;
739 } /* vorbis_read_i */
742 vorbis_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t lens)
743 { return vorbis_read_sample (psf, (void*) ptr, lens, vorbis_rfloat) ;
744 } /* vorbis_read_f */
747 vorbis_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t lens)
748 { return vorbis_read_sample (psf, (void*) ptr, lens, vorbis_rdouble) ;
749 } /* vorbis_read_d */
751 /*==============================================================================
755 vorbis_write_samples (SF_PRIVATE *psf, OGG_PRIVATE *odata, VORBIS_PRIVATE *vdata, int in_frames)
757 vorbis_analysis_wrote (&vdata->vdsp, in_frames) ;
760 ** Vorbis does some data preanalysis, then divvies up blocks for
761 ** more involved (potentially parallel) processing. Get a single
762 ** block for encoding now.
764 while (vorbis_analysis_blockout (&vdata->vdsp, &vdata->vblock) == 1)
766 /* analysis, assume we want to use bitrate management */
767 vorbis_analysis (&vdata->vblock, NULL) ;
768 vorbis_bitrate_addblock (&vdata->vblock) ;
770 while (vorbis_bitrate_flushpacket (&vdata->vdsp, &odata->opacket))
772 /* weld the packet into the bitstream */
773 ogg_stream_packetin (&odata->ostream, &odata->opacket) ;
775 /* write out pages (if any) */
777 { int result = ogg_stream_pageout (&odata->ostream, &odata->opage) ;
780 psf_fwrite (odata->opage.header, 1, odata->opage.header_len, psf) ;
781 psf_fwrite (odata->opage.body, 1, odata->opage.body_len, psf) ;
783 /* This could be set above, but for illustrative purposes, I do
784 ** it here (to show that vorbis does know where the stream ends) */
785 if (ogg_page_eos (&odata->opage))
791 vdata->loc += in_frames ;
792 } /* vorbis_write_data */
796 vorbis_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t lens)
799 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
800 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
801 int in_frames = lens / psf->sf.channels ;
802 float **buffer = vorbis_analysis_buffer (&vdata->vdsp, in_frames) ;
803 for (i = 0 ; i < in_frames ; i++)
804 for (m = 0 ; m < psf->sf.channels ; m++)
805 buffer [m][i] = (float) (ptr [j++]) / 32767.0f ;
807 vorbis_write_samples (psf, odata, vdata, in_frames) ;
810 } /* vorbis_write_s */
813 vorbis_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t lens)
815 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
816 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
817 int in_frames = lens / psf->sf.channels ;
818 float **buffer = vorbis_analysis_buffer (&vdata->vdsp, in_frames) ;
819 for (i = 0 ; i < in_frames ; i++)
820 for (m = 0 ; m < psf->sf.channels ; m++)
821 buffer [m][i] = (float) (ptr [j++]) / 2147483647.0f ;
823 vorbis_write_samples (psf, odata, vdata, in_frames) ;
826 } /* vorbis_write_i */
829 vorbis_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t lens)
831 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
832 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
833 int in_frames = lens / psf->sf.channels ;
834 float **buffer = vorbis_analysis_buffer (&vdata->vdsp, in_frames) ;
835 for (i = 0 ; i < in_frames ; i++)
836 for (m = 0 ; m < psf->sf.channels ; m++)
837 buffer [m][i] = ptr [j++] ;
839 vorbis_write_samples (psf, odata, vdata, in_frames) ;
842 } /* vorbis_write_f */
845 vorbis_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t lens)
847 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
848 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
849 int in_frames = lens / psf->sf.channels ;
850 float **buffer = vorbis_analysis_buffer (&vdata->vdsp, in_frames) ;
851 for (i = 0 ; i < in_frames ; i++)
852 for (m = 0 ; m < psf->sf.channels ; m++)
853 buffer [m][i] = (float) ptr [j++] ;
855 vorbis_write_samples (psf, odata, vdata, in_frames) ;
858 } /* vorbis_write_d */
861 vorbis_seek (SF_PRIVATE *psf, int UNUSED (mode), sf_count_t offset)
863 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
864 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
866 if (odata == NULL || vdata == NULL)
870 { psf->error = SFE_BAD_SEEK ;
871 return ((sf_count_t) -1) ;
874 if (psf->file.mode == SFM_READ)
875 { sf_count_t target = offset - vdata->loc ;
878 { /* 12 to allow for OggS bit */
879 psf_fseek (psf, 12, SEEK_SET) ;
880 vorbis_read_header (psf, 0) ; /* Reset state */
885 { sf_count_t m = target > 4096 ? 4096 : target ;
888 ** Need to multiply by channels here because the seek is done in
889 ** terms of frames and the read function is done in terms of
892 vorbis_read_sample (psf, (void *) NULL, m * psf->sf.channels, vorbis_rnull) ;
905 vorbis_byterate (SF_PRIVATE *psf)
907 if (psf->file.mode == SFM_READ)
908 return (psf->datalength * psf->sf.samplerate) / psf->sf.frames ;
911 } /* vorbis_byterate */
913 /*==============================================================================
914 ** Most of the following code was snipped from Mike Smith's ogginfo utility
915 ** which is part of vorbis-tools.
916 ** Vorbis tools is released under the GPL but Mike has kindly allowed the
917 ** following to be relicensed as LGPL for libsndfile.
927 uint32_t serial ; /* must be 32 bit unsigned */
928 ogg_stream_state ostream ;
931 vorbis_comment vcomment ;
932 sf_count_t lastgranulepos ;
938 stream_processor *streams ;
945 create_stream_set (void)
946 { stream_set *set = calloc (1, sizeof (stream_set)) ;
948 set->streams = calloc (5, sizeof (stream_processor)) ;
953 } /* create_stream_set */
956 vorbis_end (stream_processor *stream, sf_count_t * len)
957 { *len += stream->lastgranulepos ;
958 vorbis_comment_clear (&stream->vcomment) ;
959 vorbis_info_clear (&stream->vinfo) ;
963 free_stream_set (stream_set *set, sf_count_t * len)
966 for (i = 0 ; i < set->used ; i++)
967 { if (!set->streams [i].end)
968 vorbis_end (&set->streams [i], len) ;
969 ogg_stream_clear (&set->streams [i].ostream) ;
972 free (set->streams) ;
974 } /* free_stream_set */
977 streams_open (stream_set *set)
980 for (i = 0 ; i < set->used ; i++)
981 if (!set->streams [i].end)
986 static stream_processor *
987 find_stream_processor (stream_set *set, ogg_page *page)
988 { uint32_t serial = ogg_page_serialno (page) ;
991 stream_processor *stream ;
993 for (i = 0 ; i < set->used ; i++)
995 if (serial == set->streams [i].serial)
996 { /* We have a match! */
997 stream = & (set->streams [i]) ;
999 set->in_headers = 0 ;
1000 /* if we have detected EOS, then this can't occur here. */
1002 { stream->isillegal = 1 ;
1007 stream->end = ogg_page_eos (page) ;
1008 stream->serial = serial ;
1013 /* If there are streams open, and we've reached the end of the
1014 ** headers, then we can't be starting a new stream.
1015 ** XXX: might this sometimes catch ok streams if EOS flag is missing,
1016 ** but the stream is otherwise ok?
1018 if (streams_open (set) && !set->in_headers)
1021 set->in_headers = 1 ;
1023 if (set->allocated < set->used)
1024 stream = &set->streams [set->used] ;
1026 { set->allocated += 5 ;
1027 set->streams = realloc (set->streams, sizeof (stream_processor) * set->allocated) ;
1028 stream = &set->streams [set->used] ;
1034 stream->isillegal = invalid ;
1040 /* We end up processing the header page twice, but that's ok. */
1041 ogg_stream_init (&stream->ostream, serial) ;
1042 ogg_stream_pagein (&stream->ostream, page) ;
1043 res = ogg_stream_packetout (&stream->ostream, &packet) ;
1046 else if (packet.bytes >= 7 && memcmp (packet.packet, "\x01vorbis", 7) == 0)
1048 stream->lastgranulepos = 0 ;
1049 vorbis_comment_init (&stream->vcomment) ;
1050 vorbis_info_init (&stream->vinfo) ;
1053 res = ogg_stream_packetout (&stream->ostream, &packet) ;
1055 /* re-init, ready for processing */
1056 ogg_stream_clear (&stream->ostream) ;
1057 ogg_stream_init (&stream->ostream, serial) ;
1060 stream->end = ogg_page_eos (page) ;
1061 stream->serial = serial ;
1064 } /* find_stream_processor */
1067 vorbis_length_get_next_page (SF_PRIVATE *psf, ogg_sync_state * osync, ogg_page *page)
1068 { static const int CHUNK_SIZE = 4500 ;
1070 while (ogg_sync_pageout (osync, page) <= 0)
1071 { char * buffer = ogg_sync_buffer (osync, CHUNK_SIZE) ;
1072 int bytes = psf_fread (buffer, 1, 4096, psf) ;
1075 { ogg_sync_wrote (osync, 0) ;
1079 ogg_sync_wrote (osync, bytes) ;
1083 } /* vorbis_length_get_next_page */
1086 vorbis_length_aux (SF_PRIVATE * psf)
1088 ogg_sync_state osync ;
1090 sf_count_t len = 0 ;
1091 stream_set *processors ;
1093 processors = create_stream_set () ;
1094 if (processors == NULL)
1095 return 0 ; // out of memory?
1097 ogg_sync_init (&osync) ;
1099 while (vorbis_length_get_next_page (psf, &osync, &page))
1101 stream_processor *p = find_stream_processor (processors, &page) ;
1108 if (p->isillegal && !p->shownillegal)
1110 p->shownillegal = 1 ;
1111 /* If it's a new stream, we want to continue processing this page
1112 ** anyway to suppress additional spurious errors
1114 if (!p->isnew) continue ;
1118 { ogg_packet packet ;
1121 ogg_stream_pagein (&p->ostream, &page) ;
1122 if (p->doneheaders < 3)
1125 while (ogg_stream_packetout (&p->ostream, &packet) > 0)
1127 if (p->doneheaders < 3)
1128 { if (vorbis_synthesis_headerin (&p->vinfo, &p->vcomment, &packet) < 0)
1134 { sf_count_t gp = ogg_page_granulepos (&page) ;
1135 if (gp > 0) p->lastgranulepos = gp ;
1138 { vorbis_end (p, &len) ;
1144 ogg_sync_clear (&osync) ;
1145 free_stream_set (processors, &len) ;
1148 } /* vorbis_length_aux */
1151 vorbis_length (SF_PRIVATE *psf)
1152 { sf_count_t length ;
1155 if (psf->sf.seekable == 0)
1156 return SF_COUNT_MAX ;
1158 psf_fseek (psf, 0, SEEK_SET) ;
1159 length = vorbis_length_aux (psf) ;
1161 psf_fseek (psf, 12, SEEK_SET) ;
1162 if ((error = vorbis_read_header (psf, 0)) != 0)
1163 psf->error = error ;
1166 } /* vorbis_length */
1168 #else /* HAVE_EXTERNAL_LIBS */
1171 ogg_vorbis_open (SF_PRIVATE *psf)
1173 psf_log_printf (psf, "This version of libsndfile was compiled without Ogg/Vorbis support.\n") ;
1174 return SFE_UNIMPLEMENTED ;
1175 } /* ogg_vorbis_open */