xref: /third_party/libsnd/src/ogg_vorbis.c (revision b815c7f3)
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
85typedef int convert_func (SF_PRIVATE *psf, int, void *, int, int, float **) ;
86
87static int	vorbis_read_header (SF_PRIVATE *psf) ;
88static int	vorbis_write_header (SF_PRIVATE *psf, int calc_length) ;
89static int	vorbis_close (SF_PRIVATE *psf) ;
90static int	vorbis_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
91static int	vorbis_byterate (SF_PRIVATE *psf) ;
92static int	vorbis_calculate_granulepos (SF_PRIVATE *psf, uint64_t *gp_out) ;
93static int	vorbis_skip (SF_PRIVATE *psf, uint64_t target_gp) ;
94static int	vorbis_seek_trysearch (SF_PRIVATE *psf, uint64_t target_gp) ;
95static sf_count_t	vorbis_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
96static sf_count_t	vorbis_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
97static sf_count_t	vorbis_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
98static sf_count_t	vorbis_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
99static sf_count_t	vorbis_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
100static sf_count_t	vorbis_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
101static sf_count_t	vorbis_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
102static sf_count_t	vorbis_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
103static sf_count_t	vorbis_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
104static sf_count_t	vorbis_read_sample (SF_PRIVATE *psf, void *ptr, sf_count_t lens, convert_func *transfn) ;
105static int	vorbis_rnull (SF_PRIVATE *psf, int samples, void *vptr, int off , int channels, float **pcm) ;
106
107typedef struct
108{	int id ;
109	const char *name ;
110} STR_PAIRS ;
111
112
113/* See https://xiph.org/vorbis/doc/v-comment.html */
114static 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
127typedef 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
148static int
149vorbis_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
309static int
310vorbis_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
401static int
402vorbis_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
455int
456ogg_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
512static int
513vorbis_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
547static int
548vorbis_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
553static int
554vorbis_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
574static int
575vorbis_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
596static int
597vorbis_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
607static int
608vorbis_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
619static sf_count_t
620vorbis_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
668static sf_count_t
669vorbis_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
673static sf_count_t
674vorbis_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
678static sf_count_t
679vorbis_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
683static sf_count_t
684vorbis_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
691static void
692vorbis_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
731static sf_count_t
732vorbis_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
748static sf_count_t
749vorbis_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
764static sf_count_t
765vorbis_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
780static sf_count_t
781vorbis_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
796static int
797vorbis_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
869static int
870vorbis_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
916static sf_count_t
917vorbis_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
956static int
957vorbis_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
965static int
966vorbis_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
1050int
1051ogg_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