caudio/Source/cOggDecoder.cpp
Joshua Jones 28a22c7f73 Fixed problem with the msvc project not outputting a .lib file.
Updated tutorials to fix minor bugs and pathing issues.  Also fixed crash bug on failure to create the audio object.
Added msvc projects for all tutorials.
Updated the listener class to be self contained and only handle stuff related to the OpenAL listener.  It does NOT init OpenAL anymore, that has been moved to cAudioManager.
Extended the listener class to support all settings that native OpenAL supports.
Cleaned up cFileSource and fixed a crash bug on NULL file handle
Fixed returning bad audio buffer chunk sizes from the cOggDecoder on errors in the ogg stream
Seeking can now be down in fractions of a second now, changed the seconds field from int to float
Fixed various odd formatting.
Fixed potential crash bug in cMemorySource if memory could not be allocated.
cMemorySource will no longer clear the buffer you give to it before filling it with data.  This prevents an overwrite from happening in case of error but the user should provide a zeroed buffer to cMemorySource anyway for safety.
Relative seeking is now supported by cOggDecoder.
2009-08-08 05:51:32 +00:00

114 lines
2.9 KiB
C++

#include "../Headers/cOggDecoder.h"
namespace cAudio
{
//!Read Vorbis Data
size_t VorbisRead(void *ptr, size_t byteSize,size_t sizeToRead, void *datasource)
{
IDataSource* Stream = (IDataSource*)datasource;
return Stream->read(ptr,byteSize*sizeToRead);
}
//!Seek Vorbis Data
int VorbisSeek(void *datasource,ogg_int64_t offset,int whence)
{
IDataSource* Stream = (IDataSource*)datasource;
switch (whence)
{
case SEEK_SET:
Stream->seek(offset, false);
break;
case SEEK_CUR:
Stream->seek(offset, true);
break;
case SEEK_END:
Stream->seek(Stream->getSize()-offset, false);
break;
};
return 0;
}
//!Returns the vorbis data that was stored.
long VorbisTell(void *datasource)
{
return ((IDataSource*)datasource)->getCurrentPos();
}
cOggDecoder::cOggDecoder(IDataSource* stream) : IAudioDecoder(stream)
{
vorbisCallbacks.read_func = VorbisRead;
vorbisCallbacks.close_func = NULL;
vorbisCallbacks.seek_func = VorbisSeek;
vorbisCallbacks.tell_func = VorbisTell;
ov_open_callbacks(Stream,&oggStream,NULL,0,vorbisCallbacks);
vorbisInfo = ov_info(&oggStream, -1);
vorbisComment = ov_comment(&oggStream,-1);
}
cOggDecoder::~cOggDecoder()
{
ov_clear(&oggStream);
}
//!Returns given vorbis channel format
AudioFormats cOggDecoder::getFormat()
{
if(vorbisInfo->channels == 1)
{
return EAF_16BIT_MONO;
}
else
{
return EAF_16BIT_STEREO;
}
}
//!Returns vorbis file frequency
int cOggDecoder::getFrequency()
{
return vorbisInfo->rate;
}
//!Returns if vorbis file is seekable
bool cOggDecoder::isSeekingSupported()
{
return (ov_seekable(&oggStream)!=0);
}
//!Reads the vorbis data
int cOggDecoder::readAudioData(void* output, int amount)
{
int temp = 0;
int result = ov_read(&oggStream,(char*)output,amount,0,2,1,&temp);
return (result < 0) ? 0 : result;
}
//!Sets the postion for vorbis data reader
bool cOggDecoder::setPosition(int position, bool relative)
{
if(ov_seekable(&oggStream))
{
return (ov_raw_seek(&oggStream,position)==0);
}
else
return false;
}
//!Seeks the vorbis data
bool cOggDecoder::seek(float seconds, bool relative)
{
if(ov_seekable(&oggStream))
{
if(relative)
{
float curtime = ov_time_tell(&oggStream);
return (ov_time_seek(&oggStream,curtime+seconds)==0);
}
else
return (ov_time_seek(&oggStream,seconds)==0);
}
return false;
}
}