Sound generator module

Showcase your libraries, tools and other projects that help your fellow love users.
Post Reply
User avatar
Bigfoot71
Party member
Posts: 287
Joined: Fri Mar 11, 2022 11:07 am

Sound generator module

Post by Bigfoot71 »

Hi all people :D

I'm just sharing with you a little script I made for a game I'm working on and which could help some I think, it's a Lua module to generate sounds with 6 different types of waves and with some options in plus the possibility of making small melodies with another function ^^

Here are the possible types of waves:
  • sine
    square
    triangle
    sawtooth
    pulser
    composite
I started from the model in the wiki which is really useful then a lot of lessons from right to left, I made a demo having tried to reproduce the Mario theme, I don't know if it's a success you will tell me if there are real musicians :awesome:

If you have any suggestions for optimizations or additions I am all ears I even made a repository if necessary ^^

I forgot to specify that I added a table with all the note frequencies from C1 to G9 :crazy:

Links that have been useful to me:
https://thewolfsound.com/sine-saw-squar ... synthesis/
http://www.mathguide.com/lessons2/EquationsNotes.html
http://techlib.com/reference/musical_no ... encies.htm
https://pages.mtu.edu/~suits/NoteFreqCalcs.html
https://pages.mtu.edu/~suits/notefreqs.html
Attachments
Music-Demo.love
(2.41 KiB) Downloaded 103 times
Last edited by Bigfoot71 on Mon Feb 13, 2023 11:16 am, edited 1 time in total.
My avatar code for the curious :D V1, V2, V3.
Andlac028
Party member
Posts: 174
Joined: Fri Dec 14, 2018 2:27 pm
Location: Slovakia

Re: Sound generator module

Post by Andlac028 »

Bigfoot71 wrote: Sat Feb 11, 2023 9:35 pm If you have any suggestions for optimizations or additions I am all ears I even made a repository if necessary ^^
I just looked at the code and there are some suggestions for optimizations:

Use local variables also for functions like math.floor, if they are used very often in loop, because it will eliminate table lookups:

Code: Select all

local floor = math.floor
for … do
    result = floor(…)
end
In genMusic, you call genNote and then concat all the soundDatas to new soundData. That created unnecesarry soundDatas and invokes copying all the data. Try to compute length of soundsData for genMusic and only pass soundData with offsets to genNote, so there is no unnecesarry soundData for every note.

Edit: fixed some typos
Last edited by Andlac028 on Sun Feb 12, 2023 6:35 pm, edited 2 times in total.
User avatar
Bigfoot71
Party member
Posts: 287
Joined: Fri Mar 11, 2022 11:07 am

Re: Sound generator module

Post by Bigfoot71 »

Andlac028 wrote: Sun Feb 12, 2023 6:38 am I just looked at the code and there are some suggestuins for optimizations:

Use local variables also for functions like math.floor, if they are used very often in loop, because it will eliminate table lookups:

Code: Select all

local floor = math.floor
for … do
    result = floor(…)
end
In genMusic, you call genNote and then concat all the soundDatas to new soundData. That created unnecesarry siundDatas and invikves copying all the data. Try to comoute length of soundsData for genMusic and only pass soundData with offsets to genNote, so there is no unnecesarry soundData.
Thank you for these suggestions! I feel a little stupid because for math.floor (and other math functions) it was so obvious that I could have asked myself the question before sharing but it's done thank you!

I also made a real demo where you can try out all the waveforms for the sounds.
Attachments
Music-Demo.love
(3.09 KiB) Downloaded 67 times
My avatar code for the curious :D V1, V2, V3.
User avatar
zorg
Party member
Posts: 3444
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Sound generator module

Post by zorg »

Not many things i can nitpick about with reason tbh, so good job; I guess just if you'd want to write/have less lines of code, you could generate the frequencies of the notes with an algorithm instead of hardcoding the values.

Code: Select all

notes = {}

local A4 = 440.00
for n = 12, 131 do -- From C0 to B9
  table.insert(notes, A4 * 2^((n-69)/12))
end
I would also personally simplify the generators, since the p period thing imo is not that important... but i guess it does make sense if you're just generating specific length sounds... i wouldn't bother with that for a more complete synth that could realtime generate sound since it would be meaningless.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
Bigfoot71
Party member
Posts: 287
Joined: Fri Mar 11, 2022 11:07 am

Re: Sound generator module

Post by Bigfoot71 »

zorg wrote: Mon Feb 13, 2023 12:24 am Not many things i can nitpick about with reason tbh, so good job; I guess just if you'd want to write/have less lines of code, you could generate the frequencies of the notes with an algorithm instead of hardcoding the values.

Code: Select all

notes = {}

local A4 = 440.00
for n = 12, 131 do -- From C0 to B9
  table.insert(notes, A4 * 2^((n-69)/12))
end
I would also personally simplify the generators, since the p period thing imo is not that important... but i guess it does make sense if you're just generating specific length sounds... i wouldn't bother with that for a more complete synth that could realtime generate sound since it would be meaningless.
I'm not hugely savvy in music and I wouldn't even have dared to imagine that such a simple algorithm could generate "all" musical notes, thank you very much, I'll see how to integrate this to keep the letters of the notes in keys of values ​​for the table! :awesome:

Edit: Mission accomplished! Here's how I did:

Code: Select all

local notes = {}; do

    local A4 = 440.00
    local note_names = {
        "C", "C#", "D",
        "D#", "E", "F",
        "F#", "G", "G#",
        "A", "A#", "B"
    }

    for n = 12, 131 do -- From C0 to B9
        local note_frequency = A4 * 2^((n-69)/12)
        local octave = math.floor(n/12)-1
        local note_index = n % 12 + 1
        local note_name = note_names[note_index]..octave
        notes[note_name] = note_frequency
    end

end
Thanks again for this suggestion! :nyu:

Otherwise I can't find any way in pure Lua with only Löve2d to produce sounds in real time, OpenAL seems to allow it so does Löve2d also allow it "natively"?
My avatar code for the curious :D V1, V2, V3.
User avatar
zorg
Party member
Posts: 3444
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Sound generator module

Post by zorg »

Bigfoot71 wrote: Mon Feb 13, 2023 10:15 am Otherwise I can't find any way in pure Lua with only Löve2d to produce sounds in real time, OpenAL seems to allow it so does Löve2d also allow it "natively"?
Yes, you're looking for love.audio.newQueueableSource and love.sound.newSoundData primarily.

Code: Select all

local tau = 2.0 * math.pi
local buffer = love.sound.newSoundData(2048,44100,16,1) -- 2048 is how many samplepoints each channel has
local qsource = love.audio.newQueueableSource(44100,16,1,2) -- 2 is how many OpenAL-internal buffers the source has

-- in update
if qsource:getFreeBufferCount() > 0 then
  -- generate one buffer's worth of audio data; the above line is enough for timing purposes
  local phase = 0.0
  for i = 0, buffer:getSampleCount()-1 do
    local smp = math.sin(tau * phase)
    for c = 1, buffer:getChannelCount() do
      buffer:setSample(i, c, smp)
    end
    phase = (phase + (440.00 / buffer:getSampleRate())) % 1.0
  end
  -- queue it up
  qsource:queue(buffer)
end
qsource:play() -- keep playing so playback never stalls, even if there are underruns; no, this isn't heavy on processing.

Note that with vsync on, the buffer size won't be enough since you'll need x/samplerate > 1/refresh_rate samplepoints to be queued each time update is called.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
Bigfoot71
Party member
Posts: 287
Joined: Fri Mar 11, 2022 11:07 am

Re: Sound generator module

Post by Bigfoot71 »

zorg wrote: Tue Feb 14, 2023 7:10 am Yes, you're looking for love.audio.newQueueableSource and love.sound.newSoundData primarily.

Note that with vsync on, the buffer size won't be enough since you'll need x/samplerate > 1/refresh_rate samplepoints to be queued each time update is called.
Thank you so much ! I'll see what I can do cool with all that :awesome:
My avatar code for the curious :D V1, V2, V3.
Post Reply

Who is online

Users browsing this forum: No registered users and 57 guests