43 #ifndef _audiovorbisdecoder_cpp
44 #define _audiovorbisdecoder_cpp
46 #ifdef ENABLE_VORBIS_ENCODE
48 #include "Audio/vorbisdecoder.h"
53 #include <vorbis/codec.h>
54 #include <vorbis/vorbisfile.h>
63 Stream->clear( Stream->rdstate() ^ ( std::ios::eofbit | std::ios::failbit ) );
69 size_t VorbisRead(
void *ptr,
size_t byteSize,
size_t sizeToRead,
void *datasource)
72 Stream->read( static_cast<char*>(ptr), byteSize * sizeToRead );
73 return Stream->gcount();
78 int VorbisSeek(
void *datasource,ogg_int64_t offset,
int whence)
84 case SEEK_SET: Stream->seekg(offset,std::ios_base::beg);
break;
85 case SEEK_CUR: Stream->seekg(offset,std::ios_base::cur);
break;
86 case SEEK_END: Stream->seekg(offset,std::ios_base::end);
break;
88 return ( Stream->good() ? 0 : -1 );
93 long VorbisTell(
void *datasource)
97 return Stream->tellg();
102 int VorbisClose(
void *datasource)
117 class MEZZ_LIB VorbisDecoderInternalData
125 vorbis_info* VorbisInfo;
127 vorbis_comment* VorbisComments;
129 ov_callbacks VorbisCallbacks;
131 OggVorbis_File VorbisFile;
137 VorbisDecoderInternalData()
139 this->VorbisCallbacks.read_func = VorbisRead;
140 this->VorbisCallbacks.seek_func = VorbisSeek;
141 this->VorbisCallbacks.tell_func = VorbisTell;
142 this->VorbisCallbacks.close_func = VorbisClose;
145 ~VorbisDecoderInternalData() { }
152 VorbisStream(Stream),
157 this->VorbisStream->seekg(0,std::ios_base::end);
158 this->VorbisStreamSize = this->VorbisStream->tellg();
159 this->VorbisStream->seekg(0);
160 this->VDID =
new VorbisDecoderInternalData();
161 this->Valid = ( ov_open_callbacks(VorbisStream.get(),&(this->VDID->VorbisFile),NULL,0,this->VDID->VorbisCallbacks) == 0 );
164 this->VDID->VorbisInfo = ov_info( &(this->VDID->VorbisFile), -1 );
165 this->VDID->VorbisComments = ov_comment( &(this->VDID->VorbisFile), -1 );
166 this->VorbisStreamPos = this->VorbisStream->tellg();
170 VorbisDecoder::~VorbisDecoder()
172 ov_clear( &(this->VDID->VorbisFile) );
175 void VorbisDecoder::ClearStreamErrors()
177 if( this->VorbisStream->eof() ) {
178 this->VorbisStream->clear( this->VorbisStream->rdstate() ^ ( std::ios::eofbit | std::ios::failbit ) );
185 String VorbisDecoder::GetUserComment(
const UInt32 Index)
187 Char8* Comment = this->VDID->VorbisComments->user_comments[Index];
188 Integer CommentLength = this->VDID->VorbisComments->comment_lengths[Index];
189 return String(Comment,CommentLength);
192 UInt32 VorbisDecoder::GetNumUserComments()
const
194 return this->VDID->VorbisComments->comments;
200 Boole VorbisDecoder::IsValid()
210 Boole VorbisDecoder::IsSeekingSupported()
212 if( this->Valid )
return (ov_seekable( &(this->VDID->VorbisFile) ) != 0);
219 switch( this->VDID->VorbisInfo->channels )
221 case 1:
return Audio::BC_16Bit_Mono;
break;
222 case 2:
return Audio::BC_16Bit_Stereo;
break;
226 return Audio::BC_8Bit_Mono;
229 UInt32 VorbisDecoder::GetFrequency()
const
231 if( this->Valid )
return this->VDID->VorbisInfo->rate;
237 return this->VorbisStream;
240 Boole VorbisDecoder::IsEndOfStream()
const
242 return ( this->VorbisStream->eof() || this->VorbisStream->tellg() >= this->VorbisStreamSize );
247 if( this->IsSeekingSupported() ) {
249 Real CurrPos = ov_raw_tell( &(this->VDID->VorbisFile) );
250 if( ov_raw_seek( &(this->VDID->VorbisFile), CurrPos + Position ) == 0 ) {
251 this->VorbisStreamPos = this->VorbisStream->tellg();
255 if( ov_raw_seek( &(this->VDID->VorbisFile), Position ) == 0 ) {
256 this->VorbisStreamPos = this->VorbisStream->tellg();
264 Boole VorbisDecoder::Seek(
const Real Seconds,
const Boole Relative)
266 if( this->IsSeekingSupported() ) {
268 Real CurrTime = ov_time_tell( &(this->VDID->VorbisFile) );
269 if( ov_time_seek( &(this->VDID->VorbisFile), CurrTime + Seconds ) == 0 ) {
270 this->VorbisStreamPos = this->VorbisStream->tellg();
274 if( ov_time_seek( &(this->VDID->VorbisFile), Seconds ) == 0 ) {
275 this->VorbisStreamPos = this->VorbisStream->tellg();
283 UInt32 VorbisDecoder::ReadAudioData(
void* Output,
UInt32 Amount)
286 if( this->VorbisStreamPos != this->VorbisStream->tellg() ) {
287 this->ClearStreamErrors();
288 this->VorbisStream->seekg( this->VorbisStreamPos );
291 Integer Ret = ov_read( &(this->VDID->VorbisFile), (
Char8*)Output, Amount, 0, 2, 1, &Temp );
292 this->VorbisStreamPos = this->VorbisStream->tellg();
293 return ( Ret > 0 ? Ret : 0 );
302 Real VorbisDecoder::GetTotalTime()
const
303 {
return ov_time_total( &(this->VDID->VorbisFile), -1 ); }
305 Real VorbisDecoder::GetCurrentTime()
const
306 {
return ov_time_tell( &(this->VDID->VorbisFile) ); }
308 UInt32 VorbisDecoder::GetTotalSize()
const
309 {
return ov_pcm_total( &(this->VDID->VorbisFile), -1 ) * this->VDID->VorbisInfo->channels; }
311 UInt32 VorbisDecoder::GetCompressedSize()
const
312 {
return ov_raw_total( &(this->VDID->VorbisFile), -1 ); }
314 UInt32 VorbisDecoder::GetCurrentPosition()
const
315 {
return ov_pcm_tell( &(this->VDID->VorbisFile) ) * this->VDID->VorbisInfo->channels; }
317 UInt32 VorbisDecoder::GetCurrentCompressedPosition()
const
318 {
return ov_raw_tell( &(this->VDID->VorbisFile) ); }
322 #endif //ENABLE_VORBIS_ENCODE
int32_t Int32
An 32-bit integer.
bool Boole
Generally acts a single bit, true or false.
int Integer
A datatype used to represent any integer close to.
Base class for streams that support both read and write operations.
float Real
A Datatype used to represent a real floating point number.
char Char8
A datatype to represent one character.
uint32_t UInt32
An 32-bit unsigned integer.
Encoding
The encoding to use when reading or writing an audio buffer.
The bulk of the engine components go in this namspace.
CountedPtr< DataStream > DataStreamPtr
This is a convenience type for a data stream in a counted pointer.
std::string String
A datatype used to a series of characters.
Declaration of DataStream.
BitConfig
Used to describe the different bit configurations supported by this audio system. ...