I will try it
Changing audio buffer size in ftgen?
If I do something like this:
opcode Reverse, a, aiiki
setksmps 1
aIn, iFn, iEnvTable, kLength, iOffset xin
kTableLength = int(ftlen(iFn)*kLength)
kWritePointer init 0
kReadPointer init 0
kOffset init 0
aEnvPhs init 0
if changed(kTableLength) == 1 then
reinit Reset
endif
Reset:
kWritePointer init 0
kReadPointer init 0
kOffset init 0
aEnvPhs init 0
if kOffset != iOffset then
kOffset vdelayk kOffset + iOffset, (iOffset*(kTableLength/sr)), 10
endif
if kOffset == iOffset then
tablew aIn, a(kReadPointer), iFn
aSignal table kTableLength-a(kReadPointer), iFn
kWritePointer = kWritePointer < kTableLength ? kWritePointer + 1 : 0
kReadPointer = kReadPointer < kTableLength ? kReadPointer + 1 : 0
aEnvPhs phasor (sr/(kTableLength))
aEnv table aEnvPhs*2, iEnvTable, 1, 0, 1
endif
aout vdelay aSignal*aEnv, ((iOffset*(kTableLength/sr))*1000), 10000
xout aout
endop
It just ends up looping the same buffer of audio twice in a row with a offset of 0.5
I also tried delaying the envelope to half a cycle like this:
aEnvPhs phasor (sr/(kTableLength))
aEnv table aEnvPhs, iEnvTable, 1, 0, 1
aEnv vdelay aEnv, ((kTableLength/sr)/2)*1000, 10000
but no dice…
Here’s offsetting by samples instead of a float between 0 and 1…
<Cabbage> bounds(0, 0, 0, 0)
form caption("Reverse") size(400, 300), guiMode("queue"), colour(58, 110, 182), pluginId("def1")
rslider bounds(26, 28, 60, 60) channel("length") range(0, 1, 1, 1, 0.1), text("Length")
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 -m0d --midi-key=4 --midi-velocity-amp=5
</CsOptions>
<CsInstruments>
ksmps = 32
nchnls = 2
0dbfs = 1
giTableLen = 2^16
giTableL1 ftgen 0, 0, giTableLen, 7, 0, giTableLen, 0
giTableL2 ftgen 0, 0, giTableLen, 7, 0, giTableLen, 0
giTableR1 ftgen 0, 0, giTableLen, 7, 0, giTableLen, 0
giTableR2 ftgen 0, 0, giTableLen, 7, 0, giTableLen, 0
giEnvTable ftgen 0, 0, giTableLen, 9, 0.5, 1, 0
opcode Reverse, a, aiiki
setksmps 1
aIn, iFn, iEnvTable, kLength, iOffset xin
kTableLength = int(ftlen(iFn)*kLength)
kWritePointer init 0
kReadPointer init 0
kOffset init 0
aEnvPhs init 0
if changed(kTableLength) == 1 then
reinit Reset
endif
Reset:
kWritePointer init 0
kReadPointer init 0
kOffset init 0
aEnvPhs init 0
kOffset_Sec = (iOffset/sr)/2
if kOffset != kOffset_Sec then
kOffset vdelayk kOffset + kOffset_Sec, kOffset_Sec, 10
endif
if kOffset == kOffset_Sec then
tablew aIn, a(kReadPointer), iFn
aSignal table kTableLength-a(kReadPointer), iFn
kWritePointer = kWritePointer < kTableLength ? kWritePointer + 1 : 0
kReadPointer = kReadPointer < kTableLength ? kReadPointer + 1 : 0
aEnvPhs phasor (sr/(kTableLength))
aEnv table aEnvPhs*2, iEnvTable, 1, 0, 1
endif
xout aSignal*aEnv
endop
instr 1
kLength cabbageGetValue "length"
a1 inch 1
a2 inch 2
aRevL1 Reverse a1, giTableL1, giEnvTable, kLength, 0
aRevL2 Reverse a1, giTableL2, giEnvTable, kLength, giTableLen/2
aRevR1 Reverse a2, giTableR1, giEnvTable, kLength, 0
aRevR2 Reverse a2, giTableR2, giEnvTable, kLength, giTableLen/2
outs aRevL1 + aRevL2, aRevR1 + aRevR2
endin
</CsInstruments>
<CsScore>
i1 0 z
</CsScore>
</CsoundSynthesizer>
Is this correct?
Let’s split things up as the envelope is doing: Table1[1] & [2] and Table2[1] & [2].
It sounds to me like the second half of Table1[1] and first half of Table2[1] is identical? Same with second half of Table2[1] and first half of Table1[1].
But I am not completely sure, my mind is seriously tangled from this stuff…
Yes, that’s what I was suggesting. It will result in a slight echo sound, but I thought it might be interesting. What about offloading the second delay to a new instrument that starts half a table’s worth of samples behind instrument one? You can still read the same slider channel, but you will need to delay updating it for the second instance, otherwise the two delays will sync up again.
That’s what I’m trying to do with this
if kOffset != iOffset then
kOffset vdelayk kOffset + iOffset, (iOffset*(kTableLength/sr)), 10
endif
Trying to offset the time before the second table starts writing, so that a window with offset is not only a delayed version of the first window, but they have different contents. But the issue with the last one (2 replys up), is that it works quite nicely, but :
It sounds to me like the second half of Table1[1] and first half of Table2[1] is identical? Same with second half of Table2[1] and first half of Table1[1].
Anyway, I landed on this being the final solution:
<Cabbage> bounds(0, 0, 0, 0)
form caption("Reverse") size(400, 300), guiMode("queue"), colour(58, 110, 182), pluginId("def1")
rslider bounds(26, 28, 60, 60) channel("length") range(0, 1, 1, 1, 0.1), text("Length")
gentable bounds(154, 118, 189, 138), , outlineThickness(3), tableNumber(90.0), tableGridColour(155, 155, 155, 255) tableBackgroundColour(0, 0, 0, 0) tableColour:0(147, 210, 0, 255)
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 -m0d --midi-key=4 --midi-velocity-amp=5
</CsOptions>
<CsInstruments>
ksmps = 32
nchnls = 2
0dbfs = 1
giTableLen = 2^16
giTableL1 ftgen 0, 0, giTableLen, 7, 0, giTableLen, 0
giTableL2 ftgen 0, 0, giTableLen, 7, 0, giTableLen, 0
giTableR1 ftgen 0, 0, giTableLen, 7, 0, giTableLen, 0
giTableR2 ftgen 0, 0, giTableLen, 7, 0, giTableLen, 0
giEnvTable ftgen 90, 0, 8192, 20, 1, 1
opcode Reverse, a, aiiki
setksmps 1
aIn, iFn, iEnvTable, kLength, iOffset xin
kTableLength = int(ftlen(iFn)*kLength)
kWritePointer init 0
kReadPointer init 0
kOffset init 0
aEnvPhs init 0
if changed(kTableLength) == 1 then
reinit Reset
endif
Reset:
kWritePointer init 0
kReadPointer init 0
kOffset init 0
aEnvPhs init 0
kOffset_Sec init 0
kOffset_Sec = (iOffset/sr) * kLength
if kOffset != kOffset_Sec then
kOffset vdelayk kOffset + kOffset_Sec, kOffset_Sec, 10
endif
if kOffset == kOffset_Sec then
tablew aIn, a(kReadPointer), iFn
aSignal table kTableLength-a(kReadPointer), iFn
kWritePointer = kWritePointer < kTableLength ? kWritePointer + 1 : 0
kReadPointer = kReadPointer < kTableLength ? kReadPointer + 1 : 0
aEnvPhs phasor (sr/(kTableLength))
aEnv table aEnvPhs*2, iEnvTable, 1, 0, 1
endif
xout aSignal*aEnv
endop
instr 1
kLength cabbageGetValue "length"
a1 inch 1
a2 inch 2
aRevL1 Reverse a1, giTableL1, giEnvTable, kLength, 0
aRevL2 Reverse a1, giTableL2, giEnvTable, kLength, giTableLen/4
aRevR1 Reverse a2, giTableR1, giEnvTable, kLength, 0
aRevR2 Reverse a2, giTableR2, giEnvTable, kLength, giTableLen/4
outs aRevL1 + aRevL2, aRevR1 + aRevR2
endin
</CsInstruments>
<CsScore>
i1 0 z
</CsScore>
</CsoundSynthesizer>
Still I wish I would be able to offset the envelope Table and remove the click by offset instead of doubling the phasor speed, but I guess this is satisfactory.
Hopefully someone else also get’s some use out of it