1 /********************************************************************
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
6 * PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8 * THE Ogg123 SOURCE CODE IS (C) COPYRIGHT 2000-2003 *
9 * by Stan Seibert <volsung@xiph.org> AND OTHER CONTRIBUTORS *
10 * http://www.xiph.org/ *
12 ********************************************************************
16 ********************************************************************/
27 #include <vorbis/codec.h>
28 #include <vorbis/vorbisfile.h>
29 #include "transport.h"
31 #include "vorbis_comments.h"
35 #ifdef HAVE_OV_READ_FILTER
39 typedef struct ovf_private_t
{
45 int bos
; /* At beginning of logical bitstream */
47 decoder_stats_t stats
;
48 #ifdef HAVE_OV_READ_FILTER
53 /* Forward declarations */
54 format_t oggvorbis_format
;
55 ov_callbacks vorbisfile_callbacks
;
58 void print_vorbis_stream_info (decoder_t
*decoder
);
59 void print_vorbis_comments (vorbis_comment
*vc
, decoder_callbacks_t
*cb
,
63 /* ----------------------------------------------------------- */
66 int ovf_can_decode (data_source_t
*source
)
68 return 1; /* The file transport is tested last, so always try it */
72 decoder_t
* ovf_init (data_source_t
*source
, ogg123_options_t
*ogg123_opts
,
73 audio_format_t
*audio_fmt
,
74 decoder_callbacks_t
*callbacks
, void *callback_arg
)
77 ovf_private_t
*private;
81 /* Allocate data source structures */
82 decoder
= malloc(sizeof(decoder_t
));
83 private = malloc(sizeof(ovf_private_t
));
85 if (decoder
!= NULL
&& private != NULL
) {
86 decoder
->source
= source
;
87 decoder
->actual_fmt
= decoder
->request_fmt
= *audio_fmt
;
88 decoder
->format
= &oggvorbis_format
;
89 decoder
->callbacks
= callbacks
;
90 decoder
->callback_arg
= callback_arg
;
91 decoder
->private = private;
94 private->current_section
= -1;
96 private->stats
.total_time
= 0.0;
97 private->stats
.current_time
= 0.0;
98 private->stats
.instant_bitrate
= 0;
99 private->stats
.avg_bitrate
= 0;
101 #ifdef HAVE_OV_READ_FILTER
102 private->vg
.scale_factor
= 1.0;
103 private->vg
.max_scale
= 1.0;
106 fprintf(stderr
, _("ERROR: Out of memory.\n"));
110 /* Initialize vorbisfile decoder */
112 ret
= ov_open_callbacks (decoder
, &private->vf
, NULL
, 0,
113 vorbisfile_callbacks
);
117 /* free(source); nope. caller frees. */
125 int ovf_read (decoder_t
*decoder
, void *ptr
, int nbytes
, int *eos
,
126 audio_format_t
*audio_fmt
)
128 ovf_private_t
*priv
= decoder
->private;
129 decoder_callbacks_t
*cb
= decoder
->callbacks
;
134 /* Read comments and audio info at the start of a logical bitstream */
136 priv
->vc
= ov_comment(&priv
->vf
, -1);
137 priv
->vi
= ov_info(&priv
->vf
, -1);
139 decoder
->actual_fmt
.rate
= priv
->vi
->rate
;
140 decoder
->actual_fmt
.channels
= priv
->vi
->channels
;
142 switch(decoder
->actual_fmt
.channels
){
144 decoder
->actual_fmt
.matrix
="M";
147 decoder
->actual_fmt
.matrix
="L,R";
150 decoder
->actual_fmt
.matrix
="L,C,R";
153 decoder
->actual_fmt
.matrix
="L,R,BL,BR";
156 decoder
->actual_fmt
.matrix
="L,C,R,BL,BR";
159 decoder
->actual_fmt
.matrix
="L,C,R,BL,BR,LFE";
162 decoder
->actual_fmt
.matrix
="L,C,R,SL,SR,BC,LFE";
165 decoder
->actual_fmt
.matrix
="L,C,R,SL,SR,BL,BR,LFE";
168 decoder
->actual_fmt
.matrix
=NULL
;
172 #ifdef HAVE_OV_READ_FILTER
173 vg_init(&priv
->vg
, priv
->vc
);
176 print_vorbis_stream_info(decoder
);
177 print_vorbis_comments(priv
->vc
, cb
, decoder
->callback_arg
);
181 *audio_fmt
= decoder
->actual_fmt
;
183 /* Attempt to read as much audio as is requested */
184 while (nbytes
>= audio_fmt
->word_size
* audio_fmt
->channels
) {
186 old_section
= priv
->current_section
;
187 #ifdef HAVE_OV_READ_FILTER
188 ret
= ov_read_filter(&priv
->vf
, ptr
, nbytes
, audio_fmt
->big_endian
,
189 audio_fmt
->word_size
, audio_fmt
->signed_sample
,
190 &priv
->current_section
,
191 vg_filter
, &priv
->vg
);
193 ret
= ov_read(&priv
->vf
, ptr
, nbytes
, audio_fmt
->big_endian
,
194 audio_fmt
->word_size
, audio_fmt
->signed_sample
,
195 &priv
->current_section
);
204 } else if (ret
== OV_HOLE
) {
206 if (cb
->printf_error
!= NULL
)
207 cb
->printf_error(decoder
->callback_arg
, INFO
,
208 _("--- Hole in the stream; probably harmless\n"));
210 } else if (ret
< 0) {
212 if (cb
->printf_error
!= NULL
)
213 cb
->printf_error(decoder
->callback_arg
, ERROR
,
214 _("=== Vorbis library reported a stream error.\n"));
222 ptr
= (void *)((unsigned char *)ptr
+ ret
);
225 /* did we enter a new logical bitstream? */
226 if (old_section
!= priv
->current_section
&& old_section
!= -1) {
229 priv
->bos
= 1; /* Read new headers next time through */
240 int ovf_seek (decoder_t
*decoder
, double offset
, int whence
)
242 ovf_private_t
*priv
= decoder
->private;
246 if (whence
== DECODER_SEEK_CUR
) {
247 cur
= ov_time_tell(&priv
->vf
);
254 ret
= ov_time_seek(&priv
->vf
, offset
);
262 decoder_stats_t
*ovf_statistics (decoder_t
*decoder
)
264 ovf_private_t
*priv
= decoder
->private;
265 long instant_bitrate
;
268 /* ov_time_tell() doesn't work on non-seekable streams, so we use
270 priv
->stats
.total_time
= (double) ov_pcm_total(&priv
->vf
, -1) /
271 (double) decoder
->actual_fmt
.rate
;
272 priv
->stats
.current_time
= (double) ov_pcm_tell(&priv
->vf
) /
273 (double) decoder
->actual_fmt
.rate
;
275 /* vorbisfile returns 0 when no bitrate change has occurred */
276 instant_bitrate
= ov_bitrate_instant(&priv
->vf
);
277 if (instant_bitrate
> 0)
278 priv
->stats
.instant_bitrate
= instant_bitrate
;
280 avg_bitrate
= ov_bitrate(&priv
->vf
, priv
->current_section
);
281 /* Catch error case caused by non-seekable stream */
282 priv
->stats
.avg_bitrate
= avg_bitrate
> 0 ? avg_bitrate
: 0;
285 return malloc_decoder_stats(&priv
->stats
);
289 void ovf_cleanup (decoder_t
*decoder
)
291 ovf_private_t
*priv
= decoder
->private;
295 free(decoder
->private);
300 format_t oggvorbis_format
= {
311 /* ------------------- Vorbisfile Callbacks ----------------- */
313 size_t vorbisfile_cb_read (void *ptr
, size_t size
, size_t nmemb
, void *arg
)
315 decoder_t
*decoder
= arg
;
317 return decoder
->source
->transport
->read(decoder
->source
, ptr
, size
, nmemb
);
320 int vorbisfile_cb_seek (void *arg
, ogg_int64_t offset
, int whence
)
322 decoder_t
*decoder
= arg
;
324 return decoder
->source
->transport
->seek(decoder
->source
, offset
, whence
);
327 int vorbisfile_cb_close (void *arg
)
329 return 1; /* Ignore close request so transport can be closed later */
332 long vorbisfile_cb_tell (void *arg
)
334 decoder_t
*decoder
= arg
;
336 return decoder
->source
->transport
->tell(decoder
->source
);
340 ov_callbacks vorbisfile_callbacks
= {
343 &vorbisfile_cb_close
,
348 /* ------------------- Private functions -------------------- */
351 void print_vorbis_stream_info (decoder_t
*decoder
)
353 ovf_private_t
*priv
= decoder
->private;
354 decoder_callbacks_t
*cb
= decoder
->callbacks
;
357 if (cb
== NULL
|| cb
->printf_metadata
== NULL
)
360 cb
->printf_metadata(decoder
->callback_arg
, 2,
361 _("Ogg Vorbis stream: %d channel, %ld Hz"),
365 cb
->printf_metadata(decoder
->callback_arg
, 3,
366 _("Vorbis format: Version %d"),
369 cb
->printf_metadata(decoder
->callback_arg
, 3,
370 _("Bitrate hints: upper=%ld nominal=%ld lower=%ld "
372 priv
->vi
->bitrate_upper
,
373 priv
->vi
->bitrate_nominal
,
374 priv
->vi
->bitrate_lower
,
375 priv
->vi
->bitrate_window
);
377 cb
->printf_metadata(decoder
->callback_arg
, 3,
378 _("Encoded by: %s"), priv
->vc
->vendor
);
381 void print_vorbis_comments (vorbis_comment
*vc
, decoder_callbacks_t
*cb
,
388 for (i
= 0; i
< vc
->comments
; i
++) {
390 /* Gotta null terminate these things */
391 if (temp_len
< vc
->comment_lengths
[i
] + 1) {
392 temp_len
= vc
->comment_lengths
[i
] + 1;
393 temp
= realloc(temp
, sizeof(char) * temp_len
);
396 strncpy(temp
, vc
->user_comments
[i
], vc
->comment_lengths
[i
]);
397 temp
[vc
->comment_lengths
[i
]] = '\0';
399 print_vorbis_comment(temp
, cb
, callback_arg
);