love.sound - examples?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
NÖÖB
Prole
Posts: 41
Joined: Thu Jul 31, 2008 10:57 pm
Location: Norway

love.sound - examples?

Post by NÖÖB »

I'm reading the wiki on love.sound and its types and functions, but I can't wrap my head around it..
I'm under the assumption that it'll let me create sound data in code, and then stream it through a decoder, resulting in -say, a sine wave coming out of my speakers.

Can anyone provide examples on love.sound usage -preferably related to what I described (If my assumtion isn't erroneous, that is).
User avatar
BlackBulletIV
Inner party member
Posts: 1261
Joined: Wed Dec 29, 2010 8:19 pm
Location: Queensland, Australia
Contact:

Re: love.sound - examples?

Post by BlackBulletIV »

Using love.sound.SoundData is good thing to do for sound effects. SoundData holds the raw data for a sound, already decoded. This means you can play it many times with much less overhead:

Code: Select all

data = love.sound.newSoundData("file.mp3") -- create decoded data
sources = {} -- a pool of sources

for i = 1, 20 do
    table.insert(sources, love.audio.newSource(data)) -- create multiple sources
end
That's only thing I've done with love.sound so far.
User avatar
NÖÖB
Prole
Posts: 41
Joined: Thu Jul 31, 2008 10:57 pm
Location: Norway

Re: love.sound - examples?

Post by NÖÖB »

Hey, thanks for answering ^^
Do you have to use "file.xxx"? Or is it possible to fill data with values of varying amplitude, approximating a sine, or triangle waveform, and then play that data in memory?
User avatar
Taehl
Dreaming in associative arrays
Posts: 1025
Joined: Mon Jan 11, 2010 5:07 am
Location: CA, USA
Contact:

Re: love.sound - examples?

Post by Taehl »

I think what you're looking for is setSample.
Earliest Love2D supporter who can't Love anymore. Let me disable pixel shaders if I don't use them, dammit!
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.
User avatar
BlackBulletIV
Inner party member
Posts: 1261
Joined: Wed Dec 29, 2010 8:19 pm
Location: Queensland, Australia
Contact:

Re: love.sound - examples?

Post by BlackBulletIV »

You can probably create what you're looking for with this constructor type:

Code: Select all

sounddata = love.sound.newSoundData( samples, rate, bits, channels )
However it doesn't have much documentation on how to use, and I've never used it myself.

EDIT: You may want to take a look at this code from Moan (a Love game/app using procedurally generated sound):

Code: Select all

Moan = {}
Moan.osc = {}
Moan.env = {}

function Moan.osc.rect(f, a)
	local a = a or 1
	return function(t) return ((f*t)%1) > .5 and a or -a end
end

function Moan.osc.triangle(f, a)
	local a = a or 1
	return function(t)
		local t = ((f*t) % 1)
		return t < .5 and a * (4*t - 1) or a * (3 - 4*t)
	end
end

function Moan.osc.saw(f, a)
	local a = a or 1
	return function(t)
		local t = ((f*t) % 1)
		return a * (2*t - 1)
	end
end

function Moan.osc.sin(f, a)
	local a = a or 1
	return function(t)
		local t = ((f*t) % 1)
		return a * math.sin(2*math.pi*t)
	end
end

function Moan.osc.whitenoise()
	local a = a or 1
	return function() return a * (math.random() * 2 - 1) end
end
Moan.osc.wn = Moan.osc.whitenoise

function Moan.osc.pinknoise()
	local a = a or 1
	local last = 0
	return function()
		last = math.max(-1, math.min(1, last + math.random() * 2 - 1))
		return a * last
	end
end
Moan.osc.pn = Moan.osc.pinknoise

function Moan.env.rise(len, delay)
	local delay = delay or 0
	return function(t) return math.max(0, math.min(1, (t-delay)/len)) end
end

function Moan.env.fall(l, d)
	local delay = delay or 0
	return function(t) return math.min(1, math.max(0, 1-(t-delay)/len)) end
end

function Moan.env.risefall(attack,sustain,release)
	return function(t)
		if t > attack + sustain then
			return math.max(0, 1 - (t - sustain - attack) / release)
		end
		return math.min(1, t / rise)
	end
end

function Moan.env.adsr(attack,decay,sustain,release, peak,level)
	local peak = peak or 1
	local level = level or peak
	if level > peak then level = peak end

	return function(t)
		if t > attack + decay + sustain then -- release
			return math.max(0, level * (1 - (t - sustain - decay - attack) / release))
		elseif t > attack + decay then -- sustain
			return level
		elseif t > attack then -- decay
			return level + (peak - level) * (1 - (t - attack) / decay)
		end
		-- attack
		return peak * t / attack
	end
end

function Moan.envelope(f, ...)
	local envelopes = {...}
	return function(t)
		local r = f(t)
		for _,g in ipairs(envelopes) do
			r = r * g(t)
		end
		return r
	end
end

function Moan.map(f, g)
	return function(t) return g(f(t)) end
end

function Moan.compress(f)
	return Moan.map(f, math.tanh)
end

function Moan.newSample(gen, len, samplerate, bits)
	local len = len or 1
	local samplerate = samplerate or 44100
	local bits = bits or 16
	local samples = math.floor(len * samplerate)
	local data = love.sound.newSoundData(samples, samplerate, bits, 1)
	for i = 0,samples do
		data:setSample(i, gen(i / samplerate))
	end
	return data
end

Moan.fractions = {
	["c"]  = math.pow(math.pow(2,1/12), -9),
	["c#"] = math.pow(math.pow(2,1/12), -8),
	["d"]  = math.pow(math.pow(2,1/12), -7),
	["d#"] = math.pow(math.pow(2,1/12), -6),
	["e"]  = math.pow(math.pow(2,1/12), -5),
	["f"]  = math.pow(math.pow(2,1/12), -4),
	["f#"] = math.pow(math.pow(2,1/12), -3),
	["g"]  = math.pow(math.pow(2,1/12), -2),
	["g#"] = 1 / math.pow(2,1/12),
	["a"]  = 1, -- standard pitch, see Moan.base
	["a#"] = math.pow(2,1/12),
	["b"]  = math.pow(2,1/12) * math.pow(2,1/12),
}
Moan.fractions["db"] = Moan.fractions["c#"]
Moan.fractions["eb"] = Moan.fractions["c#"]
Moan.fractions["gb"] = Moan.fractions["f#"]
Moan.fractions["ab"] = Moan.fractions["g#"]
Moan.fractions["bb"] = Moan.fractions["a#"]

function Moan.base(n)
	return 440 * math.pow(2, n - 4)
end

function Moan.pitch(p, octave)
	local octave = octave or 4
	octave = Moan.base(octave)
	return Moan.fractions[p] * octave
end
Particularly this function:

Code: Select all

function Moan.newSample(gen, len, samplerate, bits)
	local len = len or 1
	local samplerate = samplerate or 44100
	local bits = bits or 16
	local samples = math.floor(len * samplerate)
	local data = love.sound.newSoundData(samples, samplerate, bits, 1)
	for i = 0,samples do
		data:setSample(i, gen(i / samplerate))
	end
	return data
end
I assume that samples is the number of samples to create in the sound file, and samplerate is how fast those samples go by. setSample then sets a sample to a particular value.
Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests