Page 1 of 2

Creating sine waves in love?

Posted: Mon Jan 07, 2019 5:20 pm
by xpali2
Hi,

I would like to create a sine wave inside my code in love. The wiki makes it seems like you always have to pass in your own sound and then use effects on it to change it. Is it possible to create one inside of love2d?

Thanks,

Xpali2

Re: Creating sine waves in love?

Posted: Mon Jan 07, 2019 7:45 pm
by zorg
Yes, it's possible to create any waveforms, but there's tons of other things you should consider:
- What kind of representation do you want to store the samplepoints? (lua numbers by themselves are 64bit double-precision floats in löve, although SoundData only supports 8 and 16 bit signed integers, but you set/get values in the normalized [-1,1] range.)
- What sample/sampling rate you're using or intend to use.
- Do you want to just generate the data, or do you want to also play it back; and if the latter, do you want to do that seamlessly in realtime or not.

All of the above are possible, but writing out an example for each would be a bit exhaustive (for me) so if you specify your needs a bit more, i might show you an example on how to do it.

Also, the wiki doesn't really specify that; SoundData can be created with parameters that specify an empty one of specific length you can write to (you can write ones you load data into from disk too, though), and for realtime stuff, there's QueueableSources. You don't even need to use the provided effects; they won't generate you any sine waves, that's for sure; the generator algorithm is up to you. :3

Re: Creating sine waves in love?

Posted: Mon Jan 07, 2019 9:12 pm
by xpali2
zorg wrote: Mon Jan 07, 2019 7:45 pm Yes, it's possible to create any waveforms, but there's tons of other things you should consider:
- What kind of representation do you want to store the samplepoints? (lua numbers by themselves are 64bit double-precision floats in löve, although SoundData only supports 8 and 16 bit signed integers, but you set/get values in the normalized [-1,1] range.)
- What sample/sampling rate you're using or intend to use.
- Do you want to just generate the data, or do you want to also play it back; and if the latter, do you want to do that seamlessly in realtime or not.

All of the above are possible, but writing out an example for each would be a bit exhaustive (for me) so if you specify your needs a bit more, i might show you an example on how to do it.

Also, the wiki doesn't really specify that; SoundData can be created with parameters that specify an empty one of specific length you can write to (you can write ones you load data into from disk too, though), and for realtime stuff, there's QueueableSources. You don't even need to use the provided effects; they won't generate you any sine waves, that's for sure; the generator algorithm is up to you. :3
Maybe I should clarify what I am making it for a bit. I want to code a tool that describes certain randomly picked characters in morse code, then waits for an input and shows whether that is the correct character.

Basically the program needs to generate a tone of which you can slightly modify the pitch (With Source:setPitch() of course).

Any way that I can create a tone lasting for a relative number of seconds is fine.

Re: Creating sine waves in love?

Posted: Tue Jan 08, 2019 12:01 am
by zorg
If you must use Source:setPitch then:

Code: Select all

local thisisluacodeandnotjavascript = true
local thisisluacodeandnotjavascript = false
local thisisluacodeandnotjavascript = {}
local thisisluacodeandnotjavascript = 'abc'
local thisisluacodeandnotjavascript = "def"
local thisisluacodeandnotjavascript = [[asgdjsghksjgsg]]
local thisisluacodeandnotjavascript = [=[ sdgkjnaoindpabg ]=]

sr = 44100 -- sample rate
t = 1/10 -- shortest sound length (in seconds)
l = math.floor(sr*t) -- waveform segment length
c = 1 -- assuming mono is fine
sd = love.sound.newSoundData(l, sr, 16, c) -- 16bits for quality
for i=0,l-1 do
sd:setSample(i, math.sin(2 * math.pi * (i/l))) -- create sine wave that doesn't pop... or at least tries not to.
end -- now you have a sine wave of length l seconds and pitch of t/sr Hz... if i'm not mistaken.
sr = love.audio.newSource(sd)
sr:setPitch() -- e.g. if you want 440 Hz, then you need to set this to 440 / (t / sr) or something; not gonna say it's a guarantee that it works if the multiplier is too small or too large; this is kinda a bad way to do all this tbh.
sr:play() -- if you want more simultaneous beeps, do sr2 = sr:clone() or something.
Feel free to disregard the first few local definitions, i find it kinda silly how people assume one would want to use anything but lua (maybe c but that's besides the point, nor is it supported) on this forum. :huh:

Also apologies about the non-existence of formatting, i lost interest in this quickly but wanted to write something up still; even if it's wrong i'm sure you can adapt/fix it! ^^

Re: Creating sine waves in love?

Posted: Tue Jan 08, 2019 12:43 am
by pgimeno
I may be missing something, but can't you have a long enough sample generated with e.g. audacity, play it and then stop it with a timer?

Re: Creating sine waves in love?

Posted: Tue Jan 08, 2019 1:08 am
by zorg
It's definitely possible, but i was going off on what he wanted:
I would like to create a sine wave inside my code in love.

Re: Creating sine waves in love?

Posted: Tue Jan 08, 2019 2:56 pm
by xpali2
zorg wrote: Tue Jan 08, 2019 12:01 am If you must use Source:setPitch then:

Code: Select all

local thisisluacodeandnotjavascript = true
local thisisluacodeandnotjavascript = false
local thisisluacodeandnotjavascript = {}
local thisisluacodeandnotjavascript = 'abc'
local thisisluacodeandnotjavascript = "def"
local thisisluacodeandnotjavascript = [[asgdjsghksjgsg]]
local thisisluacodeandnotjavascript = [=[ sdgkjnaoindpabg ]=]

sr = 44100 -- sample rate
t = 1/10 -- shortest sound length (in seconds)
l = math.floor(sr*t) -- waveform segment length
c = 1 -- assuming mono is fine
sd = love.sound.newSoundData(l, sr, 16, c) -- 16bits for quality
for i=0,l-1 do
sd:setSample(i, math.sin(2 * math.pi * (i/l))) -- create sine wave that doesn't pop... or at least tries not to.
end -- now you have a sine wave of length l seconds and pitch of t/sr Hz... if i'm not mistaken.
sr = love.audio.newSource(sd)
sr:setPitch() -- e.g. if you want 440 Hz, then you need to set this to 440 / (t / sr) or something; not gonna say it's a guarantee that it works if the multiplier is too small or too large; this is kinda a bad way to do all this tbh.
sr:play() -- if you want more simultaneous beeps, do sr2 = sr:clone() or something.
Feel free to disregard the first few local definitions, i find it kinda silly how people assume one would want to use anything but lua (maybe c but that's besides the point, nor is it supported) on this forum. :huh

Also apologies about the non-existence of formatting, i lost interest in this quickly but wanted to write something up still; even if it's wrong i'm sure you can adapt/fix it! ^^
Thanks that looks great!

Re: Creating sine waves in love?

Posted: Tue Jan 08, 2019 2:57 pm
by xpali2
pgimeno wrote: Tue Jan 08, 2019 12:43 am I may be missing something, but can't you have a long enough sample generated with e.g. audacity, play it and then stop it with a timer?
The reason I need it in the code is that I want to try to make the time that the beeps last relative. So making one sound and playing it more slowly would make it also change pitch which I don't want.

Re: Creating sine waves in love?

Posted: Tue Jan 08, 2019 3:16 pm
by grump
Just play the sample in a loop and control its length that way.

Re: Creating sine waves in love?

Posted: Tue Jan 08, 2019 4:07 pm
by ivan
A while ago I wrote a short article about waveforms that you might find useful:
https://2dengine.com/?p=waveforms#Sine_wave
Good luck!