1 /*
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
6 **
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.
11 **
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.
16 **
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.
20 */
21
22 /*
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
26 **
27 ** Redistribution and use in source and binary forms, with or without
28 ** modification, are permitted provided that the following conditions
29 ** are met:
30 **
31 ** - Redistributions of source code must retain the above copyright
32 ** notice, this list of conditions and the following disclaimer.
33 **
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.
37 **
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.
41 **
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.
53 */
54
55 #include "sfconfig.h"
56
57 #include <stdio.h>
58 #include <fcntl.h>
59 #include <string.h>
60 #include <ctype.h>
61 #include <time.h>
62 #include <math.h>
63
64 #if HAVE_UNISTD_H
65 #include <unistd.h>
66 #else
67 #include "sf_unistd.h"
68 #endif
69
70 #include "sndfile.h"
71 #include "sfendian.h"
72 #include "common.h"
73
74 #if HAVE_EXTERNAL_XIPH_LIBS
75
76 #include <ogg/ogg.h>
77 #include <vorbis/codec.h>
78 #include <vorbis/vorbisenc.h>
79
80 #include "ogg.h"
81
82 /* How many seconds in the future to not bother bisection searching for. */
83 #define VORBIS_SEEK_THRESHOLD 2
84
85 typedef int convert_func (SF_PRIVATE *psf, int, void *, int, int, float **) ;
86
87 static int vorbis_read_header (SF_PRIVATE *psf) ;
88 static int vorbis_write_header (SF_PRIVATE *psf, int calc_length) ;
89 static int vorbis_close (SF_PRIVATE *psf) ;
90 static int vorbis_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
91 static int vorbis_byterate (SF_PRIVATE *psf) ;
92 static int vorbis_calculate_granulepos (SF_PRIVATE *psf, uint64_t *gp_out) ;
93 static int vorbis_skip (SF_PRIVATE *psf, uint64_t target_gp) ;
94 static int vorbis_seek_trysearch (SF_PRIVATE *psf, uint64_t target_gp) ;
95 static sf_count_t vorbis_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
96 static sf_count_t vorbis_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
97 static sf_count_t vorbis_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
98 static sf_count_t vorbis_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
99 static sf_count_t vorbis_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
100 static sf_count_t vorbis_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
101 static sf_count_t vorbis_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
102 static sf_count_t vorbis_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
103 static sf_count_t vorbis_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
104 static sf_count_t vorbis_read_sample (SF_PRIVATE *psf, void *ptr, sf_count_t lens, convert_func *transfn) ;
105 static int vorbis_rnull (SF_PRIVATE *psf, int samples, void *vptr, int off , int channels, float **pcm) ;
106
107 typedef struct
108 { int id ;
109 const char *name ;
110 } STR_PAIRS ;
111
112
113 /* See https://xiph.org/vorbis/doc/v-comment.html */
114 static STR_PAIRS vorbis_metatypes [] =
115 { { SF_STR_TITLE, "Title" },
116 { SF_STR_COPYRIGHT, "Copyright" },
117 { SF_STR_SOFTWARE, "Software" },
118 { SF_STR_ARTIST, "Artist" },
119 { SF_STR_COMMENT, "Comment" },
120 { SF_STR_DATE, "Date" },
121 { SF_STR_ALBUM, "Album" },
122 { SF_STR_LICENSE, "License" },
123 { SF_STR_TRACKNUMBER, "Tracknumber" },
124 { SF_STR_GENRE, "Genre" },
125 } ;
126
127 typedef struct
128 { /* Current granule position. */
129 uint64_t gp ;
130 /* Struct that stores all the static vorbis bitstream settings */
131 vorbis_info vinfo ;
132 /* Struct that stores all the bitstream user comments */
133 vorbis_comment vcomment ;
134 /* Central working state for the packet->PCM decoder */
135 vorbis_dsp_state vdsp ;
136 /* Local working space for packet->PCM decode */
137 vorbis_block vblock ;
138 /* Encoding quality in range [0.0, 1.0]. */
139 double quality ;
140 /* Offset of the first samples' granule position. */
141 uint64_t pcm_start ;
142 /* Last valid samples' granule position. */
143 uint64_t pcm_end ;
144 /* File offset of the start of the last page. */
145 sf_count_t last_page ;
146 } VORBIS_PRIVATE ;
147
148 static int
vorbis_read_header(SF_PRIVATE * psf)149 vorbis_read_header (SF_PRIVATE *psf)
150 { OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
151 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
152 int printed_metadata_msg = 0 ;
153 int i, nn ;
154 sf_count_t last_page ;
155 sf_count_t saved_offset ;
156
157 /*
158 ** The first page of the Ogg stream we are told to try and open as Vorbis
159 ** has already been loaded into odata->ostream by ogg_open().
160 **
161 ** Extract the initial header from the first page and verify that the
162 ** Ogg bitstream is in fact Vorbis data.
163 */
164
165 vorbis_info_init (&vdata->vinfo) ;
166 vorbis_comment_init (&vdata->vcomment) ;
167
168 if (!odata->opacket.b_o_s)
169 { psf_log_printf (psf, "Vorbis: First packet does not have a beginning-of-stream bit.\n") ;
170 return SFE_MALFORMED_FILE ;
171 }
172
173 if (ogg_stream_packetpeek (&odata->ostream, NULL))
174 { psf_log_printf (psf, "Vorbis: First page contains extraneous packets!\n") ;
175 return SFE_MALFORMED_FILE ;
176 }
177
178 if (vorbis_synthesis_headerin (&vdata->vinfo, &vdata->vcomment, &odata->opacket) < 0)
179 { /* Error case ; not a vorbis header. */
180 psf_log_printf (psf, "Found Vorbis in stream header, but vorbis_synthesis_headerin failed.\n") ;
181 return SFE_MALFORMED_FILE ;
182 } ;
183
184 /*
185 ** At this point, we're sure we're Vorbis. We've set up the logical (Ogg)
186 ** bitstream decoder. Get the comment and codebook headers and set up the
187 ** Vorbis decoder.
188 **
189 ** The next two packets in order are the comment and codebook headers.
190 ** They're likely large and may span multiple pages. Thus we read
191 ** and submit data until we get our two packets, watching that no
192 ** pages are missing. If a page is missing, error out ; losing a
193 ** header page is the only place where missing data is fatal.
194 */
195
196 i = 0 ; /* Count of number of packets read */
197 while (i < 2)
198 { nn = ogg_stream_packetout (&odata->ostream, &odata->opacket) ;
199
200 if (nn == 0)
201 { nn = ogg_stream_next_page (psf, odata) ;
202 if (nn == 0)
203 { psf_log_printf (psf, "End of file before finding all Vorbis headers!\n") ;
204 return SFE_MALFORMED_FILE ;
205 } ;
206 if (nn == -1)
207 { psf_log_printf (psf, "Error reading file while finding Vorbis headers!\n") ;
208 return psf->error ;
209 } ;
210 continue ;
211 }
212
213 if (nn < 0)
214 { /* A hole while reading headers. This could be bad. */
215 psf_log_printf (psf, "Corrupt secondary header. Exiting.\n") ;
216 return SFE_MALFORMED_FILE ;
217 } ;
218
219 vorbis_synthesis_headerin (&vdata->vinfo, &vdata->vcomment, &odata->opacket) ;
220 i++ ;
221 } ;
222
223 /* Check for extraneous packets in the last headers page. */
224 while (ogg_stream_packetout (&odata->ostream, &odata->opacket) == 1)
225 { i++ ;
226 }
227 if (i > 2)
228 psf_log_printf (psf, "Vorbis: stream has extraneous header packets.\n") ;
229
230 psf_log_printf (psf, "Bitstream is %d channel, %D Hz\n", vdata->vinfo.channels, vdata->vinfo.rate) ;
231 psf_log_printf (psf, "Encoded by : %s\n", vdata->vcomment.vendor) ;
232
233 /* Save the offset of the first payload page */
234 psf->dataoffset = ogg_sync_ftell (psf) ;
235
236 /*
237 ** Calculate the granule position offset. The first page with a payload
238 ** packet shouldn't end in a continued packet. The difference between the
239 ** page's granule position and the sum of frames on the page tells us the
240 ** granule position offset.
241 ** See https://xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-132000A.2
242 */
243 ogg_stream_unpack_page (psf, odata) ;
244 vorbis_calculate_granulepos (psf, &vdata->pcm_start) ;
245 vdata->gp = vdata->pcm_start ;
246
247 /*
248 ** Find the end of the stream, save it. Only works if the file is seekable.
249 */
250 vdata->pcm_end = (uint64_t) -1 ;
251 psf->datalength = psf->filelength ;
252 if (!psf->is_pipe)
253 { saved_offset = ogg_sync_ftell (psf) ;
254 last_page = ogg_sync_last_page_before (psf, odata, &vdata->pcm_end, psf->filelength, odata->ostream.serialno) ;
255 if (last_page > 0)
256 { if (!ogg_page_eos (&odata->opage))
257 psf_log_printf (psf, "Ogg: Last page lacks an end-of-stream bit.\n") ;
258 psf->datalength = last_page + odata->opage.header_len + odata->opage.body_len - psf->dataoffset ;
259 if (psf->datalength + psf->dataoffset < psf->filelength)
260 psf_log_printf (psf, "Ogg: Junk after the last page.\n") ;
261 vdata->last_page = last_page ;
262 } ;
263
264 ogg_sync_fseek (psf, saved_offset, SEEK_SET) ;
265 }
266
267 psf_log_printf (psf, "PCM offset : %D\n", vdata->pcm_start) ;
268 if (vdata->pcm_end != (uint64_t) -1)
269 psf_log_printf (psf, "PCM end : %D\n", vdata->pcm_end) ;
270 else
271 psf_log_printf (psf, "PCM end : unknown\n") ;
272
273 /* Throw the comments plus a few lines about the bitstream we're decoding. */
274 for (i = 0 ; i < ARRAY_LEN (vorbis_metatypes) ; i++)
275 { char *dd ;
276
277 dd = vorbis_comment_query (&vdata->vcomment, vorbis_metatypes [i].name, 0) ;
278 if (dd == NULL)
279 continue ;
280
281 if (printed_metadata_msg == 0)
282 { psf_log_printf (psf, "Metadata :\n") ;
283 printed_metadata_msg = 1 ;
284 } ;
285
286 psf_store_string (psf, vorbis_metatypes [i].id, dd) ;
287 psf_log_printf (psf, " %-10s : %s\n", vorbis_metatypes [i].name, dd) ;
288 } ;
289 psf_log_printf (psf, "End\n") ;
290
291 psf->sf.samplerate = vdata->vinfo.rate ;
292 psf->sf.channels = vdata->vinfo.channels ;
293 psf->sf.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS ;
294 psf->sf.frames = (vdata->pcm_end != (uint64_t) -1) ? vdata->pcm_end - vdata->pcm_start : SF_COUNT_MAX ;
295
296 /* OK, got and parsed all three headers. Initialize the Vorbis
297 ** packet->PCM decoder.
298 ** Central decode state. */
299 vorbis_synthesis_init (&vdata->vdsp, &vdata->vinfo) ;
300
301 /* Local state for most of the decode so multiple block decodes can
302 ** proceed in parallel. We could init multiple vorbis_block structures
303 ** for vdsp here. */
304 vorbis_block_init (&vdata->vdsp, &vdata->vblock) ;
305
306 return 0 ;
307 } /* vorbis_read_header */
308
309 static int
vorbis_write_header(SF_PRIVATE * psf,int UNUSED (calc_length))310 vorbis_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
311 {
312 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
313 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
314 int k, ret ;
315
316 vorbis_info_init (&vdata->vinfo) ;
317
318 /* The style of encoding should be selectable here, VBR quality mode. */
319 ret = vorbis_encode_init_vbr (&vdata->vinfo, psf->sf.channels, psf->sf.samplerate, vdata->quality) ;
320
321 #if 0
322 ret = vorbis_encode_init (&vdata->vinfo, psf->sf.channels, psf->sf.samplerate, -1, 128000, -1) ; /* average bitrate mode */
323 ret = ( vorbis_encode_setup_managed (&vdata->vinfo, psf->sf.channels, psf->sf.samplerate, -1, 128000, -1)
324 || vorbis_encode_ctl (&vdata->vinfo, OV_ECTL_RATEMANAGE_AVG, NULL)
325 || vorbis_encode_setup_init (&vdata->vinfo)
326 ) ;
327 #endif
328 if (ret)
329 return SFE_BAD_OPEN_FORMAT ;
330
331 vdata->gp = 0 ;
332
333 /* add a comment */
334 vorbis_comment_init (&vdata->vcomment) ;
335
336 vorbis_comment_add_tag (&vdata->vcomment, "ENCODER", "libsndfile") ;
337 for (k = 0 ; k < SF_MAX_STRINGS ; k++)
338 { const char * name ;
339
340 if (psf->strings.data [k].type == 0)
341 break ;
342
343 switch (psf->strings.data [k].type)
344 { case SF_STR_TITLE : name = "TITLE" ; break ;
345 case SF_STR_COPYRIGHT : name = "COPYRIGHT" ; break ;
346 case SF_STR_SOFTWARE : name = "SOFTWARE" ; break ;
347 case SF_STR_ARTIST : name = "ARTIST" ; break ;
348 case SF_STR_COMMENT : name = "COMMENT" ; break ;
349 case SF_STR_DATE : name = "DATE" ; break ;
350 case SF_STR_ALBUM : name = "ALBUM" ; break ;
351 case SF_STR_LICENSE : name = "LICENSE" ; break ;
352 case SF_STR_TRACKNUMBER : name = "Tracknumber" ; break ;
353 case SF_STR_GENRE : name = "Genre" ; break ;
354
355 default : continue ;
356 } ;
357
358 vorbis_comment_add_tag (&vdata->vcomment, name, psf->strings.storage + psf->strings.data [k].offset) ;
359 } ;
360
361 /* set up the analysis state and auxiliary encoding storage */
362 vorbis_analysis_init (&vdata->vdsp, &vdata->vinfo) ;
363 vorbis_block_init (&vdata->vdsp, &vdata->vblock) ;
364
365 /*
366 ** Set up our packet->stream encoder.
367 ** Pick a random serial number ; that way we can more likely build
368 ** chained streams just by concatenation.
369 */
370
371 ogg_stream_init (&odata->ostream, psf_rand_int32 ()) ;
372
373 /* Vorbis streams begin with three headers ; the initial header (with
374 most of the codec setup parameters) which is mandated by the Ogg
375 bitstream spec. The second header holds any comment fields. The
376 third header holds the bitstream codebook. We merely need to
377 make the headers, then pass them to libvorbis one at a time ;
378 libvorbis handles the additional Ogg bitstream constraints */
379
380 { ogg_packet header ;
381 ogg_packet header_comm ;
382 ogg_packet header_code ;
383 int result ;
384
385 vorbis_analysis_headerout (&vdata->vdsp, &vdata->vcomment, &header, &header_comm, &header_code) ;
386 ogg_stream_packetin (&odata->ostream, &header) ; /* automatically placed in its own page */
387 ogg_stream_packetin (&odata->ostream, &header_comm) ;
388 ogg_stream_packetin (&odata->ostream, &header_code) ;
389
390 /* This ensures the actual
391 * audio data will start on a new page, as per spec
392 */
393 while ((result = ogg_stream_flush (&odata->ostream, &odata->opage)) != 0)
394 { ogg_write_page (psf, &odata->opage) ;
395 } ;
396 }
397
398 return 0 ;
399 } /* vorbis_write_header */
400
401 static int
vorbis_close(SF_PRIVATE * psf)402 vorbis_close (SF_PRIVATE *psf)
403 { OGG_PRIVATE* odata = psf->container_data ;
404 VORBIS_PRIVATE *vdata = psf->codec_data ;
405
406 if (odata == NULL || vdata == NULL)
407 return 0 ;
408
409 /* Clean up this logical bitstream ; before exit we shuld see if we're
410 ** followed by another [chained]. */
411
412 if (psf->file.mode == SFM_WRITE)
413 {
414 if (psf->write_current <= 0)
415 vorbis_write_header (psf, 0) ;
416
417 vorbis_analysis_wrote (&vdata->vdsp, 0) ;
418 while (vorbis_analysis_blockout (&vdata->vdsp, &vdata->vblock) == 1)
419 {
420
421 /* analysis, assume we want to use bitrate management */
422 vorbis_analysis (&vdata->vblock, NULL) ;
423 vorbis_bitrate_addblock (&vdata->vblock) ;
424
425 while (vorbis_bitrate_flushpacket (&vdata->vdsp, &odata->opacket))
426 { /* weld the packet into the bitstream */
427 ogg_stream_packetin (&odata->ostream, &odata->opacket) ;
428
429 /* write out pages (if any) */
430 while (!odata->eos)
431 { int result = ogg_stream_pageout (&odata->ostream, &odata->opage) ;
432 if (result == 0) break ;
433 ogg_write_page (psf, &odata->opage) ;
434
435 /* this could be set above, but for illustrative purposes, I do
436 it here (to show that vorbis does know where the stream ends) */
437
438 if (ogg_page_eos (&odata->opage)) odata->eos = 1 ;
439 }
440 }
441 }
442 }
443
444 /* ogg_page and ogg_packet structs always point to storage in
445 libvorbis. They are never freed or manipulated directly */
446
447 vorbis_block_clear (&vdata->vblock) ;
448 vorbis_dsp_clear (&vdata->vdsp) ;
449 vorbis_comment_clear (&vdata->vcomment) ;
450 vorbis_info_clear (&vdata->vinfo) ;
451
452 return 0 ;
453 } /* vorbis_close */
454
455 int
ogg_vorbis_open(SF_PRIVATE * psf)456 ogg_vorbis_open (SF_PRIVATE *psf)
457 { OGG_PRIVATE* odata = psf->container_data ;
458 VORBIS_PRIVATE* vdata ;
459 int error = 0 ;
460
461 if (odata == NULL)
462 { psf_log_printf (psf, "%s : odata is NULL???\n", __func__) ;
463 return SFE_INTERNAL ;
464 } ;
465
466 vdata = calloc (1, sizeof (VORBIS_PRIVATE)) ;
467 psf->codec_data = vdata ;
468
469 if (psf->file.mode == SFM_RDWR)
470 return SFE_BAD_MODE_RW ;
471
472 psf_log_printf (psf, "Vorbis library version : %s\n", vorbis_version_string ()) ;
473
474 if (psf->file.mode == SFM_READ)
475 { if ((error = vorbis_read_header (psf)))
476 return error ;
477
478 psf->read_short = vorbis_read_s ;
479 psf->read_int = vorbis_read_i ;
480 psf->read_float = vorbis_read_f ;
481 psf->read_double = vorbis_read_d ;
482 } ;
483
484 psf->codec_close = vorbis_close ;
485 if (psf->file.mode == SFM_WRITE)
486 {
487 /* Set the default vorbis quality here. */
488 vdata->quality = 0.4 ;
489
490 psf->write_header = vorbis_write_header ;
491 psf->write_short = vorbis_write_s ;
492 psf->write_int = vorbis_write_i ;
493 psf->write_float = vorbis_write_f ;
494 psf->write_double = vorbis_write_d ;
495
496 psf->sf.frames = 0 ;
497 psf->datalength = 0 ;
498 psf->filelength = 0 ;
499 psf->dataoffset = 0 ;
500 psf->strings.flags = SF_STR_ALLOW_START ;
501 } ;
502
503 psf->seek = vorbis_seek ;
504 psf->command = vorbis_command ;
505 psf->byterate = vorbis_byterate ;
506 psf->sf.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS ;
507 psf->sf.sections = 1 ;
508
509 return error ;
510 } /* ogg_vorbis_open */
511
512 static int
vorbis_command(SF_PRIVATE * psf,int command,void * data,int datasize)513 vorbis_command (SF_PRIVATE *psf, int command, void * data, int datasize)
514 { OGG_PRIVATE* odata = psf->container_data ;
515 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
516
517 switch (command)
518 { case SFC_SET_COMPRESSION_LEVEL :
519 if (data == NULL || datasize != sizeof (double))
520 return SF_FALSE ;
521
522 if (psf->have_written)
523 return SF_FALSE ;
524
525 vdata->quality = 1.0 - *((double *) data) ;
526
527 /* Clip range. */
528 vdata->quality = SF_MAX (0.0, SF_MIN (1.0, vdata->quality)) ;
529
530 psf_log_printf (psf, "%s : Setting SFC_SET_VBR_ENCODING_QUALITY to %f.\n", __func__, vdata->quality) ;
531 return SF_TRUE ;
532
533 case SFC_GET_OGG_STREAM_SERIALNO :
534 if (data == NULL || datasize != sizeof (int32_t))
535 return SF_FALSE ;
536
537 *((int32_t *) data) = odata->ostream.serialno ;
538 return SF_TRUE ;
539
540 default :
541 return SF_FALSE ;
542 } ;
543
544 return SF_FALSE ;
545 } /* vorbis_command */
546
547 static int
vorbis_rnull(SF_PRIVATE * UNUSED (psf),int samples,void * UNUSED (vptr),int UNUSED (off),int channels,float ** UNUSED (pcm))548 vorbis_rnull (SF_PRIVATE *UNUSED (psf), int samples, void *UNUSED (vptr), int UNUSED (off) , int channels, float **UNUSED (pcm))
549 {
550 return samples * channels ;
551 } /* vorbis_rnull */
552
553 static int
vorbis_rshort(SF_PRIVATE * psf,int samples,void * vptr,int off,int channels,float ** pcm)554 vorbis_rshort (SF_PRIVATE *psf, int samples, void *vptr, int off, int channels, float **pcm)
555 {
556 short *ptr = (short*) vptr + off ;
557 int i = 0, j, n ;
558 if (psf->float_int_mult)
559 {
560 float inverse = 1.0 / psf->float_max ;
561 for (j = 0 ; j < samples ; j++)
562 for (n = 0 ; n < channels ; n++)
563 ptr [i++] = psf_lrintf ((pcm [n][j] * inverse) * 32767.0f) ;
564 }
565 else
566 {
567 for (j = 0 ; j < samples ; j++)
568 for (n = 0 ; n < channels ; n++)
569 ptr [i++] = psf_lrintf (pcm [n][j] * 32767.0f) ;
570 }
571 return i ;
572 } /* vorbis_rshort */
573
574 static int
vorbis_rint(SF_PRIVATE * psf,int samples,void * vptr,int off,int channels,float ** pcm)575 vorbis_rint (SF_PRIVATE *psf, int samples, void *vptr, int off, int channels, float **pcm)
576 {
577 int *ptr = (int*) vptr + off ;
578 int i = 0, j, n ;
579
580 if (psf->float_int_mult)
581 {
582 float inverse = 1.0 / psf->float_max ;
583 for (j = 0 ; j < samples ; j++)
584 for (n = 0 ; n < channels ; n++)
585 ptr [i++] = psf_lrintf ((pcm [n][j] * inverse) * 2147483647.0f) ;
586 }
587 else
588 {
589 for (j = 0 ; j < samples ; j++)
590 for (n = 0 ; n < channels ; n++)
591 ptr [i++] = psf_lrintf (pcm [n][j] * 2147483647.0f) ;
592 }
593 return i ;
594 } /* vorbis_rint */
595
596 static int
vorbis_rfloat(SF_PRIVATE * UNUSED (psf),int samples,void * vptr,int off,int channels,float ** pcm)597 vorbis_rfloat (SF_PRIVATE *UNUSED (psf), int samples, void *vptr, int off, int channels, float **pcm)
598 {
599 float *ptr = (float*) vptr + off ;
600 int i = 0, j, n ;
601 for (j = 0 ; j < samples ; j++)
602 for (n = 0 ; n < channels ; n++)
603 ptr [i++] = pcm [n][j] ;
604 return i ;
605 } /* vorbis_rfloat */
606
607 static int
vorbis_rdouble(SF_PRIVATE * UNUSED (psf),int samples,void * vptr,int off,int channels,float ** pcm)608 vorbis_rdouble (SF_PRIVATE *UNUSED (psf), int samples, void *vptr, int off, int channels, float **pcm)
609 {
610 double *ptr = (double*) vptr + off ;
611 int i = 0, j, n ;
612 for (j = 0 ; j < samples ; j++)
613 for (n = 0 ; n < channels ; n++)
614 ptr [i++] = pcm [n][j] ;
615 return i ;
616 } /* vorbis_rdouble */
617
618
619 static sf_count_t
vorbis_read_sample(SF_PRIVATE * psf,void * ptr,sf_count_t lens,convert_func * transfn)620 vorbis_read_sample (SF_PRIVATE *psf, void *ptr, sf_count_t lens, convert_func *transfn)
621 { VORBIS_PRIVATE *vdata = psf->codec_data ;
622 OGG_PRIVATE *odata = psf->container_data ;
623 int len, samples, i = 0 , nn ;
624 float **pcm ;
625
626 len = lens / psf->sf.channels ;
627
628 while (len > 0)
629 { /*
630 ** pcm is a multichannel float vector. In stereo, for
631 ** example, pcm [0] is left, and pcm [1] is right. samples is
632 ** the size of each channel. Convert the float values
633 ** (-1.<=range<=1.) to whatever PCM format and write it out.
634 */
635 while ((samples = vorbis_synthesis_pcmout (&vdata->vdsp, &pcm)) > 0)
636 { if (samples > len) samples = len ;
637 i += transfn (psf, samples, ptr, i, psf->sf.channels, pcm) ;
638 len -= samples ;
639 /* tell libvorbis how many samples we actually consumed */
640 vorbis_synthesis_read (&vdata->vdsp, samples) ;
641 vdata->gp += samples ;
642 if (len == 0)
643 return i ;
644 } ;
645
646 /* Out of samples, load the next packet. */
647 if (odata->pkt_indx == odata->pkt_len)
648 { /* Page out of packets, load and unpack the next page. */
649 nn = ogg_stream_unpack_page (psf, odata) ;
650 if (nn <= 0)
651 return i ;
652 if (nn == 2)
653 { /* Ran over a hole. gp is now out of date, need to recalculate. */
654 vorbis_synthesis_restart (&vdata->vdsp) ;
655 vorbis_calculate_granulepos (psf, &vdata->gp) ;
656 }
657 } ;
658
659 /* Decode the packet */
660 if (vorbis_synthesis (&vdata->vblock, &(odata->pkt [odata->pkt_indx])) == 0) /* test for success! */
661 vorbis_synthesis_blockin (&vdata->vdsp, &vdata->vblock) ;
662 odata->pkt_indx++ ;
663 } ;
664
665 return i ;
666 } /* vorbis_read_sample */
667
668 static sf_count_t
vorbis_read_s(SF_PRIVATE * psf,short * ptr,sf_count_t lens)669 vorbis_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t lens)
670 { return vorbis_read_sample (psf, (void*) ptr, lens, vorbis_rshort) ;
671 } /* vorbis_read_s */
672
673 static sf_count_t
vorbis_read_i(SF_PRIVATE * psf,int * ptr,sf_count_t lens)674 vorbis_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t lens)
675 { return vorbis_read_sample (psf, (void*) ptr, lens, vorbis_rint) ;
676 } /* vorbis_read_i */
677
678 static sf_count_t
vorbis_read_f(SF_PRIVATE * psf,float * ptr,sf_count_t lens)679 vorbis_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t lens)
680 { return vorbis_read_sample (psf, (void*) ptr, lens, vorbis_rfloat) ;
681 } /* vorbis_read_f */
682
683 static sf_count_t
vorbis_read_d(SF_PRIVATE * psf,double * ptr,sf_count_t lens)684 vorbis_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t lens)
685 { return vorbis_read_sample (psf, (void*) ptr, lens, vorbis_rdouble) ;
686 } /* vorbis_read_d */
687
688 /*==============================================================================
689 */
690
691 static void
vorbis_write_samples(SF_PRIVATE * psf,OGG_PRIVATE * odata,VORBIS_PRIVATE * vdata,int in_frames)692 vorbis_write_samples (SF_PRIVATE *psf, OGG_PRIVATE *odata, VORBIS_PRIVATE *vdata, int in_frames)
693 {
694 vorbis_analysis_wrote (&vdata->vdsp, in_frames) ;
695
696 /*
697 ** Vorbis does some data preanalysis, then divvies up blocks for
698 ** more involved (potentially parallel) processing. Get a single
699 ** block for encoding now.
700 */
701 while (vorbis_analysis_blockout (&vdata->vdsp, &vdata->vblock) == 1)
702 {
703 /* analysis, assume we want to use bitrate management */
704 vorbis_analysis (&vdata->vblock, NULL) ;
705 vorbis_bitrate_addblock (&vdata->vblock) ;
706
707 while (vorbis_bitrate_flushpacket (&vdata->vdsp, &odata->opacket))
708 {
709 /* weld the packet into the bitstream */
710 ogg_stream_packetin (&odata->ostream, &odata->opacket) ;
711
712 /* write out pages (if any) */
713 while (!odata->eos)
714 { int result = ogg_stream_pageout (&odata->ostream, &odata->opage) ;
715 if (result == 0)
716 break ;
717 ogg_write_page (psf, &odata->opage) ;
718
719 /* This could be set above, but for illustrative purposes, I do
720 ** it here (to show that vorbis does know where the stream ends) */
721 if (ogg_page_eos (&odata->opage))
722 odata->eos = 1 ;
723 } ;
724 } ;
725 } ;
726
727 vdata->gp += in_frames ;
728 } /* vorbis_write_data */
729
730
731 static sf_count_t
vorbis_write_s(SF_PRIVATE * psf,const short * ptr,sf_count_t lens)732 vorbis_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t lens)
733 {
734 int i, m, j = 0 ;
735 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
736 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
737 int in_frames = lens / psf->sf.channels ;
738 float **buffer = vorbis_analysis_buffer (&vdata->vdsp, in_frames) ;
739 for (i = 0 ; i < in_frames ; i++)
740 for (m = 0 ; m < psf->sf.channels ; m++)
741 buffer [m][i] = (float) (ptr [j++]) / 32767.0f ;
742
743 vorbis_write_samples (psf, odata, vdata, in_frames) ;
744
745 return lens ;
746 } /* vorbis_write_s */
747
748 static sf_count_t
vorbis_write_i(SF_PRIVATE * psf,const int * ptr,sf_count_t lens)749 vorbis_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t lens)
750 { int i, m, j = 0 ;
751 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
752 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
753 int in_frames = lens / psf->sf.channels ;
754 float **buffer = vorbis_analysis_buffer (&vdata->vdsp, in_frames) ;
755 for (i = 0 ; i < in_frames ; i++)
756 for (m = 0 ; m < psf->sf.channels ; m++)
757 buffer [m][i] = (float) (ptr [j++]) / 2147483647.0f ;
758
759 vorbis_write_samples (psf, odata, vdata, in_frames) ;
760
761 return lens ;
762 } /* vorbis_write_i */
763
764 static sf_count_t
vorbis_write_f(SF_PRIVATE * psf,const float * ptr,sf_count_t lens)765 vorbis_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t lens)
766 { int i, m, j = 0 ;
767 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
768 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
769 int in_frames = lens / psf->sf.channels ;
770 float **buffer = vorbis_analysis_buffer (&vdata->vdsp, in_frames) ;
771 for (i = 0 ; i < in_frames ; i++)
772 for (m = 0 ; m < psf->sf.channels ; m++)
773 buffer [m][i] = ptr [j++] ;
774
775 vorbis_write_samples (psf, odata, vdata, in_frames) ;
776
777 return lens ;
778 } /* vorbis_write_f */
779
780 static sf_count_t
vorbis_write_d(SF_PRIVATE * psf,const double * ptr,sf_count_t lens)781 vorbis_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t lens)
782 { int i, m, j = 0 ;
783 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
784 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
785 int in_frames = lens / psf->sf.channels ;
786 float **buffer = vorbis_analysis_buffer (&vdata->vdsp, in_frames) ;
787 for (i = 0 ; i < in_frames ; i++)
788 for (m = 0 ; m < psf->sf.channels ; m++)
789 buffer [m][i] = (float) ptr [j++] ;
790
791 vorbis_write_samples (psf, odata, vdata, in_frames) ;
792
793 return lens ;
794 } /* vorbis_write_d */
795
796 static int
vorbis_skip(SF_PRIVATE * psf,uint64_t target)797 vorbis_skip (SF_PRIVATE *psf, uint64_t target)
798 { OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
799 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
800 ogg_packet *pkt ;
801 int thisblock, lastblock, nn ;
802 const int blocksize = vorbis_info_blocksize (&vdata->vinfo, 1) ;
803
804 /* Read out any samples that may be in the decoder from a seek without a
805 ** search. */
806 thisblock = vorbis_synthesis_pcmout (&vdata->vdsp, NULL) ;
807 if (thisblock > 0)
808 { if ((uint64_t) thisblock + vdata->gp >= target)
809 thisblock = SF_MIN (thisblock, (int) (target - vdata->gp)) ;
810
811 vorbis_synthesis_read (&vdata->vdsp, thisblock) ;
812 vdata->gp += thisblock ;
813 if (vdata->gp == target)
814 return 0 ;
815 } ;
816
817 /* Read through packets that are before our target */
818 lastblock = 0 ;
819 for ( ; vdata->gp < target ; )
820 { /* Ensure there are unpacked packets. */
821 if (odata->pkt_indx == odata->pkt_len)
822 { /* Page out of packets, load and unpack the next page. */
823 nn = ogg_stream_unpack_page (psf, odata) ;
824 if (nn < 0)
825 return nn ;
826 if (nn == 0)
827 break ;
828 if (nn == 2)
829 { /* Ran over a hole. gp is now out of date, need to recalculate. */
830 vorbis_synthesis_restart (&vdata->vdsp) ;
831 vorbis_calculate_granulepos (psf, &vdata->gp) ;
832 if (target < vdata->gp)
833 { /* Our target is inside the hole :-( */
834 return 0 ;
835 } ;
836 } ;
837 } ;
838
839 pkt = &odata->pkt [odata->pkt_indx] ;
840 thisblock = vorbis_packet_blocksize (&vdata->vinfo, pkt) ;
841 if (thisblock < 0)
842 { /* Not an audio packet */
843 odata->pkt_indx++ ;
844 continue ;
845 } ;
846
847 if (lastblock)
848 { vdata->gp += ((lastblock + thisblock) / 4) ;
849 } ;
850
851 /* Check to see if the block contains our target */
852 if (vdata->gp + ((thisblock + blocksize) / 4) >= target)
853 break ;
854
855 /* Block is before the target. Track for state, but don't decode. */
856 odata->pkt_indx++ ;
857 vorbis_synthesis_trackonly (&vdata->vblock, pkt) ;
858 vorbis_synthesis_blockin (&vdata->vdsp, &vdata->vblock) ;
859 lastblock = thisblock ;
860 } ;
861
862 /* We are at the correct block, but still need to consume samples to reach
863 ** our target. */
864 vorbis_read_sample (psf, (void *) NULL, (target - vdata->gp) * psf->sf.channels, vorbis_rnull) ;
865
866 return 0 ;
867 } /* vorbis_skip */
868
869 static int
vorbis_seek_trysearch(SF_PRIVATE * psf,uint64_t target_gp)870 vorbis_seek_trysearch (SF_PRIVATE *psf, uint64_t target_gp)
871 { OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
872 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
873 uint64_t best_gp, search_target_gp ;
874 int ret ;
875
876 /* Can't bisect a file we don't know the end of (cannot seek). */
877 if (vdata->pcm_end == (uint64_t) -1)
878 return 0 ;
879
880 /* If the target is for the near future, don't bother bisecting, just skip
881 ** to it. */
882 if (target_gp >= vdata->gp &&
883 target_gp - vdata->gp < ((unsigned) (VORBIS_SEEK_THRESHOLD) * psf->sf.samplerate))
884 return 0 ;
885
886 /* Search for a position a half large-block before our target. As Vorbis is
887 ** lapped, every sample position come from two blocks, the "left" half of
888 ** one block and the "right" half of the previous block. The granule
889 ** position of an Ogg page of a Vorbis stream is the sample offset of the
890 ** last finished sample in the stream that can be decoded from a page. A
891 ** page also contains another half-block of samples waiting to be lapped
892 ** with the first half-block of samples from the next page.
893 **
894 ** Searching for a sample one half of a large block before our target
895 ** guarantees we always load a page containing the previous half block
896 ** required to decode the target. Downside is we can't use best_gp
897 ** parameter of the page seek function. */
898 search_target_gp = vorbis_info_blocksize (&vdata->vinfo, 1) / 2 ;
899 search_target_gp = search_target_gp < target_gp ? target_gp - search_target_gp : 0 ;
900
901 ret = ogg_stream_seek_page_search (psf, odata, search_target_gp, vdata->pcm_start,
902 vdata->pcm_end, &best_gp, psf->dataoffset, vdata->last_page, vdata->vinfo.rate) ;
903 if (ret < 0)
904 return ret ;
905
906 ret = ogg_stream_unpack_page (psf, odata) ;
907 if (ret > 0)
908 { /* Reset the decoder, recalculate position */
909 vorbis_synthesis_restart (&vdata->vdsp) ;
910 ret = vorbis_calculate_granulepos (psf, &vdata->gp) ;
911 } ;
912
913 return ret ;
914 } /* vorbis_seek_trysearch */
915
916 static sf_count_t
vorbis_seek(SF_PRIVATE * psf,int UNUSED (mode),sf_count_t offset)917 vorbis_seek (SF_PRIVATE *psf, int UNUSED (mode), sf_count_t offset)
918 { OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
919 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
920 uint64_t target_gp ;
921 int ret ;
922
923 if (odata == NULL || vdata == NULL)
924 return 0 ;
925
926 if (offset < 0)
927 { psf->error = SFE_BAD_SEEK ;
928 return ((sf_count_t) -1) ;
929 } ;
930
931 if (psf->file.mode == SFM_READ)
932 { target_gp = (uint64_t) offset + vdata->pcm_start ;
933
934 ret = vorbis_seek_trysearch (psf, target_gp) ;
935
936 if (ret < 0 || vdata->gp > target_gp)
937 { /* Search failed (bad data?), reset to the beginning of the stream. */
938 psf_log_printf (psf, "Vorbis: Seek search failed. Reading through stream from start.\n") ;
939 ogg_stream_reset_serialno (&odata->ostream, odata->ostream.serialno) ;
940 odata->pkt_len = 0 ;
941 odata->pkt_indx = 0 ;
942 ogg_sync_fseek (psf, psf->dataoffset, SEEK_SET) ;
943 vdata->gp = vdata->pcm_start ;
944 vorbis_synthesis_restart (&vdata->vdsp) ;
945 } ;
946
947 vorbis_skip (psf, target_gp) ;
948
949 return vdata->gp - vdata->pcm_start ;
950 } ;
951
952 psf->error = SFE_BAD_SEEK ;
953 return ((sf_count_t) -1) ;
954 } /* vorbis_seek */
955
956 static int
vorbis_byterate(SF_PRIVATE * psf)957 vorbis_byterate (SF_PRIVATE *psf)
958 {
959 if (psf->file.mode == SFM_READ)
960 return (psf->datalength * psf->sf.samplerate) / psf->sf.frames ;
961
962 return -1 ;
963 } /* vorbis_byterate */
964
965 static int
vorbis_calculate_granulepos(SF_PRIVATE * psf,uint64_t * gp_out)966 vorbis_calculate_granulepos (SF_PRIVATE *psf, uint64_t *gp_out)
967 { OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
968 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
969 ogg_packet *pkt ;
970 uint64_t last_gp ;
971 int thisblock, lastblock, i ;
972 unsigned duration ;
973
974 /* Calculate the granule position when dropped into the middle of a stream
975 ** with an un-primed decoder.
976 **
977 ** Normally the last unpacked packet contains the granule position of the
978 ** last completed sample from decoding all the blocks in the page's
979 ** packets. By calculating how many samples we can decode from the blocks
980 ** in the page's packets and subtracting it from the final packet's granule
981 ** position we get the position of the first sample to be output from the
982 ** decoder after it primes. That is, the current granule position.
983 **
984 ** However, there is an ambiguity if this is the last page of a stream. The
985 ** last page of a stream may have a granule position of fewer samples than
986 ** the page actually contains. The excess samples are padding leftovers
987 ** for and exact sample length file. */
988
989 if (odata->pkt_len > 0)
990 { /* Calculate how many samples can be decoded from blocks in this page,
991 ** accounting for the fact that blocks are 1/2 lapped. */
992 lastblock = -1 ;
993 duration = 0 ;
994 pkt = odata->pkt ;
995 for (i = 0 ; i < odata->pkt_len ; i++)
996 { thisblock = vorbis_packet_blocksize (&vdata->vinfo, &pkt [i]) ;
997 if (thisblock >= 0)
998 { if (lastblock != -1)
999 duration += (lastblock + thisblock) >> 2 ;
1000 lastblock = thisblock ;
1001 } ;
1002 } ;
1003
1004 pkt = &odata->pkt [odata->pkt_len - 1] ;
1005 last_gp = pkt->granulepos ;
1006 if (last_gp == (uint64_t) -1)
1007 { psf_log_printf (psf, "Vorbis: Ogg page has no granule position, cannot calculate sample position!\n") ;
1008 psf->error = SFE_MALFORMED_FILE ;
1009 return -1 ;
1010 } ;
1011
1012 if (pkt->e_o_s)
1013 { if (last_gp <= duration)
1014 { /* Corner case: One page stream. Ogg/Vorbis spec dictates the
1015 ** granule position offset MUST be zero, hence this first (and
1016 ** only) page must start at 0. */
1017 *gp_out = 0 ;
1018 return 1 ;
1019 } ;
1020
1021 /* Otherwise, we cannot know where we are without looking at the
1022 ** blocks of the previous page. (The granule position of the
1023 ** previous page is not enough, we need the block sizes.)
1024 **
1025 ** We avoid this case by never allowing a bisection search to seek
1026 ** beyond the second-to-last page, so the last page is always
1027 ** approached with a known location and never dropped into.
1028 **
1029 ** The only way we should be able to end up here is if there was a
1030 ** hole in stream just before the last page, in which case all bets
1031 ** are off anyways. */
1032 psf_log_printf (psf, "Vorbis: Cannot calculate ambiguous last page duration. Sample count may be wrong.\n") ;
1033 } ;
1034
1035 if (last_gp < duration)
1036 { psf_log_printf (psf, "Vorbis: Granule position is nonsensical! (Missing end-of-stream marker?)\n") ;
1037 psf->error = SFE_MALFORMED_FILE ;
1038 return -1 ;
1039 } ;
1040
1041 *gp_out = last_gp - duration ;
1042 return 1 ;
1043 } ;
1044
1045 return 0 ;
1046 } /* vorbis_calculate_granulepos */
1047
1048 #else /* HAVE_EXTERNAL_XIPH_LIBS */
1049
1050 int
ogg_vorbis_open(SF_PRIVATE * psf)1051 ogg_vorbis_open (SF_PRIVATE *psf)
1052 {
1053 psf_log_printf (psf, "This version of libsndfile was compiled without Ogg/Vorbis support.\n") ;
1054 return SFE_UNIMPLEMENTED ;
1055 } /* ogg_vorbis_open */
1056
1057 #endif
1058