GEN~ copy buffer
Hi all I'm trying to copy buffers from a circular buffer to a fix one. Doesn't work. Any help?
Here is a gen code box function which works fine. It will return 1 if the copy procedure has finished.
BR
Jo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Duplicate_Buffer (Copy_SourceBuffer, Copy_TargetBuffer, Copy_AmountSamples) {
History Copy_SegmentSize (32);
History Copy_Counter (0);
if (Copy_Counter < Copy_AmountSamples) {
for (i=0; i < Copy_SegmentSize; i += 1) {
read = peek (Copy_SourceBuffer, Copy_Counter);
poke (Copy_TargetBuffer, read, Copy_Counter);
Copy_Counter = Copy_Counter + 1;
}
}
else
if (Copy_Counter >= Copy_AmountSamples) {
Copy_Counter = 0;
return 1; // SPIKE :-)
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Nice routine!
Maybe it needs an additional condition in the for loop to break when the source buffer is fully copied (in case the source buffer is not a multiple of 32 samples long):
Duplicate_Buffer (Copy_SourceBuffer, Copy_TargetBuffer, Copy_AmountSamples) {
History Copy_SegmentSize (32);
History Copy_Counter (0);
if (Copy_Counter < Copy_AmountSamples) {
for (i=0; i < Copy_SegmentSize && Copy_Counter < Copy_AmountSamples; i += 1) {
read = peek (Copy_SourceBuffer, Copy_Counter);
poke (Copy_TargetBuffer, read, Copy_Counter);
Copy_Counter += 1;
}
}
else if (Copy_Counter >= Copy_AmountSamples) {
Copy_Counter = 0;
return 1; // SPIKE :-)
}
}
Hello Graham, thanks for the optimization of the code :-)
BR
Jo
HI Jo, thanks A LOT! almost there, I just can't find a way to put a bang into it to control when it copies. I adapted your function a bit.
I
looking at all that stuff, a simple message to dest buffer:
set src, set dst
would copy the source buffer to destination buffer, no need for
anything else, no java, no gen ---
I assumed the OP wanted to use gen for a specific reason.
BTW the 'set' message to buffer~ does not copy data, it just changes the name that a buffer~ is referenced by.
I am gratefull fo all possible solutions for copying, merging etc buffers.
For me the best is el.buffet~ , but it does not work for me in version 3.
setting buffer to another one and back to original, grabs data from
the other buffer, so for me it is copy, or what would one call it ?
Hi there, still haven't found out how exactly to use that code. It copies but I'd like to copy it only at certain times, when I bang for example. Still doesn't do that any help
Bangs are used in the max world. Gen is the signal world. Therefore these are two pairs of shoes. If you want to trigger a gen function from the max world you have to use a click object from the max world. When you send a bang to the click object it will create signal spike. This spike can be used to trigger a function in the gen world.
So try using the following combination: button => click => gen
Jo
As I said welcome to the signal world :-)
When you use the clock object it sends a signal spike to gen. The audio signal looks like this before and after you trigger the click object: 00000000000001000000000..... So this means that your code in the gen object is only triggered once and that means that it only copies one segment as the code is written that way. A segment is set to 32 in the code so this means it only copies 32 samples :-)
On the other hand when you use your sig method it will send the following to gen. You click on the box and the audio signal changes from 0 to 1 and stays that way. This means that your code is continuously executed. This means that you continuously copying. You see this when you clear the buffer manually. It will always copy again...
So you need to tell gen how long it shall execute the code that I was providing you and when it should stop executing.
Start is done using click and you would need a history variable in gen to keep that state.
Stop is provided by my routing as it sends out a 1 when it has finished copying.
I know this can be quiet strange but gen has no bangs it only has a continuous flow of audio signals :-)
BR
Jo
Hi, Jo G.
Please help me to catch a gist of Gen world. When I was trying to copy a buffer I encountered a problem. I'd tried to read copied dates but I found the silence: seems, nothing happened.
I use following code:
//////////////////////////////////////////////////////////////
Buffer source("source");
Data copy(44100);
count1, count2, count3 = counter(0, 0, 44100);
size_source = dim(source);
channel_source = channels(source);
size_copy = dim(copy);
channel_copy = channels(copy);
for (i=0; i<= 44100; i+=1) {
sample_source = peek(source, i);
poke(copy, sample_source, i);
}
sample_copy = peek(copy, count1);
out = sample_copy;
////////////////////////////////////////////////////////////
Also, I have a question about reading the buffer/data. I know that I can use counter/phasor/lookup and etc.
But, why doesn't the following code allow to reach success:
!!!!!WARNING!!!!!!
I DO NOT RECOMMEND TO LAUNCH SIMILAR CODE IN GEN. THAT CAN LEAD TO DESTRUCTION YOUR SOUND-SYSTEM OR/AND YOUR EARS.
//////////////////////////////////
for (i = 0; i <= size; i +=1) {
slice = peek(source, i);
out1 = slice;
}
/////////////////////////////////
I get audio processing exception: too many iterations (runaway loop?)
Silence because your counter() is incrementing by zero. Try "c = count(1, 0, dim(copy))".
Runaway loop because you are copying 44100 samples on every sample, that is, 44100 x 44100 samples per second.
The code in a codebox runs on *every sample* of passing time. You need to either (a) make the copy only happen once, rather than on every sample, or (b) spread the copying over time. E.g.:
a)
Buffer src;
Data dst(44100);
History docopy(1);
if (docopy) {
// set docopy=0 to prevent it happening on every sample
// send message 'docopy 1' to gen~ to re-trigger the copy
docopy = 0;
for (i=0; i<dim(dst); i+=1) {
poke(dst, peek(src, i), i);
}
}
// continuous playback to verify it:
c = counter(1, 0, dim(dst));
out1 = peek(dst, c);
b)
Buffer src;
Data dst(44100);
// copy just one sample at a time
c = counter(1, 0, dim(dst));
poke(dst, peek(src, c), c);
// continuous playback to verify it:
out1 = peek(dst, c);
Thanks, Graham. I caught your idea. Your code is clear. But unfortunately neither a) and b) works. That has not produced a sound yet. I tried to use other "buffer" instead "data" object. In that case, I see the code works because of a filled buffer window. However, it's still blear why I cannot get a sound from gen's outlet.
I tested both a) and b) before posting, they do work. Here's b) with a buffer-based dst:
But apparently I pasted a) with a typo -- here's a) with a buffer based dst:
The major point is you used the object "buffer" for a dst instead of the object "data" as you wrote in the previous comment. That's clear and does make a scene. I was wondering why code doesn't work if use the object "data".
great thread, was about to give up on writing myriads of samples in one for loop in gen~ until I found this. Makes total sense to split the code into segments. I am using [edge~] with segment-exceed notifications to iterate through the segments and it works like a charm! Albeit, different usecase: spreading audio across channels evenly.
Thanks everyone.