Refactor VorbisFile

This commit is contained in:
Joshua Granick
2017-01-07 16:47:51 -08:00
parent 50c71c4762
commit ecc484eed2
5 changed files with 250 additions and 316 deletions

View File

@@ -212,7 +212,8 @@
<compilerflag value="-I${NATIVE_TOOLKIT_PATH}/vorbis/include/" />
<compilerflag value="-DLIME_VORBIS" />
<file name="src/media/codecs/VorbisBindings.cpp" />
<file name="src/media/codecs/vorbis/VorbisBindings.cpp" />
<file name="src/media/codecs/vorbis/VorbisFile.cpp" />
</section>

View File

@@ -0,0 +1,27 @@
#ifndef LIME_MEDIA_CODECS_VORBIS_VORBIS_FILE_H
#define LIME_MEDIA_CODECS_VORBIS_VORBIS_FILE_H
#include <utils/Bytes.h>
#include <vorbis/vorbisfile.h>
namespace lime {
class VorbisFile {
public:
static OggVorbis_File* FromBytes (Bytes* bytes);
static OggVorbis_File* FromFile (const char* path);
};
}
#endif

View File

@@ -1,8 +1,7 @@
#include <hx/CFFIPrime.h>
#include <media/codecs/vorbis/VorbisFile.h>
#include <system/CFFIPointer.h>
#include <system/System.h>
#include <utils/Bytes.h>
#include <vorbis/vorbisfile.h>
namespace lime {
@@ -42,104 +41,6 @@ namespace lime {
}
typedef struct {
unsigned char* data;
ogg_int64_t size;
ogg_int64_t pos;
} Vorbis_BufferData;
static size_t Vorbis_BufferRead (void* dest, size_t eltSize, size_t nelts, Vorbis_BufferData* src) {
size_t len = eltSize * nelts;
if ((src->pos + len) > src->size) {
len = src->size - src->pos;
}
if (len > 0) {
memcpy (dest, (src->data + src->pos), len);
src->pos += len;
}
return len;
}
static int Vorbis_BufferSeek (Vorbis_BufferData* src, ogg_int64_t pos, int whence) {
switch (whence) {
case SEEK_CUR:
src->pos += pos;
break;
case SEEK_END:
src->pos = src->size - pos;
break;
case SEEK_SET:
src->pos = pos;
break;
default:
return -1;
}
if (src->pos < 0) {
src->pos = 0;
return -1;
}
if (src->pos > src->size) {
return -1;
}
return 0;
}
static int Vorbis_BufferClose (Vorbis_BufferData* src) {
return 0;
}
static long Vorbis_BufferTell (Vorbis_BufferData *src) {
return src->pos;
}
static ov_callbacks VORBIS_CALLBACKS_BUFFER = {
(size_t (*)(void *, size_t, size_t, void *)) Vorbis_BufferRead,
(int (*)(void *, ogg_int64_t, int)) Vorbis_BufferSeek,
(int (*)(void *)) Vorbis_BufferClose,
(long (*)(void *)) Vorbis_BufferTell
};
void lime_vorbis_file_clear (value vorbisFile);
@@ -199,73 +100,29 @@ namespace lime {
value lime_vorbis_file_from_bytes (value data) {
OggVorbis_File* vorbisFile = new OggVorbis_File;
memset (vorbisFile, 0, sizeof (OggVorbis_File));
Bytes bytes;
bytes.Set (data);
Vorbis_BufferData buffer = Vorbis_BufferData ();
buffer.data = bytes.Data ();
buffer.size = bytes.Length ();
buffer.pos = 0;
OggVorbis_File* vorbisFile = VorbisFile::FromBytes (&bytes);
if (ov_open_callbacks (&buffer, vorbisFile, NULL, 0, VORBIS_CALLBACKS_BUFFER) != 0) {
if (vorbisFile) {
free (vorbisFile);
return alloc_null ();
return CFFIPointer ((void*)(uintptr_t)vorbisFile, gc_vorbis_file);
}
return CFFIPointer ((void*)(uintptr_t)vorbisFile, gc_vorbis_file);
return alloc_null ();
}
value lime_vorbis_file_from_file (HxString path) {
if (path.c_str ()) {
OggVorbis_File* vorbisFile = VorbisFile::FromFile (path.c_str ());
if (vorbisFile) {
FILE_HANDLE *file = lime::fopen (path.c_str (), "rb");
if (file) {
OggVorbis_File* vorbisFile = new OggVorbis_File;
memset (vorbisFile, 0, sizeof (OggVorbis_File));
if (file->isFile ()) {
if (ov_open (file->getFile (), vorbisFile, NULL, file->getLength ()) != 0) {
free (vorbisFile);
lime::fclose (file);
return alloc_null ();
}
} else {
lime::fclose (file);
Bytes* bytes = new Bytes (path.c_str ());
Vorbis_BufferData buffer = Vorbis_BufferData ();
buffer.data = bytes->Data ();
buffer.size = bytes->Length ();
buffer.pos = 0;
if (ov_open_callbacks (&buffer, vorbisFile, NULL, 0, VORBIS_CALLBACKS_BUFFER) != 0) {
delete bytes;
free (vorbisFile);
return alloc_null ();
}
}
return CFFIPointer ((void*)(uintptr_t)vorbisFile, gc_vorbis_file);
}
return CFFIPointer ((void*)(uintptr_t)vorbisFile, gc_vorbis_file);
}

View File

@@ -0,0 +1,196 @@
#include <media/codecs/vorbis/VorbisFile.h>
#include <system/System.h>
namespace lime {
typedef struct {
unsigned char* data;
ogg_int64_t size;
ogg_int64_t pos;
} VorbisFile_Buffer;
static size_t VorbisFile_BufferRead (void* dest, size_t eltSize, size_t nelts, VorbisFile_Buffer* src) {
size_t len = eltSize * nelts;
if ((src->pos + len) > src->size) {
len = src->size - src->pos;
}
if (len > 0) {
memcpy (dest, (src->data + src->pos), len);
src->pos += len;
}
return len;
}
static int VorbisFile_BufferSeek (VorbisFile_Buffer* src, ogg_int64_t pos, int whence) {
switch (whence) {
case SEEK_CUR:
src->pos += pos;
break;
case SEEK_END:
src->pos = src->size - pos;
break;
case SEEK_SET:
src->pos = pos;
break;
default:
return -1;
}
if (src->pos < 0) {
src->pos = 0;
return -1;
}
if (src->pos > src->size) {
return -1;
}
return 0;
}
static int VorbisFile_BufferClose (VorbisFile_Buffer* src) {
return 0;
}
static long VorbisFile_BufferTell (VorbisFile_Buffer* src) {
return src->pos;
}
static ov_callbacks VORBIS_FILE_BUFFER_CALLBACKS = {
(size_t (*)(void *, size_t, size_t, void *)) VorbisFile_BufferRead,
(int (*)(void *, ogg_int64_t, int)) VorbisFile_BufferSeek,
(int (*)(void *)) VorbisFile_BufferClose,
(long (*)(void *)) VorbisFile_BufferTell
};
static size_t VorbisFile_FileRead (void* dest, size_t eltSize, size_t nelts, FILE_HANDLE* file) {
return lime::fread (dest, eltSize, nelts, file);
}
static int VorbisFile_FileSeek (FILE_HANDLE* file, ogg_int64_t pos, int whence) {
return lime::fseek (file, pos, whence);
}
static int VorbisFile_FileClose (FILE_HANDLE* file) {
return lime::fclose (file);
}
static long VorbisFile_FileTell (FILE_HANDLE* file) {
return lime::ftell (file);
}
static ov_callbacks VORBIS_FILE_FILE_CALLBACKS = {
(size_t (*)(void *, size_t, size_t, void *)) VorbisFile_FileRead,
(int (*)(void *, ogg_int64_t, int)) VorbisFile_FileSeek,
(int (*)(void *)) VorbisFile_FileClose,
(long (*)(void *)) VorbisFile_FileTell
};
OggVorbis_File* VorbisFile::FromBytes (Bytes* bytes) {
OggVorbis_File* vorbisFile = new OggVorbis_File;
memset (vorbisFile, 0, sizeof (OggVorbis_File));
VorbisFile_Buffer buffer = VorbisFile_Buffer ();
buffer.data = bytes->Data ();
buffer.size = bytes->Length ();
buffer.pos = 0;
if (ov_open_callbacks (&buffer, vorbisFile, NULL, 0, VORBIS_FILE_BUFFER_CALLBACKS) != 0) {
free (vorbisFile);
return 0;
}
return vorbisFile;
}
OggVorbis_File* VorbisFile::FromFile (const char* path) {
if (path) {
FILE_HANDLE *file = lime::fopen (path, "rb");
if (file) {
OggVorbis_File* vorbisFile = new OggVorbis_File;
memset (vorbisFile, 0, sizeof (OggVorbis_File));
if (ov_open_callbacks (file, vorbisFile, NULL, 0, VORBIS_FILE_FILE_CALLBACKS) != 0) {
free (vorbisFile);
lime::fclose (file);
return 0;
}
return vorbisFile;
}
}
return 0;
}
}

View File

@@ -1,165 +1,28 @@
#include <media/codecs/vorbis/VorbisFile.h>
#include <media/containers/OGG.h>
#include <system/System.h>
#include <vorbis/vorbisfile.h>
namespace lime {
typedef struct {
unsigned char* data;
ogg_int64_t size;
ogg_int64_t pos;
} OAL_OggMemoryFile;
static size_t OAL_OggBufferRead (void* dest, size_t eltSize, size_t nelts, OAL_OggMemoryFile* src) {
size_t len = eltSize * nelts;
if ((src->pos + len) > src->size) {
len = src->size - src->pos;
}
if (len > 0) {
memcpy (dest, (src->data + src->pos), len);
src->pos += len;
}
return len;
}
static int OAL_OggBufferSeek (OAL_OggMemoryFile* src, ogg_int64_t pos, int whence) {
switch (whence) {
case SEEK_CUR:
src->pos += pos;
break;
case SEEK_END:
src->pos = src->size - pos;
break;
case SEEK_SET:
src->pos = pos;
break;
default:
return -1;
}
if (src->pos < 0) {
src->pos = 0;
return -1;
}
if (src->pos > src->size) {
return -1;
}
return 0;
}
static int OAL_OggBufferClose (OAL_OggMemoryFile* src) {
return 0;
}
static long OAL_OggBufferTell (OAL_OggMemoryFile *src) {
return src->pos;
}
static ov_callbacks OAL_CALLBACKS_BUFFER = {
(size_t (*)(void *, size_t, size_t, void *)) OAL_OggBufferRead,
(int (*)(void *, ogg_int64_t, int)) OAL_OggBufferSeek,
(int (*)(void *)) OAL_OggBufferClose,
(long (*)(void *)) OAL_OggBufferTell
};
bool OGG::Decode (Resource *resource, AudioBuffer *audioBuffer) {
OggVorbis_File oggFile;
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;
}
}
oggFile = VorbisFile::FromFile (resource->path);
} else {
fakeFile = OAL_OggMemoryFile ();
fakeFile.data = resource->data->Data ();
fakeFile.size = resource->data->Length ();
fakeFile.pos = 0;
oggFile = VorbisFile::FromBytes (resource->data);
if (ov_open_callbacks (&fakeFile, &oggFile, NULL, 0, OAL_CALLBACKS_BUFFER) != 0) {
return false;
}
}
if (!oggFile) {
return false;
}
@@ -176,18 +39,13 @@ namespace lime {
#define BUFFER_SIZE 4096
vorbis_info *pInfo = ov_info (&oggFile, -1);
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;
}
ov_clear (oggFile);
delete oggFile;
return false;
@@ -198,12 +56,12 @@ namespace lime {
audioBuffer->bitsPerSample = 16;
int dataLength = ov_pcm_total (&oggFile, -1) * audioBuffer->channels * audioBuffer->bitsPerSample / 8;
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);
bytes = ov_read (oggFile, (char *)audioBuffer->data->Data () + totalBytes, BUFFER_SIZE, BUFFER_READ_TYPE, 2, 1, &bitStream);
totalBytes += bytes;
}
@@ -214,16 +72,11 @@ namespace lime {
}
ov_clear (&oggFile);
ov_clear (oggFile);
delete oggFile;
#undef BUFFER_READ_TYPE
if (data) {
delete data;
}
return true;
}