Browse Source

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
Bart van Strien 7 years ago
parent
commit
ac12424bab

+ 16 - 0
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

+ 2 - 0
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:
 

+ 19 - 3
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;
 }
 

+ 22 - 2
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