Page 1 of 1

How to make tone signal and multiple tone signals?

Posted: Wed Aug 03, 2022 9:38 am
by marcoortiz
Hi all!

Is it possible to make a tone signal? I've tried with the 1000 Hz 1 second wave file, but I hear small pause every second. Is it possible to make it continuously?

How to make 1000 Hz signal and 1500 Hz signal simultaneously?

Re: How to make tone signal and multiple tone signals?

Posted: Wed Aug 03, 2022 10:51 am
by darkfrei
I've generated the file on some online sound generator and it was with this problem too.

Just make your own sound as

Code: Select all

local rate      = 44100 -- samples per second
local length    = 1/32  -- 0.03125 seconds
local tone      = 440.0 -- Hz
local p         = math.floor(rate/tone) -- 100 (wave length in samples)
local soundData = love.sound.newSoundData(math.floor(length*rate), rate, 16, 1)
for i=0, soundData:getSampleCount() - 1 do
--	soundData:setSample(i, math.sin(2*math.pi*i/p)) -- sine wave.
	soundData:setSample(i, i%p<p/2 and 1 or -1)     -- square wave; the first half of the wave is 1, the second half is -1.
end
local source = love.audio.newSource(soundData)
local function beep() source:play() end

Code: Select all

beep()

Re: How to make tone signal and multiple tone signals?

Posted: Wed Aug 03, 2022 3:07 pm
by ReFreezed
You can use a queueable source to generate continuous sound.

Code: Select all

local signal1Frequency = 1000
local signal2Frequency = 1500

local bufferSize      = 1024
local sampleRate      = 48000
local bitDepth        = 16
local internalBuffers = 4

function love.load()
	data   = love.sound.newSoundData(bufferSize, sampleRate, bitDepth, 1)
	source = love.audio.newQueueableSource(sampleRate, bitDepth, 1, internalBuffers)
end

local sampleCounter = 0

function love.update(dt)
	for i = 1, source:getFreeBufferCount() do
		for sampleIndex = 0, bufferSize-1 do
			local time     = sampleCounter / sampleRate
			local signal1  = math.sin(signal1Frequency * time * 2*math.pi)
			local signal2  = math.sin(signal2Frequency * time * 2*math.pi)
			local combined = (signal1 + signal2) / 2

			data:setSample(sampleIndex, combined)

			sampleCounter = sampleCounter + 1
		end

		source:queue(data)
		source:play()
	end
end

Re: How to make tone signal and multiple tone signals?

Posted: Thu Aug 04, 2022 9:00 pm
by pgimeno
I wonder if the "small pause" you hear is actually a click that happens when the length is not an exact multiple of the period. A simple looping source should suffice, if you are cautious with that.

Code: Select all

local function getLoopingSineSource(freq)
  local single_period_length = 44100 / freq
  -- Make a search for the length that is closest to an exact multiple of
  -- the period in the first 20 full cycles
  local closest, closest_length
  for i = 1, 20 do
    local period = i * single_period_length
    local rounded = math.floor(period + 0.5)
    local dist = math.abs(period - rounded)
    if i == 1 or dist < closest then
      closest = dist
      closest_length = rounded
    end
  end

  local sdata = love.sound.newSoundData(closest_length, 44100, 16, 1)
  for i = 0, closest_length - 1 do
    sdata:setSample(i, math.sin(2 * math.pi / single_period_length * i))
  end
  local src = love.audio.newSource(sdata)
  src:setLooping(true)
  return src
end


local src = getLoopingSineSource(1000)
src:play()
local src2 = getLoopingSineSource(1500)
src2:play()