bool OGG::Decode (Resource *resource, AudioBuffer *audioBuffer) { OggVorbis_File oggFile; Bytes *data = NULL; OAL_OggMemoryFile fakeFile; if (resource->path) { FILE_HANDLE *file = lime::fopen (resource->path, "rb"); if (!file) { return false; } if (file->isFile ()) { if (ov_open (file->getFile (), &oggFile, NULL, file->getLength ()) != 0) { lime::fclose (file); return false; } } else { lime::fclose (file); data = new Bytes (resource->path); fakeFile = OAL_OggMemoryFile (); fakeFile.data = data->Data (); fakeFile.size = data->Length (); fakeFile.pos = 0; if (ov_open_callbacks (&fakeFile, &oggFile, NULL, 0, OAL_CALLBACKS_BUFFER) != 0) { delete data; return false; } } } else { fakeFile = OAL_OggMemoryFile (); fakeFile.data = resource->data->Data (); fakeFile.size = resource->data->Length (); fakeFile.pos = 0; if (ov_open_callbacks (&fakeFile, &oggFile, NULL, 0, OAL_CALLBACKS_BUFFER) != 0) { return false; } } // 0 for Little-Endian, 1 for Big-Endian #ifdef HXCPP_BIG_ENDIAN #define BUFFER_READ_TYPE 1 #else #define BUFFER_READ_TYPE 0 #endif int bitStream; long bytes = 1; int totalBytes = 0; #define BUFFER_SIZE 4096 vorbis_info *pInfo = ov_info (&oggFile, -1); if (pInfo == NULL) { //LOG_SOUND("FAILED TO READ OGG SOUND INFO, IS THIS EVEN AN OGG FILE?\n"); ov_clear (&oggFile); if (data) { delete data; } return false; } audioBuffer->channels = pInfo->channels; audioBuffer->sampleRate = pInfo->rate; audioBuffer->bitsPerSample = 16; int dataLength = ov_pcm_total (&oggFile, -1) * audioBuffer->channels * audioBuffer->bitsPerSample / 8; audioBuffer->data->Resize (dataLength); while (bytes > 0) { bytes = ov_read (&oggFile, (char *)audioBuffer->data->Data () + totalBytes, BUFFER_SIZE, BUFFER_READ_TYPE, 2, 1, &bitStream); totalBytes += bytes; } if (dataLength != totalBytes) { audioBuffer->data->Resize (totalBytes); } ov_clear (&oggFile); #undef BUFFER_READ_TYPE if (data) { delete data; } return true; }
bool OGG::Decode (Resource *resource, AudioBuffer *audioBuffer) { OggVorbis_File oggFile; if (resource->path) { FILE_HANDLE *file = lime::fopen (resource->path, "rb"); if (!file) { return false; } if (file->isFile ()) { ov_open (file->getFile (), &oggFile, NULL, file->getLength ()); } else { ByteArray data = ByteArray (resource->path); OAL_OggMemoryFile fakeFile = { data.Bytes (), data.Size (), 0 }; if (ov_open_callbacks (&fakeFile, &oggFile, NULL, 0, OAL_CALLBACKS_BUFFER) != 0) { return false; } } } else { OAL_OggMemoryFile fakeFile = { resource->data->Bytes (), resource->data->Size (), 0 }; if (ov_open_callbacks (&fakeFile, &oggFile, NULL, 0, OAL_CALLBACKS_BUFFER) != 0) { return false; } } // 0 for Little-Endian, 1 for Big-Endian #ifdef HXCPP_BIG_ENDIAN #define BUFFER_READ_TYPE 1 #else #define BUFFER_READ_TYPE 0 #endif int bitStream; long bytes = 1; int totalBytes = 0; #define BUFFER_SIZE 32768 vorbis_info *pInfo = ov_info (&oggFile, -1); if (pInfo == NULL) { //LOG_SOUND("FAILED TO READ OGG SOUND INFO, IS THIS EVEN AN OGG FILE?\n"); return false; } audioBuffer->channels = pInfo->channels; audioBuffer->sampleRate = pInfo->rate; //default to 16? todo audioBuffer->bitsPerSample = 16; // Seem to need four times the read PCM total audioBuffer->data->Resize (ov_pcm_total (&oggFile, -1) * 4); while (bytes > 0) { if (audioBuffer->data->Size () < totalBytes + BUFFER_SIZE) { audioBuffer->data->Resize (totalBytes + BUFFER_SIZE); } bytes = ov_read (&oggFile, (char *)audioBuffer->data->Bytes () + totalBytes, BUFFER_SIZE, BUFFER_READ_TYPE, 2, 1, &bitStream); totalBytes += bytes; } audioBuffer->data->Resize (totalBytes); ov_clear (&oggFile); #undef BUFFER_SIZE #undef BUFFER_READ_TYPE return true; }