Game Development Reference
In-Depth Information
{
return -1L;
}
return static_cast<long>(pVorbisData->dataRead);
}
You might notice that the method that fakes the
fclose()
doesn
'
t do anything.
Ordinarily, you might free the memory in the buffer, but since the raw sound
data is managed by the resource cache, nothing needs to be done. Here
'
s what the
ParseOgg()
method looks like:
bool OggResourceLoader::ParseOgg(char *oggStream, size_t length,
shared_ptr<ResHandle> handle)
{
shared_ptr<SoundResourceExtraData> extra =
static_pointer_cast<SoundResourceExtraData>(handle->GetExtra());
OggVorbis_File vf; // for the vorbisfile interface
ov_callbacks oggCallbacks;
OggMemoryFile *vorbisMemoryFile = new OggMemoryFile;
vorbisMemoryFile->dataRead = 0;
vorbisMemoryFile->dataSize = length;
vorbisMemoryFile->dataPtr = (unsigned char *)oggStream;
oggCallbacks.read_func = VorbisRead;
oggCallbacks.close_func = VorbisClose;
oggCallbacks.seek_func = VorbisSeek;
oggCallbacks.tell_func = VorbisTell;
int ov_ret =
ov_open_callbacks(vorbisMemoryFile, &vf, NULL, 0, oggCallbacks);
assert(ov_ret>=0);
// ok now the tricky part
// the vorbis_info struct keeps the most of the interesting format info
vorbis_info *vi = ov_info(&vf,-1);
memset(&extra->m_WavFormatEx, 0, sizeof(extra->m_WavFormatEx));
extra->m_WavFormatEx.cbSize
= sizeof(extra->m_WavFormatEx);
extra->m_WavFormatEx.nChannels
= vi->channels;
// ogg vorbis is always 16 bit
extra->m_WavFormatEx.wBitsPerSample = 16;
extra->m_WavFormatEx.nSamplesPerSec = vi->rate;