1
/*
2
 * Copyright 2008-2011 Various Authors
3
 * Copyright 2004-2005 Timo Hirvonen
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License as
7
 * published by the Free Software Foundation; either version 2 of the
8
 * License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful, but
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17
 */
18
19
#include "ip.h"
20
#include "xmalloc.h"
21
#include "read_wrapper.h"
22
#include "debug.h"
23
#ifdef HAVE_CONFIG
24
#include "config/tremor.h"
25
#endif
26
#include "comment.h"
27
28
#ifdef CONFIG_TREMOR
29
#include <tremor/ivorbisfile.h>
30
#else
31
#include <vorbis/vorbisfile.h>
32
#endif
33
34
#include <errno.h>
35
#include <string.h>
36
#include <sys/types.h>
37
#include <unistd.h>
38
#include <math.h>
39
40
struct vorbis_private {
41
	OggVorbis_File vf;
42
	int current_section;
43
};
44
45
/* http://www.xiph.org/vorbis/doc/vorbisfile/callbacks.html */
46
47
static size_t read_func(void *ptr, size_t size, size_t nmemb, void *datasource)
48
{
49
	struct input_plugin_data *ip_data = datasource;
50
	int rc;
51
52
	rc = read_wrapper(ip_data, ptr, size * nmemb);
53
	if (rc == -1) {
54
		d_print("error: %s\n", strerror(errno));
55
		return 0;
56
	}
57
	if (rc == 0) {
58
		errno = 0;
59
		return 0;
60
	}
61
	return rc / size;
62
}
63
64
static int seek_func(void *datasource, ogg_int64_t offset, int whence)
65
{
66
	struct input_plugin_data *ip_data = datasource;
67
68
	if (lseek(ip_data->fd, offset, whence) == -1)
69
		return -1;
70
	return 0;
71
}
72
73
static int close_func(void *datasource)
74
{
75
	struct input_plugin_data *ip_data = datasource;
76
	int rc;
77
78
	rc = close(ip_data->fd);
79
	ip_data->fd = -1;
80
	return rc;
81
}
82
83
static long tell_func(void *datasource)
84
{
85
	struct input_plugin_data *ip_data = datasource;
86
	off_t off;
87
88
	off = lseek(ip_data->fd, 0, SEEK_CUR);
89
	return (off == -1) ? -1 : off;
90
}
91
92
/*
93
 * typedef struct {
94
 *   size_t (*read_func)  (void *ptr, size_t size, size_t nmemb, void *datasource);
95
 *   int    (*seek_func)  (void *datasource, ogg_int64_t offset, int whence);
96
 *   int    (*close_func) (void *datasource);
97
 *   long   (*tell_func)  (void *datasource);
98
 * } ov_callbacks;
99
 */
100
static ov_callbacks callbacks = {
101
	.read_func = read_func,
102
	.seek_func = seek_func,
103
	.close_func = close_func,
104
	.tell_func = tell_func
105
};
106
107
/* http://xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-800004.3.9 */
108
static void channel_map_init_vorbis(int channels, channel_position_t *map)
109
{
110
	switch (channels) {
111
	case 8:
112
		channel_map_init_vorbis(7, map);
113
		map[5] = CHANNEL_POSITION_REAR_LEFT;
114
		map[6] = CHANNEL_POSITION_REAR_RIGHT;
115
		map[7] = CHANNEL_POSITION_LFE;
116
		break;
117
	case 7:
118
		channel_map_init_vorbis(3, map);
119
		map[3] = CHANNEL_POSITION_SIDE_LEFT;
120
		map[4] = CHANNEL_POSITION_SIDE_RIGHT;
121
		map[5] = CHANNEL_POSITION_REAR_CENTER;
122
		map[6] = CHANNEL_POSITION_LFE;
123
		break;
124
	case 6:
125
		map[5] = CHANNEL_POSITION_LFE;
126
		/* Fall through */
127
	case 5:
128
		map[3] = CHANNEL_POSITION_REAR_LEFT;
129
		map[4] = CHANNEL_POSITION_REAR_RIGHT;
130
		/* Fall through */
131
	case 3:
132
		map[0] = CHANNEL_POSITION_FRONT_LEFT;
133
		map[1] = CHANNEL_POSITION_CENTER;
134
		map[2] = CHANNEL_POSITION_FRONT_RIGHT;
135
		break;
136
	case 4:
137
		map[2] = CHANNEL_POSITION_REAR_LEFT;
138
		map[3] = CHANNEL_POSITION_REAR_RIGHT;
139
		/* Fall through */
140
	case 2:
141
		map[0] = CHANNEL_POSITION_FRONT_LEFT;
142
		map[1] = CHANNEL_POSITION_FRONT_RIGHT;
143
		break;
144
	case 1:
145
		map[0] = CHANNEL_POSITION_MONO;
146
		break;
147
	default:
148
		map[0] = CHANNEL_POSITION_INVALID;
149
		break;
150
	}
151
}
152
153
static int vorbis_open(struct input_plugin_data *ip_data)
154
{
155
	struct vorbis_private *priv;
156
	vorbis_info *vi;
157
	int rc;
158
159
	priv = xnew(struct vorbis_private, 1);
160
	priv->current_section = -1;
161
	memset(&priv->vf, 0, sizeof(priv->vf));
162
163
	rc = ov_open_callbacks(ip_data, &priv->vf, NULL, 0, callbacks);
164
	if (rc != 0) {
165
		d_print("ov_open failed: %d\n", rc);
166
		free(priv);
167
		/* ogg is a container format, so it is likely to contain
168
		 * something else if it isn't vorbis */
169
		return -IP_ERROR_UNSUPPORTED_FILE_TYPE;
170
	}
171
	ip_data->private = priv;
172
173
	vi = ov_info(&priv->vf, -1);
174
	ip_data->sf = sf_rate(vi->rate) | sf_channels(vi->channels) | sf_bits(16) | sf_signed(1);
175
#ifdef WORDS_BIGENDIAN
176
	ip_data->sf |= sf_bigendian(1);
177
#endif
178
	channel_map_init_vorbis(vi->channels, ip_data->channel_map);
179
	return 0;
180
}
181
182
static int vorbis_close(struct input_plugin_data *ip_data)
183
{
184
	struct vorbis_private *priv;
185
	int rc;
186
187
	priv = ip_data->private;
188
	/* this closes ip_data->fd! */
189
	rc = ov_clear(&priv->vf);
190
	ip_data->fd = -1;
191
	if (rc)
192
		d_print("ov_clear returned %d\n", rc);
193
	free(priv);
194
	ip_data->private = NULL;
195
	return 0;
196
}
197
198
static inline int vorbis_endian(void)
199
{
200
#ifdef WORDS_BIGENDIAN
201
	return 1;
202
#else
203
	return 0;
204
#endif
205
}
206
207
/*
208
 * OV_HOLE
209
 *     indicates there was an interruption in the data.
210
 *     (one of: garbage between pages, loss of sync followed by recapture,
211
 *     or a corrupt page)
212
 * OV_EBADLINK
213
 *     indicates that an invalid stream section was supplied to libvorbisfile,
214
 *     or the requested link is corrupt.
215
 * 0
216
 *     indicates EOF
217
 * n
218
 *     indicates actual number of bytes read. ov_read() will decode at most
219
 *     one vorbis packet per invocation, so the value returned will generally
220
 *     be less than length.
221
 */
222
static int vorbis_read(struct input_plugin_data *ip_data, char *buffer, int count)
223
{
224
	struct vorbis_private *priv;
225
	int rc;
226
	int current_section;
227
228
	priv = ip_data->private;
229
#ifdef CONFIG_TREMOR
230
	/* Tremor can only handle signed 16 bit data */
231
	rc = ov_read(&priv->vf, buffer, count, &current_section);
232
#else
233
	rc = ov_read(&priv->vf, buffer, count, vorbis_endian(), 2, 1, &current_section);
234
#endif
235
236
	if (ip_data->remote && current_section != priv->current_section) {
237
		ip_data->metadata_changed = 1;
238
		priv->current_section = current_section;
239
	}
240
241
	switch (rc) {
242
	case OV_HOLE:
243
		errno = EAGAIN;
244
		return -1;
245
	case OV_EBADLINK:
246
		errno = EINVAL;
247
		return -1;
248
	case OV_EINVAL:
249
		errno = EINVAL;
250
		return -1;
251
	case 0:
252
		if (errno) {
253
			d_print("error: %s\n", strerror(errno));
254
			return -1;
255
/* 			return -IP_ERROR_INTERNAL; */
256
		}
257
		/* EOF */
258
		return 0;
259
	default:
260
		if (rc < 0) {
261
			d_print("error: %d\n", rc);
262
			rc = -IP_ERROR_FILE_FORMAT;
263
		}
264
		return rc;
265
	}
266
}
267
268
static int vorbis_seek(struct input_plugin_data *ip_data, double offset)
269
{
270
	struct vorbis_private *priv;
271
	int rc;
272
273
	priv = ip_data->private;
274
275
#ifdef CONFIG_TREMOR
276
	rc = ov_time_seek(&priv->vf, offset * 1000);
277
#else
278
	rc = ov_time_seek(&priv->vf, offset);
279
#endif
280
	switch (rc) {
281
	case OV_ENOSEEK:
282
		return -IP_ERROR_FUNCTION_NOT_SUPPORTED;
283
	case OV_EINVAL:
284
		return -IP_ERROR_INTERNAL;
285
	case OV_EREAD:
286
		return -IP_ERROR_INTERNAL;
287
	case OV_EFAULT:
288
		return -IP_ERROR_INTERNAL;
289
	case OV_EBADLINK:
290
		return -IP_ERROR_INTERNAL;
291
	}
292
	return 0;
293
}
294
295
static int vorbis_read_comments(struct input_plugin_data *ip_data,
296
		struct keyval **comments)
297
{
298
	GROWING_KEYVALS(c);
299
	struct vorbis_private *priv;
300
	vorbis_comment *vc;
301
	int i;
302
303
	priv = ip_data->private;
304
	vc = ov_comment(&priv->vf, -1);
305
	if (vc == NULL) {
306
		d_print("vc == NULL\n");
307
		*comments = keyvals_new(0);
308
		return 0;
309
	}
310
	for (i = 0; i < vc->comments; i++) {
311
		const char *str = vc->user_comments[i];
312
		const char *eq = strchr(str, '=');
313
		char *key;
314
315
		if (!eq) {
316
			d_print("invalid comment: '%s' ('=' expected)\n", str);
317
			continue;
318
		}
319
320
		key = xstrndup(str, eq - str);
321
		comments_add_const(&c, key, eq + 1);
322
		free(key);
323
	}
324
	keyvals_terminate(&c);
325
	*comments = c.keyvals;
326
	return 0;
327
}
328
329
static int vorbis_duration(struct input_plugin_data *ip_data)
330
{
331
	struct vorbis_private *priv;
332
	int duration;
333
334
	priv = ip_data->private;
335
	duration = ov_time_total(&priv->vf, -1);
336
	if (duration == OV_EINVAL)
337
		return -IP_ERROR_FUNCTION_NOT_SUPPORTED;
338
#ifdef CONFIG_TREMOR
339
	duration = (duration + 500) / 1000;
340
#endif
341
	return duration;
342
}
343
344
static long vorbis_bitrate(struct input_plugin_data *ip_data)
345
{
346
	struct vorbis_private *priv = ip_data->private;
347
	long bitrate = ov_bitrate(&priv->vf, -1);
348
	if (bitrate == OV_EINVAL || bitrate == OV_FALSE)
349
		return -IP_ERROR_FUNCTION_NOT_SUPPORTED;
350
	return bitrate;
351
}
352
353
static long vorbis_current_bitrate(struct input_plugin_data *ip_data)
354
{
355
	struct vorbis_private *priv = ip_data->private;
356
	return ov_bitrate_instant(&priv->vf);
357
}
358
359
static char *vorbis_codec(struct input_plugin_data *ip_data)
360
{
361
	return xstrdup("vorbis");
362
}
363
364
static const long rate_mapping_44[2][12] = {
365
	{ 32000, 48000, 60000, 70000,  80000,  86000,  96000, 110000, 120000, 140000, 160000, 239920 },
366
	{ 45000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 499821 }
367
};
368
369
static char *vorbis_codec_profile(struct input_plugin_data *ip_data)
370
{
371
	struct vorbis_private *priv = ip_data->private;
372
	vorbis_info *vi = ov_info(&priv->vf, -1);
373
	long b = vi->bitrate_nominal;
374
	char buf[64];
375
376
	if (b <= 0)
377
		return NULL;
378
379
	if (vi->channels > 2 || vi->rate < 44100) {
380
		sprintf(buf, "%ldkbps", b / 1000);
381
	} else {
382
		const long *map = rate_mapping_44[vi->channels - 1];
383
		float q;
384
		int i;
385
386
		for (i = 0; i < 12-1; i++) {
387
			if (b >= map[i] && b < map[i+1])
388
				break;
389
		}
390
		/* This is used even if upper / lower bitrate are set
391
		 * because it gives a good approximation. */
392
		q = (i - 1) + (float) (b - map[i]) / (map[i+1] - map[i]);
393
		sprintf(buf, "q%g", roundf(q * 100.f) / 100.f);
394
	}
395
396
	return xstrdup(buf);
397
}
398
399
const struct input_plugin_ops ip_ops = {
400
	.open = vorbis_open,
401
	.close = vorbis_close,
402
	.read = vorbis_read,
403
	.seek = vorbis_seek,
404
	.read_comments = vorbis_read_comments,
405
	.duration = vorbis_duration,
406
	.bitrate = vorbis_bitrate,
407
	.bitrate_current = vorbis_current_bitrate,
408
	.codec = vorbis_codec,
409
	.codec_profile = vorbis_codec_profile
410
};
411
412
const int ip_priority = 50;
413
const char * const ip_extensions[] = { "ogg", NULL };
414
const char * const ip_mime_types[] = { "application/ogg", "audio/x-ogg", NULL };
415
const char * const ip_options[] = { NULL };