I need to automatically resize after recording and set up adding the resized buffer to a polybuffer!

Sebastian Rodriguez's icon

Hey,

I currently have a multichannel signal as the given input recorded into a large buffer (to allow for open ended recording). From there I can copy the recorded input into an appropriately sized buffer by clicking a bang. What I really need to happen is for the buffer to automatically resize after recording is done. Further, I really need to make it easy for the user to append this resized buffer to a polybuffer, or add it to a specific polybuffer instance (ie: example-polybuffer.1).

Thanks, you rule!!

buffer-resize-and-polybuffer-append.maxpat
Max Patch

Source Audio's icon

message crop to buffer does that.
like crop 0 10000 leaves you with first 10 seconds.
much faster than using peek is to copy buffers
using set or duplicate messages.
Why polybuffer ?
I don't know of a method to add directly from buffer
to polybuffer specifying size.
One first has to create polybuffer instance, than copy to it,
and finally crop.
So one needs to use other methods, like el-buffet external
from lyon poutpourri.
I am not using Max 8 and mc stuff, so maybe there is some option there,
but I don't know that.
I would record, when recording is done, create new polybuffer instance
with exact length as recording, then copy from recording buffer into it.

message send 1 to polybuffer routes the message to the
instance 1.
Like send 1 duplicate REC, send 1 crop 0 32000
would copy entire REC buffer to polybuffer instance 1, than crop it
to 32000 ms.
What I dislike about polybuffer is that one can't remove individual buffers.
P.S. if you want to resize recording buffer after recording is done,
things look a bit different, one can crop recording buffer,
create new empty instance of polybuffer, than duplicate recording buffer into it

Source Audio's icon

Max Patch
Copy patch and select New From Clipboard in Max.

only 1 rec channel connected, many things missing,
just en example

Sebastian Rodriguez's icon

Thanks for feedback, which has helped me get a better grasp of what I'm doing. I don't understand how to implements the following you said

"message send 1 to polybuffer routes the message to the instance 1. Like send 1 duplicate REC, send 1 crop 0 32000 would copy entire REC buffer to polybuffer instance 1, than crop it to 32000 ms."

I am having trouble using duplicate or send to send the information from a cropped buffer to a poly buffer. Can you explain how this works in more detail please?

Source Audio's icon

No problem.
In the patch I posted it is done this way :
as soon as recording ends, polybuffer gets message to create
new empty buffer with only one channel and size zero.
appendempty 0 1
Why ? because it gets done very quick, and it does not matter what size
the new created buffer is, or how many channels it has.
It just has to be there to receive
duplicate message.
Duplicate message will anyway expand it to full size of the source buffer,
and all it's channels.
So we have first instance of polybuffer: PLAY.1
At the same moment, Recording buffer gets croped
to recording length
and duplicate message gets sent to polybuffer.
send $1 duplicate REC .
counter object increases on every recording end. For first recording, message is
send 1 duplicate REC, next recording: send 2 duplicate REC etc
After 1000 ms message size 120000 resizes and empties the Recording Buffer
to get it full size and ready for next recording.
That is recording and copying part of the patch.
--------
On playback side - when recording starts, playback is stoped,
and groove object set to REC buffer.
As soon as POLY.1 gets duplicated, groove is set to POLY.1
and playback starts.
Also on each recording end polybuffer gets asked to update list of recorded
buffers, so that one can choose which to play from umenu.
------------
I made a mistake (fast typing) on the matrix input.
That is for fade in on recording start, and fade out on recording end,
which is not really implemented.
Matrix needs message 0 0 1 to set input 0 to output 0 with
gain 1.
I shorted the message to $1 1, but it should be $1 $1 1
-------------
Fade out on recording is another story.
It should be crossfade, which means that recording end
should send count~ to beginning, and overdub with fade out should be recorded
for the length of the fadeout at the beginning of the loop.
This way one gets perfect crossfade.
I did not go that far in the example patch.
---------
The main goal in doing this is to find optimal way of dealing with
new recording, copying, playback etc.
It all depends on the way recorder or looper is designed.
If one first duplicates full recording buffer to empty polybuffer,
and then crops the copy, one moved more memory arround,
but recording buffer remains untouched, in case one wants to play back from it
or overdub, and needs a copy at some later time, or not at all.

The way I did it in example patch is the other way arround :
first crop recording buffer , copy only recorded samples to polybuffer
and release recording buffer.
-------
This method is also usable on normal buffers,
not only polybuffers.

Any more questions ?

Sebastian Rodriguez's icon

That explanation, and patch, was extremely helpful. The part I am trying to understand is how your buffer copy is so fast! I understand your logic as you explained it here:
"The way I did it in example patch is the other way around : first crop recording buffer , copy only recorded samples to polybuffer and release recording buffer."

I guess I am not sure what the part I will post below is doing different from the patch I sent. It would be neat if you simplified that part of the example. How is this section of the patch you sent working, and how is it different from the 'copier mechanism' from the earlier patch I posted?

Max Patch
Copy patch and select New From Clipboard in Max.

Thanks so much (again), really.

Source Audio's icon

I don't use max 8 and all that mc stuff,
so I am not looking really deep into patch you posted first.
The simple fact is: using uzi and peek (as in your 'copier mechanism')
to copy between buffers is too slow and outdated.
It makes sense only for short buffers
where you want to read something using peek,
than manipulate samples and write that back or somewhere else.
---------
message duplicate, or set to buffers works very fast because it
copies samples directly in memory.
If you use existing normal buffers, it is all simple.
here one example :

Max Patch
Copy patch and select New From Clipboard in Max.

Working on polybuffer is different because
one has to create buffers or use existing ones.
You have to read through the polybuffer reference.
here from the reference about send message:

Polybuffer message Send
send    index [int]
anything [list]
Sends messages to the buffer~ objects. The index corresponds to the buffer~ index, and an index of 0 send the message to every buffer~. For instance, send 0 clear sends the message clear to every buffer~ contained in this polybuffer~.
------
Understand that ?
so if you want to copy 1000ms from buffer A to polybuffer TEST
into buffer with index 2, message:
send 2 duplicate A, send 2 crop 1000
to polybuffer~ TEST would do it.
You are left with untouched Buffer A
and first 1000 ms of it copied into polybuffer TEST, buffer TEST.2
********
That would work ONLY if buffer TEST.2 allready exists.
If not , nothing would happen, maybe error into max console...
There is no other way but to use appendempty message to polybuffer to
create new instances.
I proposed using appendempty 0 1, because it
creates new zero size 1 channel buffer in no time,
ready to be copied into.

********
But we had to copy entire buffer A first, then crop.
---------
Other option was to first crop buffer A, then copy it
to polybuffer.
------------
I don't think I can explain all this better.
When working in real time it is very important
that whatever one does makes no interrupts
in running patch.
I've seen people making mistakes like sending
message clear to a large buffer, which then resulted in
midi playback dropouts and many other similar things.
One has to find out that message clearlow instead does it
in low priority mode, so other running things don't
get into trouble.

Sebastian Rodriguez's icon

Very nice of you to re-explain yourself; however, I had asked a different question. For your edification, mc.peek~ is the same as peek~, but it takes in a multi-channel patch cord. A mc patch cord is the same as feeding the number of traditional signal cables into each inlet, except it simplifies this process visually. It does the same thing, but helps patches look tidier.

Anyway, thanks for creating such a simple patch, even if it addressed a different question.

Roman Thilenius's icon


"thanks for this question, but i´d like to answer another first." (martin sonnenborn)

when i am copying buffers using traditional index~ and poke~ mechanisms i let my app switch to nonrealtime driver when the buffer exceeds a certain size.

Source Audio's icon

I know well what mc stuff is, but if the question was not about what I answered,
what was the question about then ?
Why is my patch copying so fast ?
Your whole post was about resizing and copying buffers, not the way one
records or plays back.
My patch was there just to show that.