pjackson ·
Hi, Im new to synthmaker and only just working things out.
What I am trying to do - I want to make plugin that takes wavelength long samples(I think these are called grains but Im not completely sure on terminology) of an input signal, quickly processes them and then streams them out again. I figure with this sort of thing i can switch octaves by lengthening the grain before its output again, or do other things.
This is the way Ive been trying to do it. I have three buffers - writeBuffer, swapBuffer and playbuffer. Writebuffer constantly reads in the input signal, when the signal crosses zero it writes out its data to swapBuffer. PlayBuffer constantly plays out what it contains, looping around and round. When it reaches the end of its grain it copies whatever was in swapbuffer over.
So basically data goes from writebuffer -> swapBuffer -> playBuffer
My problem comes when I want to copy one buffer over to another. my buffers are 4096 floats big. And I cant find a way to make a loop that only calculates when I actually want to copy the values. All my code executes every sample. Here is an example of how Im trying to do it, Im not used to these bitmask things either-
//copy writeBuffer to swapBuffer loopIndexA = 0; loop(4096) { swapBuffer[loopIndexA] = (zeroCrossing == 1) & writeBuffer[loopIndexA] + (zeroCrossing == 0) & swapBuffer[loopIndexA]; loopIndexA = loopIndexA + 1; }
That loops round 4096 times every sample! Am I doing something that will never work? Is there another way to acheive what i want? can I make a loop only execute when i want it to?
Heres all my code if your interested, this doesnt work at all though!! It just maxes out the CPU - obviously because its doing these loops 8000 times per sample-
streamin in; streamout out;
float writeBuffer[4096]; float writeCounter = 0; float writeGrainSize = 4096;
float swapBuffer[4096]; //float swapCounter = 0; float swapGrainSize = 4096;
float playBuffer[4096]; float playCounter = 0; float playGrainSize = 4096;
float aboveOrBelow = 0; //0 is below, 1 is above float aboveOrBelowDelayed = 0; float zeroCrossing = 0;
float loopIndexA; float loopIndexB;
//main section //---------------------------------------------------------------
//set aboveorBelow for zero crossings aboveOrBelow = in > 0.0 & 1.0;
//detect zero crossing and do something zeroCrossing = (aboveOrBelow == 1) & (aboveOrBelowDelayed == 0); //copy writeBuffer to swapBuffer loopIndexA = 0; loop(4096) { swapBuffer[loopIndexA] = (zeroCrossing == 1) & writeBuffer[loopIndexA] + (zeroCrossing == 0) & swapBuffer[loopIndexA]; loopIndexA = loopIndexA + 1; } //set grainsize swapGrainSize = (zeroCrossing == 1) & loopIndexA + (zeroCrossing == 0) & swapGrainSize; //set writeCounter back to zero writeCounter = writeCounter - (zeroCrossing == 1) & writeCounter;
//write to the writeBuffer writeBuffer[writeCounter] = in;
//play the playbuffer out = playBuffer[playCounter];
//getting stuff ready for next sample //---------------------------------------------------------------
//write out delayed aboveOrBelow aboveOrBelowDelayed = aboveOrBelow;
//increase counters writeCounter = writeCounter + 1.0; writeCounter = writeCounter - (writeCounter >= writeGrainSize) & writeGrainSize; playCounter = playCounter + 1.0;
//copy swapBuffer to playBuffer if grain size is reached loopIndexB = 0; loop(4096) { playBuffer[loopIndexB] = (playCounter >= playGrainSize) & swapBuffer[loopIndexB] + (playCounter < playGrainSize) & playBuffer[loopIndexB]; loopIndexB = loopIndexB + 1; } //set grainsize playGrainSize = (playCounter >= playGrainSize) & swapGrainSize + (playCounter >= playGrainSize) & playGrainSize; //set playCounter back to zero playCounter = playCounter - (playCounter >= playGrainSize) & playCounter;
Id be really greatful for any help you can give me? maybe point me in the right direction at least?..
cheers