From ac12424bab686bd3b15584de4f0fd6e33579a1e5 Mon Sep 17 00:00:00 2001 From: Bart van Strien Date: Wed, 4 Oct 2017 13:56:14 +0200 Subject: [PATCH] Add optional channel parameter to SoundData:getSample/setSample (resolves #1346) If omitted they work as before, if specified it handles the interleaving internally. --HG-- branch : minor --- src/modules/sound/SoundData.cpp | 16 ++++++++++++++++ src/modules/sound/SoundData.h | 2 ++ src/modules/sound/wrap_SoundData.cpp | 22 +++++++++++++++++++--- src/modules/sound/wrap_SoundData.lua | 24 ++++++++++++++++++++++-- 4 files changed, 59 insertions(+), 5 deletions(-) diff --git a/src/modules/sound/SoundData.cpp b/src/modules/sound/SoundData.cpp index f936bb867..ec5686274 100644 --- a/src/modules/sound/SoundData.cpp +++ b/src/modules/sound/SoundData.cpp @@ -223,6 +223,14 @@ void SoundData::setSample(int i, float sample) } } +void SoundData::setSample(int i, int channel, float sample) +{ + if (channel < 1 || channel > channels) + throw love::Exception("Attempt to set sample from out-of-range channel!"); + + return setSample(i * channels + (channel - 1), sample); +} + float SoundData::getSample(int i) const { // Check range. @@ -242,5 +250,13 @@ float SoundData::getSample(int i) const } } +float SoundData::getSample(int i, int channel) const +{ + if (channel < 1 || channel > channels) + throw love::Exception("Attempt to get sample from out-of-range channel!"); + + return getSample(i * channels + (channel - 1)); +} + } // sound } // love diff --git a/src/modules/sound/SoundData.h b/src/modules/sound/SoundData.h index d5517c66f..1e3fb437b 100644 --- a/src/modules/sound/SoundData.h +++ b/src/modules/sound/SoundData.h @@ -57,7 +57,9 @@ public: virtual float getDuration() const; void setSample(int i, float sample); + void setSample(int i, int channel, float sample); float getSample(int i) const; + float getSample(int i, int channel) const; private: diff --git a/src/modules/sound/wrap_SoundData.cpp b/src/modules/sound/wrap_SoundData.cpp index 9344835ae..77e5fd4e5 100644 --- a/src/modules/sound/wrap_SoundData.cpp +++ b/src/modules/sound/wrap_SoundData.cpp @@ -90,9 +90,19 @@ int w_SoundData_setSample(lua_State *L) { SoundData *sd = luax_checksounddata(L, 1); int i = (int) luaL_checkinteger(L, 2); - float sample = (float) luaL_checknumber(L, 3); - luax_catchexcept(L, [&](){ sd->setSample(i, sample); }); + if (lua_gettop(L) > 3) + { + int channel = luaL_checkinteger(L, 3); + float sample = (float) luaL_checknumber(L, 4); + luax_catchexcept(L, [&](){ sd->setSample(i, channel, sample); }); + } + else + { + float sample = (float) luaL_checknumber(L, 3); + luax_catchexcept(L, [&](){ sd->setSample(i, sample); }); + } + return 0; } @@ -101,7 +111,13 @@ int w_SoundData_getSample(lua_State *L) SoundData *sd = luax_checksounddata(L, 1); int i = (int) luaL_checkinteger(L, 2); - luax_catchexcept(L, [&](){ lua_pushnumber(L, sd->getSample(i)); }); + if (lua_gettop(L) > 2) + { + int channel = luaL_checkinteger(L, 3); + luax_catchexcept(L, [&](){ lua_pushnumber(L, sd->getSample(i, channel)); }); + } + else + luax_catchexcept(L, [&](){ lua_pushnumber(L, sd->getSample(i)); }); return 1; } diff --git a/src/modules/sound/wrap_SoundData.lua b/src/modules/sound/wrap_SoundData.lua index 729c97b9c..dfa48bfab 100644 --- a/src/modules/sound/wrap_SoundData.lua +++ b/src/modules/sound/wrap_SoundData.lua @@ -76,13 +76,21 @@ local objectcache = setmetatable({}, { -- Overwrite existing functions with new FFI versions. -function SoundData:getSample(i) +function SoundData:getSample(i, channel) if type(i) ~= "number" then error("bad argument #1 to SoundData:getSample (expected number)", 2) end + if channel ~= nil and type(channel) ~= "number" then error("bad argument #2 to SoundData:getSample (expected number)", 2) end i = floor(i) local p = objectcache[self] + if channel then + if channel < 1 or channel > p.channels then + error("Attempt to get sample from out-of-range channel!", 2) + end + i = i * p.channels + (channel-1) + end + if not (i >= 0 and i < p.size/p.bytedepth) then error("Attempt to get out-of-range sample!", 2) end @@ -96,14 +104,26 @@ function SoundData:getSample(i) end end -function SoundData:setSample(i, sample) +function SoundData:setSample(i, channel, sample) if type(i) ~= "number" then error("bad argument #1 to SoundData:setSample (expected number)", 2) end + if sample ~= nil then + if type(channel) ~= "number" then error("bad argument #2 to SoundData:setSample (expected number)", 2) end + else + sample, channel = channel, nil + end if type(sample) ~= "number" then error("bad argument #2 to SoundData:setSample (expected number)", 2) end i = floor(i) local p = objectcache[self] + if channel then + if channel < 1 or channel > p.channels then + error("Attempt to set sample from out-of-range channel!", 2) + end + i = i * p.channels + (channel-1) + end + if not (i >= 0 and i < p.size/p.bytedepth) then error("Attempt to set out-of-range sample!", 2) end