Cabbage Logo
Back to Cabbage Site

Changing audio buffer size in ftgen?

I’m currently storing audio as a ftgen for use in certain opcodes.

For example:

giTable ftgen 0, 0, sr, 2, 0

As I understand, this takes 1 second of audio, but I’m looking for a way to change the size of the audio buffer to another size like 0.5 seconds. Does anyone know how to achieve this?

I tried multiplying, but I only managed to change the pitch of the buffer that way…

You can always call ftgen again to change the size of the buffer, but this might cause dropouts depending on when and where you resize the function table. If you only want to play back half of the 1 second table you can just limit the amount of samples you read.

a1 phasor 1
a2 tab a1*.5, giTable, 1

or if you are not using normalised mode for the table reader:

a1 phasor 1
a2 tab a1*22050, giTable

Hmm, how would one change a2 into i-rate?

What are you trying to do exactly, if the buffer contains audio why would you want to read it at i-time?

Using this opcode as a delay-effect, which the incoming audio is the source signal function table. Trying to reduce the window to 0.5 seconds instead of 1 second as it is a bit long for the effect I’m making.

So you’re writing audio to a function table, and syncgrain is then reading from this function table? If the function table is too long, just shorten it? Instead of:

giTable ftgen 0, 0, sr, 2, 0

can you not just do:

giTable ftgen 0, 0, sr/2, 2, 0

I tried that, but it alters the pitch

I will throw together a example

1 Like

Here Example.csd (1.4 KB)

Also, any tips on how to improve the feedback functionality? Currently it also affects the volume of outgoing audio, so if the feedback is lower, the output will also be lower, and if the feedback is high the volume will be high.

A few issues here. First off, this doens’t make much sense:

gaWritePointer = phasor(1)
gaWritePointer = phasor(1)

You write ga1 to the table, and then immediately after that you overwrite the value of ga1 with ga2? Also, there is no ixmode of 2, although in this case it still works as expected because any non-0 value will cause normalisation of table length.

That code is also the problem with the repitching. You should set your phasor freq to match the size of the buffer. If you are only reading half a second long table, your phasor frequency should be two because you will be filling the buffer twice every second. Or you can just use this type of formula, which will allow you to change the buffer size to whatever you like without having to mess with the phasor frequency again:

gaWritePointer = phasor(sr/ftlen(giTable))

You might try one of the compression opcodes to sort this. There are quite a few to choose from. I don’t have much experience with them myself, but they should be pretty straightforward. You could also modify tie the two slider together and when one is at its lowest, the other should be at its highest, but this wouldn’t allow users to have them both at max volume.

Sorry, I originally had written ga1 and ga2 to to two different tables in the original code, that’s why I had that code two times.

Will test it out in the project now!

Should I add these together?

gasum = ga1 + ga2

gaWritePointer = phasor(sr/ftlen(giTable))

Also, I’m getting a lot of feedback if I increase kfreq to like 10?

You can sum them but you should probably half the result in order to prevent clipping. You are controlling the feedback yourself, can’t you just turn it down?

Yup, I will cap the max-value of the density and feedback :+1:

I owe you about 50 beers by the way :wink:

I look forward to cashing those in :beers:

1 Like

Coming back to this thread, I was wondering Rory:

a1 phasor 1
a2 tab a1*.5, giTable, 1

Is it just me, or does this not really limit the amount of samples you read, but it changes the speed of reading samples from giTable? In this case, it is half the speed right (octave down)?

Doing some reversal of audio with reading function tables, and currently looking into ways to change the buffer size with a k-rate variable :thinking:

Edit: Seems like I need to do something like this:

a1  phasor  sr/ftlen(giTable)*kbuffer

kbuffer being integers from 1 and up, but I’m not sure. Any insights?

Yes, it only reads half the samples in a second, as opposed all all the sample in a second. This is what gives you a drop in pitch.

If you want to read half the table, but start at mid-way through you can do this:

a2 tab 0.5+(a1*0.5), giTable, 1

The line with the phasor only controls the speed of playback. But it’s coupled to the amount of sample you are playing. What I’d be inclined to do here is create a UDO that takes a phasor but let’s me set the start and end points of each cycle.

This would read the last half of giTable in half the speed, pitching it down an octave correct?

What if I want to create a buffer size change functionality for reversal of audio. The longer the ftgen, the longer it will take before the audio starts reversing. Would changing the buffer size be possible with a phasor or would it require switching between function tables of different lengths?

Let’s say I have these two tables with different lengths:

giTableLen1 = 2^17
giTableLen2 = 2^16

giTable1  ftgen 1,0, giTableLen1 ,2,0 ;Audio left
giTable2  ftgen 2,0, giTableLen2 ,2,0 ;Audio right

How could I temporarily store them in a i-rate variable, and switch between them? I tried reinitializing, but couldn’t get it to work :thinking:

Any idea?

I am not sure buffer size is the correct terminology here, you’re really talking about loop points no?

Not if you reset it back to 0. I would forego a phasor and do all this in a UDO that runs with ksmps set to 1. This way you have total control over loop points, when and where to start, and moving backwards is just a case of using kIndex-=1 as opposed to kIndex+=1.

You know what I mean?