3 Copyright (C) 2000 Martin Vogt
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation.
9 For more information look at the file COPYRIGHT in this package
14 #include "vorbisPlugin.h"
16 size_t fread_func(void *ptr
, size_t size
, size_t nmemb
, void *stream
) {
17 InputStream
* input
=(InputStream
*) stream
;
18 return input
->read((char*)ptr
,size
*nmemb
);
22 int fseek_func(void *stream
, ogg_int64_t offset
, int whence
) {
24 InputStream
* input
=(InputStream
*) stream
;
26 if (whence
==SEEK_SET
) {
27 ret
=input
->seek(offset
);
30 if (whence
==SEEK_CUR
) {
31 ret
=input
->seek(input
->getBytePosition()+offset
);
34 if (whence
==SEEK_END
) {
35 ret
=input
->seek(input
->getByteLength());
38 cout
<< "hm, strange call"<<endl
;
43 int fclose_func (void *stream
) {
44 InputStream
* input
=(InputStream
*) stream
;
46 // its handled different in kmpg
47 // we close the stream if the decoder signals eof.
53 long ftell_func (void *stream
) {
54 InputStream
* input
=(InputStream
*) stream
;
55 return input
->getBytePosition();
59 VorbisPlugin::VorbisPlugin() {
62 timeDummy
=new TimeStamp();
63 pcmout
=new char[4096];
70 VorbisPlugin::~VorbisPlugin() {
76 // here we can config our decoder with special flags
77 void VorbisPlugin::config(char* key
, char* value
,void* user_data
) {
79 if (strcmp(key
,"-c")==0) {
82 DecoderPlugin::config(key
,value
,user_data
);
86 int VorbisPlugin::init() {
87 ov_callbacks callbacks
;
89 callbacks
.read_func
= fread_func
;
90 callbacks
.seek_func
= fseek_func
;
91 callbacks
.close_func
= fclose_func
;
92 callbacks
.tell_func
= ftell_func
;
94 // here is the hack to pass the pointer to
95 // our streaming interface.
97 if(ov_open_callbacks(input
, &vf
, NULL
, 0, callbacks
) < 0) {
105 // called by decoder thread
106 int VorbisPlugin::processVorbis(vorbis_info
* vi
,vorbis_comment
* comment
) {
110 int current_section
=-1; /* A vorbis physical bitstream may
111 consist of many logical sections
112 (information for each of which may be
113 fetched from the vf structure). This
114 value is filled in by ov_read to alert
115 us what section we're currently
116 decoding in case we need to change
117 playback settings at a section
119 ret
=ov_read(&vf
,pcmout
,4096,0,2,1,¤t_section
);
126 /* error in the stream. Not a problem, just reporting it in
127 case we (the app) cares. In this case, we don't. */
130 if(current_section
!=last_section
){
131 vi
=ov_info(&vf
,-1); /* The info struct is different in each
132 section. vf holds them all for the
133 given bitstream. This requests the
136 double timeoffset
=ov_time_tell(&vf
);
138 comment
= ov_comment(&vf
, -1);
140 cout
<< "we have a comment"<<endl
;
143 last_section
=current_section
;
144 output
->audioPlay(timeDummy
,timeDummy
,pcmout
,ret
);
151 void VorbisPlugin::decoder_loop() {
152 vorbis_info
*vi
=NULL
;
153 vorbis_comment
*comment
;
160 cout
<< "VorbisPlugin::decoder_loop input is NULL"<<endl
;
163 if (output
== NULL
) {
164 cout
<< "VorbisPlugin::decoder_loop output is NULL"<<endl
;
170 /********** Decode setup ************/
175 switch(streamState
) {
176 case _STREAM_STATE_FIRST_INIT
:
177 if (init()== false) {
178 // total failure. exit decoding
184 if (lnoLength
==false) {
185 pluginInfo
->setLength(getTotalLength());
186 output
->writeInfo(pluginInfo
);
188 output
->audioSetup(vi
->rate
,vi
->channels
-1,1,0,16);
190 setStreamState(_STREAM_STATE_PLAY
);
192 case _STREAM_STATE_INIT
:
193 case _STREAM_STATE_PLAY
:
194 processVorbis(vi
,comment
);
196 case _STREAM_STATE_WAIT_FOR_END
:
201 cout
<< "unknown stream state vorbis decoder:"<<streamState
<<endl
;
205 ov_clear(&vf
); /* ov_clear closes the stream if its open. Safe to
206 call on an uninitialized structure as long as
210 output
->audioFlush();
213 // vorbis can seek in streams
214 int VorbisPlugin::seek_impl(int second
) {
215 ov_time_seek(&vf
,(double) second
);
221 int VorbisPlugin::getTotalLength() {
223 int byteLen
=input
->getByteLength();
227 /* Retrieve the length in second*/
229 if (lshutdown
==false) {
230 back
= (int) ov_time_total(&vf
, -1);