Phase problem

Hello, I would like to kick this problem. I will create one wave over the entire sample buffer, for example like this:

``````function sine(nr_samples)
local sin = math.sin
local pi = math.pi
local buffer = {}
for i=0, nr_samples do
buffer[#buffer + 1] = sin(2 * pi * i / nr_samples)
end
return buffer
end
``````

Then I try to create 256 harmonies on this wave using this. input is buffer with created sine wave HARMONIC_SERIES is table with 256 values for harmonies

``````function wave_calc(samples)
local abs = math.abs
local cos=math.cos
local sin=math.sin
local pi = math.pi
local buffer = {}
local series = HARMONIC_SERIES

-- speedup for rendering
-- use only active harmonies
local active = {}
for i=1, 256 do
if series[i] ~= 0 then
active[#active + 1] = i
end
end

for i=1, #samples do
local normalize, out = 0, 0
for k=1, #active do
local j = active[k]
local harm = series[j]
local pos = samples[((i * j - 1) % #samples) + 1] * harm
out = out + pos
normalize = normalize + abs(harm)
end
buffer[#buffer + 1] = out / normalize
end
return buffer
end
``````

I also have an extra table for the 256 phase values for each of the 256 harmonics.And now the problem I can’t figure out. How do I apply the phase shift for each harmony separately to this function? So for harmony 2 I will use the phase shift from the table of phases 2? Will it be applied to this function like this or am I going about it completely wrong?

here’s what I’m trying to do, unfortunately no phase shifts yet Thanks.

Is that a typo? shouldn’t it be #buffer + i ?

similarly here, shouldn’t this be k instead of 1?

wouldn’t it be more normal for(int i=0; i< #sample; ++i)?

What language is this in? also, in the first function you fill #buffer, then in the next one you overwrite buffer? Anyways, when you index into the sine array, add the phase to the index. Scaled appropriately.

But, really, why aren’t you using an FFT for this? It would be nearly trivial…

Also, that normalization code looks pretty funky… shouldn’t in the loop it should be normalize = std::max(normalize, abs(harm))?

hello, it’s adding a value to the end of the buffer. ‘buffer’ is the buffer, ‘#buffer’ is the size of the buffer.

ok. In what language is #buffer a valid variable name? maybe call it sizeOfBuffer?

it is Lua. lua tables indexing from ‘1’ so loop must be (1… #samples), or (0 … #samples - 1). I’m trying to run it in Renoise and at the same time as a script in the Lua VCV module from Wrong People.

ok, sry, my Lua is pretty rusty.

No prob, I’m not skilled with FFT, but one thing i know. FFT in Lua is really sloooow. In pure Lua. In LuaJIT i don’t know because Renoise not using LuaJIT. So i must improvize.

FFT in c is very fast, and there is one in the Vcv sdk already.

Anyway, phase is just the sample position.

Another idea, Calculate all values on the go and sum waves.

``````local i = 1
local buffer = {}
while i <= number_of_samples do
local j = 1
local sum = 0
while j <= 256 do
local sample = math.sin(2 * math.pi * j * (i / number_of_samples) + table_of_phases[j])
sum = sum + sample
j = j + 1
end
buffer[#buffer + 1] = sum / 256
i = i + 1
end
``````

Do you think the result would be the same? so that the result is not white noise.

visible slowdown but seems to be working for now.

Doing that on the fly will, as you note, waste a huge amount of cpu.

Are you sure Fourier decomposition is best for the information conserving task at hand? Is order best represented by increasing sines? Seems like `sin` is the biggest cycles in the loop. And aliasing? I guess it depends on the harmonic amplitude graph.