Browse Source

Add SoundData:copyFrom

SoundData:copyFrom(src, srcStart, count, dstStart = 0)
Miku AuahDark 4 years ago
parent
commit
e71441d68b

+ 27 - 0
src/modules/sound/SoundData.cpp

@@ -258,5 +258,32 @@ float SoundData::getSample(int i, int channel) const
 	return getSample(i * channels + (channel - 1));
 	return getSample(i * channels + (channel - 1));
 }
 }
 
 
+void SoundData::copyFrom(const SoundData *src, int srcStart, int count, int dstStart)
+{
+	if (channels != src->channels)
+		throw love::Exception("Channel count mismatch!");
+
+	size_t bytesPerSample = (size_t) channels * bitDepth/8;
+	size_t srcBytesPerSample = (size_t) src->channels * src->bitDepth/8;
+	
+	// Check range
+	if (dstStart < 0 || (dstStart+count) * bytesPerSample >= size)
+		throw love::Exception("Destination out-of-range!");
+	if (srcStart < 0 || (srcStart+count) * srcBytesPerSample >= src->size)
+		throw love::Exception("Source out-of-range!");
+
+	if (bitDepth != src->bitDepth)
+	{
+		// Bit depth mismatch, use get/setSample at loop
+		for (int i = 0; i < count * channels; i++)
+			setSample(dstStart + i, src->getSample(srcStart + i));
+	}
+	else if (this->data == src->data)
+		// May overlap, use memmove
+		memmove(data + dstStart * bytesPerSample, src->data + srcStart * bytesPerSample, count * bytesPerSample);
+	else
+		memcpy(data + dstStart * bytesPerSample, src->data + srcStart * bytesPerSample, count * bytesPerSample);
+}
+
 } // sound
 } // sound
 } // love
 } // love

+ 2 - 0
src/modules/sound/SoundData.h

@@ -61,6 +61,8 @@ public:
 	float getSample(int i) const;
 	float getSample(int i) const;
 	float getSample(int i, int channel) const;
 	float getSample(int i, int channel) const;
 
 
+	void copyFrom(const SoundData *src, int srcStart, int count, int dstStart);
+
 private:
 private:
 
 
 	void load(int samples, int sampleRate, int bitDepth, int channels, void *newData = 0);
 	void load(int samples, int sampleRate, int bitDepth, int channels, void *newData = 0);

+ 14 - 0
src/modules/sound/wrap_SoundData.cpp

@@ -121,6 +121,19 @@ int w_SoundData_getSample(lua_State *L)
 	return 1;
 	return 1;
 }
 }
 
 
+int w_SoundData_copyFrom(lua_State *L)
+{
+	SoundData *dst = luax_checksounddata(L, 1);
+	const SoundData *src = luax_checksounddata(L, 2);
+
+	int srcStart = (int) luaL_checkinteger(L, 3);
+	int count = (int) luaL_checkinteger(L, 4);
+	int dstStart = (int) luaL_optinteger(L, 5, 0);
+
+	luax_catchexcept(L, [&](){ dst->copyFrom(src, srcStart, count, dstStart); });
+	return 0;
+}
+
 static const luaL_Reg w_SoundData_functions[] =
 static const luaL_Reg w_SoundData_functions[] =
 {
 {
 	{ "clone", w_SoundData_clone },
 	{ "clone", w_SoundData_clone },
@@ -131,6 +144,7 @@ static const luaL_Reg w_SoundData_functions[] =
 	{ "getDuration", w_SoundData_getDuration },
 	{ "getDuration", w_SoundData_getDuration },
 	{ "setSample", w_SoundData_setSample },
 	{ "setSample", w_SoundData_setSample },
 	{ "getSample", w_SoundData_getSample },
 	{ "getSample", w_SoundData_getSample },
+	{ "copyFrom", w_SoundData_copyFrom },
 
 
 	{ 0, 0 }
 	{ 0, 0 }
 };
 };