function isnt evaluated in Button?

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

function isnt evaluated in Button?

casey.thomas.anderson
Hi all,

I am working on a part of a gui that will allow me to write the contents of a Buffer to disc after I have stopped recording. It appears to me that the function I have been using for this is not getting evaluated when in a Button. What happens reliably right now is that the function writes 44 Bytes of nothing to the disc. If I remove

~saveBuf.value( "outRecordInfo", "outRecordBuffer", "wav");

from the else case of

if( butt.value == 1, {

and manually run that line elsewhere the buffer does get written to disc without issue. What do I need to do to have the gui cue this when I turn the recording button off? In other words, what is incorrect about the below?

Casey

Code below:

here is the buffer write function (btw, I know about s.record, no reason to respond just to tell me about that)

~saveBuf = { |info, buffer, format|
var infoBus = info.asString, buf = buffer.asString, form = format.asString;

a[(infoBus).asSymbol].get({ |value|

var dur = value, path;

path = thisProcess.platform.recordingsDir +/+ "MASTEROUT_"++Date.localtime.stamp ++ "."++form; // generated path
a[(buf).asSymbol].write(path, form, "int16", dur, 0, completionMessage: {
("saved "++buf++"!").postln;
});
});

};

Here is the part of the gui that is supposed to control it:

// master rec toggle
~recMaster = Button(~window, Rect( 10, 300, 110, 25 ) )
.canFocus_(false)
.states_([
["XXX", Color.black, Color.gray],
["REC", Color.black, Color.red]
])
.action_({ arg butt;

if( butt.value == 1, {
if( ~run == True, {
"REC MASTER OUT".postln;
~allRec = Synth.new(\rec_manual_stereo, [ \amp, 0.9, \buf, ~outRecordBuffer, \inBus, ~outRecordBus.index, \recManualBus, ~outRecordInfo.index, \trig, 1 ], ~saveStuff);
},{
"RUN MASTER OUT FIRST!".postln;
});
},{
"STOP REC MASTER OUT".postln;
~allRec.set(\off, 1);
~saveBuf.value( "outRecordInfo", "outRecordBuffer", "wav");

});
});
Reply | Threaded
Open this post in threaded view
|

Re: function isnt evaluated in Button?

ddw_music
casey.thomas.anderson wrote
> here is the buffer write function (btw, I know about s.record, no reason
> to respond just to tell me about that)

If you're writing contents of a buffer, s.record would be absolutely the
wrong thing ;) so you're fine there.


> a[(buf).asSymbol].write(path, form, "int16", dur, 0, completionMessage: {
> ("saved "++buf++"!").postln;
> });

The problem here is that the last argument is a completion *message*, not a
completion *function*.

A completion message needs to be a function that returns an *array*
containing a valid OSC message for the server to execute, e.g.

Buffer.alloc(s, 2048, 1, completionMessage: { |buf| buf.sine1Msg([1]) });

(That's "sine1Msg," not "sine1" -- the function must return the message but
not try to send it.)

It's not valid to put arbitrary code into a completion *message* function.
"postln" does not return a valid OSC message, so you shouldn't use
completionMessage to print "done" feedback to the user.

The easiest way to print that message at the right time is with fork and
sync:

{
    a[...].write(... no completion here...);
    s.sync:
    "Done writing buffer".postln;
}.fork(AppClock);

(AppClock just in case you want to do any GUI stuff in there too.)

hjh



--
Sent from: http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/SuperCollider-Users-New-Use-this-f2676391.html

_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
Reply | Threaded
Open this post in threaded view
|

Re: function isnt evaluated in Button?

casey.thomas.anderson
Hi James,

Thanks as always for your input. I am afraid I only partially understand your suggestion here. I have rewritten the function but get errors because of how it is being triggered in the Button below. Is there something else I need to do here? The errors seem to indicate that I am supposed to be using a routine here but I am unclear on how I should implement that with what I already have and also whether or not I can pass values via arguments to a function that is .fork'd.

~saveBuf = { |info, buffer, format|
var infoBus = info.asString, buf = buffer.asString, form = format.asString;

a[(infoBus).asSymbol].get({ |value|
var dur = value, path;

path = thisProcess.platform.recordingsDir +/+ "MASTEROUT_"++Date.localtime.stamp ++ "."++form; // generated path
a[(buf).asSymbol].write(path, form, "int16", dur, 0);
s.sync;
("saved "++buf++"!").postln;
});

};

I am just guessing that I dont use fork there until I want this to actually happen.

the gui:

// master rec toggle
~recMaster = Button(~window, Rect( 10, 300, 110, 25 ) )
.canFocus_(false)
.states_([
["XXX", Color.black, Color.gray],
["REC", Color.black, Color.red]
])
.action_({ arg butt;

if( butt.value == 1, {
if( ~run == True, {
"REC MASTER OUT".postln;
~allRec = Synth.new(\rec_manual_stereo, [ \amp, 0.9, \buf, ~outRecordBuffer, \inBus, ~outRecordBus.index, \recManualBus, ~outRecordInfo.index, \trig, 1 ], ~saveStuff);
},{
"RUN MASTER OUT FIRST!".postln;
});
},{
"STOP REC MASTER OUT".postln;
~allRec.set(\off, 1);
~saveBuf.fork( "outRecordInfo", "outRecordBuffer", "wav"); // this doesnt happen?
});
});

On Wed, Jan 10, 2018 at 4:46 PM <[hidden email]> wrote:
casey.thomas.anderson wrote
> here is the buffer write function (btw, I know about s.record, no reason
> to respond just to tell me about that)

If you're writing contents of a buffer, s.record would be absolutely the
wrong thing ;) so you're fine there.


> a[(buf).asSymbol].write(path, form, "int16", dur, 0, completionMessage: {
> ("saved "++buf++"!").postln;
> });

The problem here is that the last argument is a completion *message*, not a
completion *function*.

A completion message needs to be a function that returns an *array*
containing a valid OSC message for the server to execute, e.g.

Buffer.alloc(s, 2048, 1, completionMessage: { |buf| buf.sine1Msg([1]) });

(That's "sine1Msg," not "sine1" -- the function must return the message but
not try to send it.)

It's not valid to put arbitrary code into a completion *message* function.
"postln" does not return a valid OSC message, so you shouldn't use
completionMessage to print "done" feedback to the user.

The easiest way to print that message at the right time is with fork and
sync:

{
    a[...].write(... no completion here...);
    s.sync:
    "Done writing buffer".postln;
}.fork(AppClock);

(AppClock just in case you want to do any GUI stuff in there too.)

hjh



--
Sent from: http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/SuperCollider-Users-New-Use-this-f2676391.html

_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
Reply | Threaded
Open this post in threaded view
|

Re: function isnt evaluated in Button?

ddw_music
You should put the "fork" inside the saveBuf function, and then do
~saveBuf.value(... arguments...) as you did before.

You can't do "fork(arguments)." You can "value" with arguments, and the
function inside does { blah blah }.fork.

My home network is down now, I only have mobile data on the phone, so you're
on your own from here unless others chime in.

hjh



--
Sent from: http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/SuperCollider-Users-New-Use-this-f2676391.html

_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
Reply | Threaded
Open this post in threaded view
|

Re: function isnt evaluated in Button?

casey.thomas.anderson
Hm, I definitely cannot get this to work. What I have right now (below) results in the symptoms I originally described: a file with the size of 44 Bytes is made on disc but buffer contents are not recorded there.

Would love it if someone could clear up what I am doing wrong here specifically:

// the function with fork (although I do not know if I am using fork correctly here)

~saveBuf = { |info, buffer, format|
var infoBus = info.asString, buf = buffer.asString, form = format.asString;

a[(infoBus).asSymbol].get({ |value|
var dur = value, path;

path = thisProcess.platform.recordingsDir +/+ "MASTEROUT_"++Date.localtime.stamp ++ "."++form; // generated path
fork{
a[(buf).asSymbol].write(path, form, "int16", dur, 0);
s.sync;
("saved "++buf++"!").postln;
};
});
};

The Gui:

// master rec toggle
~recMaster = Button(~window, Rect( 10, 300, 110, 25 ) )
.canFocus_(false)
.states_([
["XXX", Color.black, Color.gray],
["REC", Color.black, Color.red]
])
.action_({ arg butt;

if( butt.value == 1, {
if( ~run == True, {
"REC MASTER OUT".postln;
~allRec = Synth.new(\rec_manual_stereo, [ \amp, 0.9, \buf, ~outRecordBuffer, \inBus, ~outRecordBus.index, \recManualBus, ~outRecordInfo.index, \trig, 1 ], ~saveStuff);
},{
"RUN MASTER OUT FIRST!".postln;
});
},{
"STOP REC MASTER OUT".postln;
~allRec.set(\off, 1);
~saveBuf.value( "outRecordInfo", "outRecordBuffer", "wav"); // this doesnt happen?
});
});


On January 10, 2018 at 7:20:09 PM, [hidden email] ([hidden email]) wrote:

You should put the "fork" inside the saveBuf function, and then do
~saveBuf.value(... arguments...) as you did before.

You can't do "fork(arguments)." You can "value" with arguments, and the
function inside does { blah blah }.fork.

My home network is down now, I only have mobile data on the phone, so you're
on your own from here unless others chime in.

hjh



--
Sent from: http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/SuperCollider-Users-New-Use-this-f2676391.html

_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
Reply | Threaded
Open this post in threaded view
|

Re: function isnt evaluated in Button?

casey.thomas.anderson
Interestingly enough if I run the function manually from the IDE (after removing .fork and s.sync entirely) I am able to record without issue. It is only when I try to use it in the if statement for butt.value == 1 that I have this problem of not actually recording.

On January 11, 2018 at 10:24:33 AM, casey anderson ([hidden email]) wrote:

Hm, I definitely cannot get this to work. What I have right now (below) results in the symptoms I originally described: a file with the size of 44 Bytes is made on disc but buffer contents are not recorded there.

Would love it if someone could clear up what I am doing wrong here specifically:

// the function with fork (although I do not know if I am using fork correctly here)

~saveBuf = { |info, buffer, format|
var infoBus = info.asString, buf = buffer.asString, form = format.asString;

a[(infoBus).asSymbol].get({ |value|
var dur = value, path;

path = thisProcess.platform.recordingsDir +/+ "MASTEROUT_"++Date.localtime.stamp ++ "."++form; // generated path
fork{
a[(buf).asSymbol].write(path, form, "int16", dur, 0);
s.sync;
("saved "++buf++"!").postln;
};
});
};

The Gui:

// master rec toggle
~recMaster = Button(~window, Rect( 10, 300, 110, 25 ) )
.canFocus_(false)
.states_([
["XXX", Color.black, Color.gray],
["REC", Color.black, Color.red]
])
.action_({ arg butt;

if( butt.value == 1, {
if( ~run == True, {
"REC MASTER OUT".postln;
~allRec = Synth.new(\rec_manual_stereo, [ \amp, 0.9, \buf, ~outRecordBuffer, \inBus, ~outRecordBus.index, \recManualBus, ~outRecordInfo.index, \trig, 1 ], ~saveStuff);
},{
"RUN MASTER OUT FIRST!".postln;
});
},{
"STOP REC MASTER OUT".postln;
~allRec.set(\off, 1);
~saveBuf.value( "outRecordInfo", "outRecordBuffer", "wav"); // this doesnt happen?
});
});


On January 10, 2018 at 7:20:09 PM, [hidden email] ([hidden email]) wrote:

You should put the "fork" inside the saveBuf function, and then do
~saveBuf.value(... arguments...) as you did before.

You can't do "fork(arguments)." You can "value" with arguments, and the
function inside does { blah blah }.fork.

My home network is down now, I only have mobile data on the phone, so you're
on your own from here unless others chime in.

hjh



--
Sent from: http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/SuperCollider-Users-New-Use-this-f2676391.html

_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
Reply | Threaded
Open this post in threaded view
|

Re: function isnt evaluated in Button?

ddw_music
In reply to this post by casey.thomas.anderson
casey.thomas.anderson wrote
> Hm, I definitely cannot get this to work.

You haven't gotten it to work *yet*... not quite the same thing ;)


>  What I have right now (below)
> results in the symptoms I originally described: a file with the size of 44
> Bytes is made on disc but buffer contents are not recorded there.
>
> a[(buf).asSymbol].write(path, form, "int16", dur, 0)

Offhand, I haven't checked the help file, but I think you might have the
wrong parameters. Buffer writing has two arguments to define the segment to
write: startFrames and numFrames. You've provided dur and 0, so (if I
remember the arguments right) it will start recording at frame index 'dur'
and then write 0 frames -- it isn't "numFrames, leaveOpen" (where 0 would be
valid for leaveOpen).

IDE method autocompletion is useful for this case: inside the parens, hit
ctrl-shift-space (cmd on Mac), choose the right class defining "write" (i.e.
Buffer), and then watch the tooltip.

hjh



--
Sent from: http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/SuperCollider-Users-New-Use-this-f2676391.html

_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
Reply | Threaded
Open this post in threaded view
|

Re: function isnt evaluated in Button?

casey.thomas.anderson
The only time dur is 0 is when it is in the Button block, otherwise dur is set via information stored in a control bus. I just double checked against parameters for Buffer.write and can confirm that I have them in the correct order but did notice that I am not using leaveOpen so perhaps that being false by default is the problem?

I will include all of the pieces (but not the group order stuff) below:

Here is the synth def that records and gets the recording duration to pass to dur later (this works):

SynthDef( \rec_manual_stereo, { | amp = 0.0, buf, inBus, rate = 1, recManualBus, off = 0, trig = 0|
var env, in, phase, time;

in = In.ar( inBus, 2 );
phase = Phasor.ar(trig, BufRateScale.kr(buf) * rate, 0, (BufFrames.kr(buf)));
BufWr.ar(in, buf, phase);
time = Latch.kr(phase, off);
  Out.kr( recManualBus, time );
FreeSelf.kr( time );
}).add;

The function (this works too provided i dont use fork or s.sync):

~saveBuf = { |info, buffer, format|
var infoBus = info.asString, buf = buffer.asString, form = format.asString;

a[(infoBus).asSymbol].get({ |value|
var dur = value, path;

path = thisProcess.platform.recordingsDir +/+ "MASTEROUT_"++Date.localtime.stamp ++ "."++form; // generated path
// fork{
a[(buf).asSymbol].write(path, form, "int16", dur, 0);
// s.sync;
("saved "++buf++"!").postln;
// };
});
};


The button (this does work but i cannot get the button off block to actually write the buffer contents to disc so have commented it out for now to run manually):

~recMaster = Button(~window, Rect( 10, 300, 110, 25 ) )
.canFocus_(false)
.states_([
["XXX", Color.black, Color.gray],
["REC", Color.black, Color.red]
])
.action_({ arg butt;

if( butt.value == 1, {
if( ~run == True, {
"REC MASTER OUT".postln;
~allRec = Synth.new(\rec_manual_stereo, [ \amp, 0.9, \buf, ~outRecordBuffer, \inBus, ~outRecordBus.index, \recManualBus, ~outRecordInfo.index, \trig, 1 ], ~saveStuff);
},{
"RUN MASTER OUT FIRST!".postln;
});
},{
"STOP REC MASTER OUT".postln;
~allRec.set(\off, 1);
//~saveBuf.value( "outRecordInfo", "outRecordBuffer", "wav"); // this doesnt happen?
});
});

If I use the above and then run this line manually after turning the button off:

~saveBuf.value( "outRecordInfo", "outRecordBuffer", "wav");

I am able to record and then save the buffer contents to a file.

Or perhaps I am losing my mind,

Casey

On January 11, 2018 at 3:58:22 PM, [hidden email] ([hidden email]) wrote:

casey.thomas.anderson wrote
> Hm, I definitely cannot get this to work.

You haven't gotten it to work *yet*... not quite the same thing ;)


> What I have right now (below)
> results in the symptoms I originally described: a file with the size of 44
> Bytes is made on disc but buffer contents are not recorded there.
>
> a[(buf).asSymbol].write(path, form, "int16", dur, 0)

Offhand, I haven't checked the help file, but I think you might have the
wrong parameters. Buffer writing has two arguments to define the segment to
write: startFrames and numFrames. You've provided dur and 0, so (if I
remember the arguments right) it will start recording at frame index 'dur'
and then write 0 frames -- it isn't "numFrames, leaveOpen" (where 0 would be
valid for leaveOpen).

IDE method autocompletion is useful for this case: inside the parens, hit
ctrl-shift-space (cmd on Mac), choose the right class defining "write" (i.e.
Buffer), and then watch the tooltip.

hjh



--
Sent from: http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/SuperCollider-Users-New-Use-this-f2676391.html

_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
Reply | Threaded
Open this post in threaded view
|

Re: function isnt evaluated in Button?

ddw_music
casey.thomas.anderson wrote
> The only time dur is 0 is when it is in the Button block, otherwise dur is
> set via information stored in a control bus. I just double checked against
> parameters for Buffer.write and can confirm that I have them in the
> correct
> order but did notice that I am not using leaveOpen so perhaps that being
> false by default is the problem?

OK, I just checked, you're right, it is numFrames first. And no, you do want
leaveOpen to be false. If the file isn't closed after writing, then it will
be invalid and you won't be able to use it. Closing it is important.

This may be an important clue:

> The only time dur is 0 is when it is in the Button block, otherwise dur is
> set via information stored in a control bus.

In both cases, you're getting dur from the bus... so, when you click the
button, somehow the bus is not being set properly.

That's a potential difference: when you use the button to record, it's "set
\off --> immediately check the bus value," but when you run the function by
hand, it's "set \off --> some time passes --> check the bus value."

> FreeSelf.kr( time );

Shouldn't that be 'off' instead of 'time'?

I don't think you need Latch at all. Probably you put that in as a
workaround for using the wrong argument to FreeSelf, and that might be
causing the bus not to get the value in time. I would just do

Out.kr(recManualBus, phase);
FreeSelf.kr(off);

But I don't have any more time for today, sorry.

hjh



--
Sent from: http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/SuperCollider-Users-New-Use-this-f2676391.html

_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
Reply | Threaded
Open this post in threaded view
|

Re: function isnt evaluated in Button?

casey.thomas.anderson
Oh wow, good catch in the SynthDef. I have made that change and no longer have this problem with the button. I will work on implementing the fork and s.sync stuff over the weekend (got a lot of sound design work to catch up on tonight now that this is resolved).

Thanks for your patience and explanations, James. I really appreciate it.

Casey

On January 11, 2018 at 5:50:17 PM, [hidden email] ([hidden email]) wrote:

casey.thomas.anderson wrote
> The only time dur is 0 is when it is in the Button block, otherwise dur is
> set via information stored in a control bus. I just double checked against
> parameters for Buffer.write and can confirm that I have them in the
> correct
> order but did notice that I am not using leaveOpen so perhaps that being
> false by default is the problem?

OK, I just checked, you're right, it is numFrames first. And no, you do want
leaveOpen to be false. If the file isn't closed after writing, then it will
be invalid and you won't be able to use it. Closing it is important.

This may be an important clue:

> The only time dur is 0 is when it is in the Button block, otherwise dur is
> set via information stored in a control bus.

In both cases, you're getting dur from the bus... so, when you click the
button, somehow the bus is not being set properly.

That's a potential difference: when you use the button to record, it's "set
\off --> immediately check the bus value," but when you run the function by
hand, it's "set \off --> some time passes --> check the bus value."

> FreeSelf.kr( time );

Shouldn't that be 'off' instead of 'time'?

I don't think you need Latch at all. Probably you put that in as a
workaround for using the wrong argument to FreeSelf, and that might be
causing the bus not to get the value in time. I would just do

Out.kr(recManualBus, phase);
FreeSelf.kr(off);

But I don't have any more time for today, sorry.

hjh



--
Sent from: http://new-supercollider-mailing-lists-forums-use-these.2681727.n2.nabble.com/SuperCollider-Users-New-Use-this-f2676391.html

_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/