Using latest android branch of LÖVE (6d14516b05c9) that now syncs with default (woooo!)

This commit is contained in:
fysx
2015-07-03 19:09:18 +02:00
parent 1924bbdeeb
commit 357a7237a4
304 changed files with 28694 additions and 23064 deletions
+5 -2
View File
@@ -41,6 +41,9 @@ SoundData::SoundData(Decoder *decoder)
, bitDepth(0)
, channels(0)
{
if (decoder->getBitDepth() != 8 && decoder->getBitDepth() != 16)
throw love::Exception("Invalid bit depth: %d", decoder->getBitDepth());
size_t bufferSize = 524288; // 0x80000
int decoded = decoder->decode();
@@ -117,7 +120,7 @@ void SoundData::load(int samples, int sampleRate, int bitDepth, int channels, vo
if (sampleRate <= 0)
throw love::Exception("Invalid sample rate: %d", sampleRate);
if (bitDepth <= 0)
if (bitDepth != 8 && bitDepth != 16)
throw love::Exception("Invalid bit depth: %d", bitDepth);
if (channels <= 0)
@@ -176,7 +179,7 @@ int SoundData::getSampleRate() const
int SoundData::getSampleCount() const
{
return (size/channels)/(bitDepth/8);
return (int) ((size/channels)/(bitDepth/8));
}
float SoundData::getDuration() const
@@ -0,0 +1,274 @@
/**
* Copyright (c) 2006-2015 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifdef LOVE_SUPPORT_COREAUDIO
// LOVE
#include "CoreAudioDecoder.h"
// C++
#include <vector>
namespace love
{
namespace sound
{
namespace lullaby
{
// Callbacks
namespace
{
OSStatus readFunc(void *inClientData, SInt64 inPosition, UInt32 requestCount, void *buffer, UInt32 *actualCount)
{
Data *data = (Data *) inClientData;
SInt64 bytesLeft = data->getSize() - inPosition;
if (bytesLeft > 0)
{
UInt32 actualSize = bytesLeft >= requestCount ? requestCount : (UInt32) bytesLeft;
memcpy(buffer, (char *) data->getData() + inPosition, actualSize);
*actualCount = actualSize;
}
else
{
*actualCount = 0;
return kAudioFilePositionError;
}
return noErr;
}
SInt64 getSizeFunc(void *inClientData)
{
Data *data = (Data *) inClientData;
return data->getSize();
}
} // anonymous namespace
CoreAudioDecoder::CoreAudioDecoder(Data *data, const std::string &ext, int bufferSize)
: Decoder(data, ext, bufferSize)
, audioFile(nullptr)
, extAudioFile(nullptr)
, inputInfo()
, outputInfo()
{
try
{
OSStatus err = noErr;
// Open the file represented by the Data.
err = AudioFileOpenWithCallbacks(data, readFunc, nullptr, getSizeFunc, nullptr, kAudioFileMP3Type, &audioFile);
if (err != noErr)
throw love::Exception("Could open audio file for decoding.");
// We want to use the Extended AudioFile API.
err = ExtAudioFileWrapAudioFileID(audioFile, false, &extAudioFile);
if (err != noErr)
throw love::Exception("Could open audio file for decoding.");
// Get the format of the audio data.
UInt32 propertySize = sizeof(inputInfo);
err = ExtAudioFileGetProperty(extAudioFile, kExtAudioFileProperty_FileDataFormat, &propertySize, &inputInfo);
if (err != noErr)
throw love::Exception("Could not determine file format.");
// Set the output format to 16 bit signed integer (native-endian) data.
// Keep the channel count and sample rate of the source format.
outputInfo.mSampleRate = inputInfo.mSampleRate;
outputInfo.mChannelsPerFrame = inputInfo.mChannelsPerFrame;
int bytes = (inputInfo.mBitsPerChannel == 8) ? 1 : 2;
outputInfo.mFormatID = kAudioFormatLinearPCM;
outputInfo.mBitsPerChannel = bytes * 8;
outputInfo.mBytesPerFrame = bytes * outputInfo.mChannelsPerFrame;
outputInfo.mFramesPerPacket = 1;
outputInfo.mBytesPerPacket = bytes * outputInfo.mChannelsPerFrame;
outputInfo.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
// unsigned 8-bit or signed 16-bit integer PCM data.
if (outputInfo.mBitsPerChannel == 16)
outputInfo.mFormatFlags |= kAudioFormatFlagIsSignedInteger;
// Set the desired output format.
propertySize = sizeof(outputInfo);
err = ExtAudioFileSetProperty(extAudioFile, kExtAudioFileProperty_ClientDataFormat, propertySize, &outputInfo);
if (err != noErr)
throw love::Exception("Could not set decoder properties.");
}
catch (love::Exception &)
{
closeAudioFile();
throw;
}
sampleRate = (int) outputInfo.mSampleRate;
}
CoreAudioDecoder::~CoreAudioDecoder()
{
closeAudioFile();
}
void CoreAudioDecoder::closeAudioFile()
{
if (extAudioFile != nullptr)
ExtAudioFileDispose(extAudioFile);
else if (audioFile != nullptr)
AudioFileClose(audioFile);
extAudioFile = nullptr;
audioFile = nullptr;
}
bool CoreAudioDecoder::accepts(const std::string &ext)
{
UInt32 size = 0;
std::vector<UInt32> types;
// Get the size in bytes of the type array we're about to get.
OSStatus err = AudioFileGetGlobalInfoSize(kAudioFileGlobalInfo_ReadableTypes, sizeof(UInt32), nullptr, &size);
if (err != noErr)
return false;
types.resize(size / sizeof(UInt32));
// Get an array of supported types.
err = AudioFileGetGlobalInfo(kAudioFileGlobalInfo_ReadableTypes, 0, nullptr, &size, &types[0]);
if (err != noErr)
return false;
// Turn the extension string into a CFStringRef.
CFStringRef extstr = CFStringCreateWithCString(nullptr, ext.c_str(), kCFStringEncodingUTF8);
CFArrayRef exts = nullptr;
size = sizeof(CFArrayRef);
for (UInt32 type : types)
{
// Get the extension strings for the type.
err = AudioFileGetGlobalInfo(kAudioFileGlobalInfo_ExtensionsForType, sizeof(UInt32), &type, &size, &exts);
if (err != noErr)
continue;
// A type can have more than one extension string.
for (CFIndex i = 0; i < CFArrayGetCount(exts); i++)
{
CFStringRef value = (CFStringRef) CFArrayGetValueAtIndex(exts, i);
if (CFStringCompare(extstr, value, 0) == kCFCompareEqualTo)
{
CFRelease(extstr);
CFRelease(exts);
return true;
}
}
CFRelease(exts);
}
CFRelease(extstr);
return false;
}
love::sound::Decoder *CoreAudioDecoder::clone()
{
return new CoreAudioDecoder(data.get(), ext, bufferSize);
}
int CoreAudioDecoder::decode()
{
int size = 0;
while (size < bufferSize)
{
AudioBufferList dataBuffer;
dataBuffer.mNumberBuffers = 1;
dataBuffer.mBuffers[0].mDataByteSize = bufferSize - size;
dataBuffer.mBuffers[0].mData = (char *) buffer + size;
dataBuffer.mBuffers[0].mNumberChannels = outputInfo.mChannelsPerFrame;
UInt32 frames = (bufferSize - size) / outputInfo.mBytesPerFrame;
if (ExtAudioFileRead(extAudioFile, &frames, &dataBuffer) != noErr)
return size;
if (frames == 0)
{
eof = true;
break;
}
size += frames * outputInfo.mBytesPerFrame;
}
return size;
}
bool CoreAudioDecoder::seek(float s)
{
OSStatus err = ExtAudioFileSeek(extAudioFile, (SInt64) (s * inputInfo.mSampleRate));
if (err == noErr)
{
eof = false;
return true;
}
return false;
}
bool CoreAudioDecoder::rewind()
{
OSStatus err = ExtAudioFileSeek(extAudioFile, 0);
if (err == noErr)
{
eof = false;
return true;
}
return false;
}
bool CoreAudioDecoder::isSeekable()
{
return true;
}
int CoreAudioDecoder::getChannels() const
{
return outputInfo.mChannelsPerFrame;
}
int CoreAudioDecoder::getBitDepth() const
{
return outputInfo.mBitsPerChannel;
}
} // lullaby
} // sound
} // love
#endif // LOVE_SUPPORT_COREAUDIO
@@ -0,0 +1,81 @@
/**
* Copyright (c) 2006-2015 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_SOUND_LULLABY_CORE_AUDIO_DECODER_H
#define LOVE_SOUND_LULLABY_CORE_AUDIO_DECODER_H
#include "common/config.h"
#ifdef LOVE_SUPPORT_COREAUDIO
// LOVE
#include "common/Data.h"
#include "Decoder.h"
// Core Audio
#include <AudioToolbox/AudioFormat.h>
#include <AudioToolbox/ExtendedAudioFile.h>
namespace love
{
namespace sound
{
namespace lullaby
{
/**
* Decoder which supports all formats handled by Apple's Core Audio framework.
**/
class CoreAudioDecoder : public Decoder
{
public:
CoreAudioDecoder(Data *data, const std::string &ext, int bufferSize);
virtual ~CoreAudioDecoder();
static bool accepts(const std::string &ext);
love::sound::Decoder *clone();
int decode();
bool seek(float s);
bool rewind();
bool isSeekable();
int getChannels() const;
int getBitDepth() const;
private:
void closeAudioFile();
AudioFileID audioFile;
ExtAudioFileRef extAudioFile;
AudioStreamBasicDescription inputInfo;
AudioStreamBasicDescription outputInfo;
}; // CoreAudioDecoder
} // lullaby
} // sound
} // love
#endif // LOVE_SUPPORT_COREAUDIO
#endif // LOVE_SOUND_LULLABY_CORE_AUDIO_DECODER_H
@@ -27,7 +27,7 @@
#include "common/Data.h"
#include "Decoder.h"
#ifdef LOVE_MACOSX_USE_FRAMEWORKS
#ifdef LOVE_APPLE_USE_FRAMEWORKS
#include <Game_Music_Emu/gme.h>
#else
#include <gme.h>
@@ -17,9 +17,11 @@
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "common/config.h"
#include "ModPlugDecoder.h"
#ifndef LOVE_NO_MODPLUG
#include "common/Exception.h"
namespace love
@@ -45,11 +47,8 @@ ModPlugDecoder::ModPlugDecoder(Data *data, const std::string &ext, int bufferSiz
// garbage settings when the struct is only partially initialized)
// This does not exist yet on Windows.
// Some settings not supported by some older versions
#ifndef LOVE_OLD_MODPLUG
settings.mStereoSeparation = 128;
settings.mMaxMixChannels = 32;
#endif
settings.mReverbDepth = 0;
settings.mReverbDelay = 0;
settings.mBassAmount = 0;
@@ -145,3 +144,5 @@ int ModPlugDecoder::getBitDepth() const
} // lullaby
} // sound
} // love
#endif // LOVE_NO_MODPLUG
@@ -21,6 +21,10 @@
#ifndef LOVE_SOUND_LULLABY_MODPLUG_DECODER_H
#define LOVE_SOUND_LULLABY_MODPLUG_DECODER_H
#include "common/config.h"
#ifndef LOVE_NO_MODPLUG
// LOVE
#include "common/Data.h"
#include "Decoder.h"
@@ -62,4 +66,6 @@ private:
} // sound
} // love
#endif // LOVE_NO_MODPLUG
#endif // LOVE_SOUND_LULLABY_MODPLUG_DECODER_H
@@ -26,7 +26,7 @@
#include "Decoder.h"
// libmpg123
#ifdef LOVE_MACOSX_USE_FRAMEWORKS
#ifdef LOVE_APPLE_USE_FRAMEWORKS
#include <mpg123/mpg123.h>
#else
#include <mpg123.h>
+13 -1
View File
@@ -34,6 +34,10 @@
# include "Mpg123Decoder.h"
#endif // LOVE_NOMPG123
#ifdef LOVE_SUPPORT_COREAUDIO
# include "CoreAudioDecoder.h"
#endif
namespace love
{
namespace sound
@@ -65,8 +69,12 @@ sound::Decoder *Sound::newDecoder(love::filesystem::FileData *data, int bufferSi
sound::Decoder *decoder = 0;
// Find a suitable decoder here, and return it.
if (ModPlugDecoder::accepts(ext))
if (false)
/* nothing */;
#ifndef LOVE_NO_MODPLUG
else if (ModPlugDecoder::accepts(ext))
decoder = new ModPlugDecoder(data, ext, bufferSize);
#endif // LOVE_NO_MODPLUG
#ifndef LOVE_NOMPG123
else if (Mpg123Decoder::accepts(ext))
decoder = new Mpg123Decoder(data, ext, bufferSize);
@@ -77,6 +85,10 @@ sound::Decoder *Sound::newDecoder(love::filesystem::FileData *data, int bufferSi
else if (GmeDecoder::accepts(ext))
decoder = new GmeDecoder(data, ext, bufferSize);
#endif // LOVE_SUPPORT_GME
#ifdef LOVE_SUPPORT_COREAUDIO
else if (CoreAudioDecoder::accepts(ext))
decoder = new CoreAudioDecoder(data, ext, bufferSize);
#endif
else if (WaveDecoder::accepts(ext))
decoder = new WaveDecoder(data, ext, bufferSize);
/*else if (FLACDecoder::accepts(ext))
@@ -63,7 +63,7 @@ static size_t vorbisRead(void *ptr /* ptr to the data that the vorbis files need
if (actualSizeToRead)
{
// Copy the data from the start of the file PLUS how much we have already read in
memcpy(ptr, (char *)vorbisData->dataPtr + vorbisData->dataRead, actualSizeToRead);
memcpy(ptr, (const char *)vorbisData->dataPtr + vorbisData->dataRead, actualSizeToRead);
// Increase by how much we have read by
vorbisData->dataRead += (actualSizeToRead);
}
@@ -109,7 +109,7 @@ static int vorbisSeek(void *datasource /* ptr to the data that the vorbis files
vorbisData->dataRead = vorbisData->dataSize+1;
break;
default:
throw love::Exception("Unknown seek command in vorbisSeek\n");
throw love::Exception("Unknown seek command in vorbisSeek");
break;
};
@@ -143,8 +143,8 @@ VorbisDecoder::VorbisDecoder(Data *data, const std::string &ext, int bufferSize)
#endif
// Initialize OGG file
oggFile.dataPtr = (char *) data->getData();
oggFile.dataSize = data->getSize();
oggFile.dataPtr = (const char *) data->getData();
oggFile.dataSize = (int) data->getSize();
oggFile.dataRead = 0;
// Open Vorbis handle
@@ -188,7 +188,7 @@ int VorbisDecoder::decode()
while (size < bufferSize)
{
int result = ov_read(&handle, (char *) buffer + size, bufferSize - size, endian, (getBitDepth() == 16 ? 2 : 1), 1, 0);
long result = ov_read(&handle, (char *) buffer + size, bufferSize - size, endian, (getBitDepth() == 16 ? 2 : 1), 1, 0);
if (result == OV_HOLE)
continue;
@@ -250,7 +250,7 @@ int VorbisDecoder::getBitDepth() const
int VorbisDecoder::getSampleRate() const
{
return vorbisInfo->rate;
return (int) vorbisInfo->rate;
}
} // lullaby
@@ -40,7 +40,7 @@ namespace lullaby
// Struct for handling data
struct SOggFile
{
char *dataPtr; // Pointer to the data in memory
const char *dataPtr; // Pointer to the data in memory
int dataSize; // Size of the data
int dataRead; // How much we've read so far
};
@@ -126,8 +126,8 @@ int WaveDecoder::decode()
while (size < (size_t) bufferSize)
{
size_t bytes = bufferSize;
int wuff_status = wuff_read(handle, (wuff_uint8 *) buffer, &bytes);
size_t bytes = bufferSize-size;
int wuff_status = wuff_read(handle, (wuff_uint8 *) buffer+size, &bytes);
if (wuff_status < 0)
return 0;
@@ -140,7 +140,7 @@ int WaveDecoder::decode()
size += bytes;
}
return size;
return (int) size;
}
bool WaveDecoder::seek(float s)
+2 -2
View File
@@ -27,7 +27,7 @@ namespace sound
Decoder *luax_checkdecoder(lua_State *L, int idx)
{
return luax_checktype<Decoder>(L, idx, "Decoder", SOUND_DECODER_T);
return luax_checktype<Decoder>(L, idx, SOUND_DECODER_ID);
}
int w_Decoder_getChannels(lua_State *L)
@@ -61,7 +61,7 @@ static const luaL_Reg functions[] =
extern "C" int luaopen_decoder(lua_State *L)
{
return luax_register_type(L, "Decoder", functions);
return luax_register_type(L, SOUND_DECODER_ID, functions);
}
} // sound
+10 -10
View File
@@ -38,10 +38,10 @@ int w_newSoundData(lua_State *L)
if (lua_isnumber(L, 1))
{
int samples = luaL_checkint(L, 1);
int sampleRate = luaL_optint(L, 2, Decoder::DEFAULT_SAMPLE_RATE);
int bitDepth = luaL_optint(L, 3, Decoder::DEFAULT_BIT_DEPTH);
int channels = luaL_optint(L, 4, Decoder::DEFAULT_CHANNELS);
int samples = (int) luaL_checknumber(L, 1);
int sampleRate = (int) luaL_optnumber(L, 2, Decoder::DEFAULT_SAMPLE_RATE);
int bitDepth = (int) luaL_optnumber(L, 3, Decoder::DEFAULT_BIT_DEPTH);
int channels = (int) luaL_optnumber(L, 4, Decoder::DEFAULT_CHANNELS);
luax_catchexcept(L, [&](){ t = instance()->newSoundData(samples, sampleRate, bitDepth, channels); });
}
@@ -49,7 +49,7 @@ int w_newSoundData(lua_State *L)
else
{
// Convert to Decoder, if necessary.
if (!luax_istype(L, 1, SOUND_DECODER_T))
if (!luax_istype(L, 1, SOUND_DECODER_ID))
{
w_newDecoder(L);
lua_replace(L, 1);
@@ -58,7 +58,7 @@ int w_newSoundData(lua_State *L)
luax_catchexcept(L, [&](){ t = instance()->newSoundData(luax_checkdecoder(L, 1)); });
}
luax_pushtype(L, "SoundData", SOUND_SOUND_DATA_T, t);
luax_pushtype(L, SOUND_SOUND_DATA_ID, t);
t->release();
return 1;
}
@@ -66,18 +66,18 @@ int w_newSoundData(lua_State *L)
int w_newDecoder(lua_State *L)
{
love::filesystem::FileData *data = love::filesystem::luax_getfiledata(L, 1);
int bufferSize = luaL_optint(L, 2, Decoder::DEFAULT_BUFFER_SIZE);
int bufferSize = (int) luaL_optnumber(L, 2, Decoder::DEFAULT_BUFFER_SIZE);
Decoder *t = nullptr;
luax_catchexcept(L,
[&]() { t = instance()->newDecoder(data, bufferSize); },
[&]() { data->release(); }
[&](bool) { data->release(); }
);
if (t == nullptr)
return luaL_error(L, "Extension \"%s\" not supported.", data->getExtension().c_str());
luax_pushtype(L, "Decoder", SOUND_DECODER_T, t);
luax_pushtype(L, SOUND_DECODER_ID, t);
t->release();
return 1;
}
@@ -111,7 +111,7 @@ extern "C" int luaopen_love_sound(lua_State *L)
WrappedModule w;
w.module = instance;
w.name = "sound";
w.flags = MODULE_SOUND_T;
w.type = MODULE_SOUND_ID;
w.functions = functions;
w.types = types;
+27 -2
View File
@@ -22,14 +22,24 @@
#include "common/wrap_Data.h"
// Shove the wrap_SoundData.lua code directly into a raw string literal.
static const char sounddata_lua[] =
#include "wrap_SoundData.lua"
;
namespace love
{
namespace sound
{
/**
* NOTE: Additional wrapper code is in wrap_SoundData.lua. Be sure to keep it
* in sync with any changes made to this file!
**/
SoundData *luax_checksounddata(lua_State *L, int idx)
{
return luax_checktype<SoundData>(L, idx, "SoundData", SOUND_SOUND_DATA_T);
return luax_checktype<SoundData>(L, idx, SOUND_SOUND_DATA_ID);
}
int w_SoundData_getChannels(lua_State *L)
@@ -105,7 +115,22 @@ static const luaL_Reg functions[] =
extern "C" int luaopen_sounddata(lua_State *L)
{
return luax_register_type(L, "SoundData", functions);
// The last argument pushes the type's metatable onto the stack.
int ret = luax_register_type(L, SOUND_SOUND_DATA_ID, functions, true);
// Load and execute SoundData.lua, sending the metatable as an argument.
if (ret > 0)
{
luaL_loadbuffer(L, sounddata_lua, sizeof(sounddata_lua), "SoundData.lua");
lua_pushvalue(L, -2);
lua_call(L, 1, 0);
// Pop the metatable.
lua_pop(L, 1);
ret--;
}
return ret;
}
} // sound
@@ -0,0 +1,123 @@
R"luastring"--(
-- DO NOT REMOVE THE ABOVE LINE. It is used to load this file as a C++ string.
-- There is a matching delimiter at the bottom of the file.
--[[
Copyright (c) 2006-2015 LOVE Development Team
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
--]]
local SoundData_mt = ...
if type(jit) ~= "table" or not jit.status() then
-- LuaJIT's FFI is *much* slower than LOVE's regular methods when the JIT
-- compiler is disabled.
return
end
local status, ffi = pcall(require, "ffi")
if not status then return end
local tonumber, assert = tonumber, assert
local float = ffi.typeof("float")
local datatypes = {ffi.typeof("uint8_t *"), ffi.typeof("int16_t *")}
local typemaxvals = {0x7F, 0x7FFF}
local _getBitDepth = SoundData_mt.__index.getBitDepth
local _getSampleCount = SoundData_mt.__index.getSampleCount
local _getSampleRate = SoundData_mt.__index.getSampleRate
local _getChannels = SoundData_mt.__index.getChannels
local _getDuration = SoundData_mt.__index.getDuration
-- Table which holds SoundData objects as keys, and information about the objects
-- as values. Uses weak keys so the SoundData objects can still be GC'd properly.
local objectcache = setmetatable({}, {
__mode = "k",
__index = function(self, sounddata)
local bytedepth = _getBitDepth(sounddata) / 8
local pointer = ffi.cast(datatypes[bytedepth], sounddata:getPointer())
local p = {
bytedepth = bytedepth,
pointer = pointer,
size = sounddata:getSize(),
maxvalue = typemaxvals[bytedepth],
samplecount = _getSampleCount(sounddata),
samplerate = _getSampleRate(sounddata),
channels = _getChannels(sounddata),
duration = _getDuration(sounddata),
}
self[sounddata] = p
return p
end,
})
-- Overwrite existing functions with new FFI versions.
function SoundData_mt.__index:getSample(i)
local p = objectcache[self]
assert(i >= 0 and i < p.size/p.bytedepth, "Attempt to get out-of-range sample!")
if p.bytedepth == 2 then
-- 16-bit data is stored as signed values internally.
return tonumber(p.pointer[i]) / p.maxvalue
else
-- 8-bit data is stored as unsigned values internally.
return (tonumber(p.pointer[i]) - 128) / 127
end
end
function SoundData_mt.__index:setSample(i, sample)
local p = objectcache[self]
assert(i >= 0 and i < p.size/p.bytedepth, "Attempt to set out-of-range sample!")
if p.bytedepth == 2 then
-- 16-bit data is stored as signed values internally.
p.pointer[i] = sample * p.maxvalue
else
-- 8-bit data is stored as unsigned values internally.
-- The float cast is needed to make values end up the same as in the
-- C++ version of this method.
p.pointer[i] = ffi.cast(float, (sample * 127) + 128)
end
end
function SoundData_mt.__index:getBitDepth()
return objectcache[self].bytedepth * 8
end
function SoundData_mt.__index:getSampleCount()
return objectcache[self].samplecount
end
function SoundData_mt.__index:getSampleRate()
return objectcache[self].samplerate
end
function SoundData_mt.__index:getChannels()
return objectcache[self].channels
end
function SoundData_mt.__index:getDuration()
return objectcache[self].duration
end
-- DO NOT REMOVE THE NEXT LINE. It is used to load this file as a C++ string.
--)luastring"--"