From 04b20624b2ca73ee23a75e050b1ab41aeda8381b Mon Sep 17 00:00:00 2001 From: Miku AuahDark Date: Tue, 22 Sep 2020 13:09:03 +0800 Subject: [PATCH] Add SoundData:slice SoundData:slice(start, length = -1) When length = -1, it will slice until the end. --- src/modules/sound/SoundData.cpp | 19 +++++++++++++++++-- src/modules/sound/SoundData.h | 5 +++-- src/modules/sound/wrap_SoundData.cpp | 13 +++++++++++++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/modules/sound/SoundData.cpp b/src/modules/sound/SoundData.cpp index 9b81044e0..9bbc76dd7 100644 --- a/src/modules/sound/SoundData.cpp +++ b/src/modules/sound/SoundData.cpp @@ -98,7 +98,7 @@ SoundData::SoundData(int samples, int sampleRate, int bitDepth, int channels) load(samples, sampleRate, bitDepth, channels); } -SoundData::SoundData(void *d, int samples, int sampleRate, int bitDepth, int channels) +SoundData::SoundData(const void *d, int samples, int sampleRate, int bitDepth, int channels) : data(0) , size(0) , sampleRate(0) @@ -129,7 +129,7 @@ SoundData *SoundData::clone() const return new SoundData(*this); } -void SoundData::load(int samples, int sampleRate, int bitDepth, int channels, void *newData) +void SoundData::load(int samples, int sampleRate, int bitDepth, int channels, const void *newData) { if (samples <= 0) throw love::Exception("Invalid sample count: %d", samples); @@ -285,5 +285,20 @@ void SoundData::copyFrom(const SoundData *src, int srcStart, int count, int dstS memcpy(data + dstStart * bytesPerSample, src->data + srcStart * bytesPerSample, count * bytesPerSample); } +SoundData *SoundData::slice(int start, int length) const +{ + int totalSamples = getSampleCount(); + + if (length == 0) + throw love::Exception("Invalid slice length: 0"); + else if (length < 0) + length = totalSamples - start; + + if (start < 0 || start + length > totalSamples) + throw love::Exception("Attempt to slice at out-of-range position!"); + + return new SoundData(data + start * channels * bitDepth/8, length, sampleRate, bitDepth, channels); +} + } // sound } // love diff --git a/src/modules/sound/SoundData.h b/src/modules/sound/SoundData.h index 431d18247..993cc0bfe 100644 --- a/src/modules/sound/SoundData.h +++ b/src/modules/sound/SoundData.h @@ -39,7 +39,7 @@ public: SoundData(Decoder *decoder); SoundData(int samples, int sampleRate, int bitDepth, int channels); - SoundData(void *d, int samples, int sampleRate, int bitDepth, int channels); + SoundData(const void *d, int samples, int sampleRate, int bitDepth, int channels); SoundData(const SoundData &c); virtual ~SoundData(); @@ -62,10 +62,11 @@ public: float getSample(int i, int channel) const; void copyFrom(const SoundData *src, int srcStart, int count, int dstStart); + SoundData *slice(int start, int length = -1) const; private: - void load(int samples, int sampleRate, int bitDepth, int channels, void *newData = 0); + void load(int samples, int sampleRate, int bitDepth, int channels, const void *newData = 0); uint8 *data; size_t size; diff --git a/src/modules/sound/wrap_SoundData.cpp b/src/modules/sound/wrap_SoundData.cpp index 5674ec681..87064fa8f 100644 --- a/src/modules/sound/wrap_SoundData.cpp +++ b/src/modules/sound/wrap_SoundData.cpp @@ -134,6 +134,18 @@ int w_SoundData_copyFrom(lua_State *L) return 0; } +int w_SoundData_slice(lua_State *L) +{ + SoundData *t = luax_checksounddata(L, 1), *c = nullptr; + int start = (int) luaL_checkinteger(L, 2); + int length = (int) luaL_optinteger(L, 3, -1); + + luax_catchexcept(L, [&](){ c = t->slice(start, length); }); + luax_pushtype(L, c); + c->release(); + return 1; +} + static const luaL_Reg w_SoundData_functions[] = { { "clone", w_SoundData_clone }, @@ -145,6 +157,7 @@ static const luaL_Reg w_SoundData_functions[] = { "setSample", w_SoundData_setSample }, { "getSample", w_SoundData_getSample }, { "copyFrom", w_SoundData_copyFrom }, + { "slice", w_SoundData_slice }, { 0, 0 } };