Env & PlayBuf

View: New views
4 Messages — Rating Filter:   Alert me  

Env & PlayBuf

by dkolokol () :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

hello, all!
i'm quite new to SC, so apologize if my question is dated and/or lame

i'm trying to build a looper with 2d-interface (for controlling [pos, dur] and rate), and wanted to get rid of clicks while looping buffer's content. i decided to Xfade start and end of a sample, and thought multiplying PlayBuf by Envelope would help. but somehow it didn't ((

here is the example:

b = Buffer.read(s,"sounds/a11wlk01-44_1.aiff");

(
{ var rate, dur, trig, pos, xFade, len;
        var bufnum = b.bufnum, busnum = 0, bufdur = b.numFrames / b.sampleRate, panidx=0, vol=0.8;
        pos = MouseX.kr(0, bufdur, 0); // arg X: position
        rate = MouseY.kr(-2, 2, 0);  //arg Y: rate -2..2 linear
        dur = (bufdur-pos)*(1/max(rate, 0.01));
        xFade = dur/6; // 1/6 of duration is xfade area
        len = dur-xFade; // for trigger and envelope
        trig = Impulse.kr(len.reciprocal);
        Pan2.ar(
                PlayBuf.ar(1, bufnum, rate*BufRateScale.kr(bufnum), trig, BufFrames.ir(bufnum)*pos, 1)
                                *(EnvGen.kr(Env.new([0, vol, vol, 0], [xFade, len, xFade], \welch, 2))),
        panidx)
}.scope(2, zoom: 4);
)


duration depends on startPos, but even with MouseX in 0 position samples last relatively shorter than they should be. and... clicks are still there ((

i feel that i forgot sthn really insubstantial, but can't figure out what exactly. so, will be enormously thankful for any kind of advice!
denis

Re: Env & PlayBuf

by miguel.negrao :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

We can check PlayBufCF of wslib Quark, it should do what you want.

Miguel

dkolokol escreveu:

> hello, all!
> i'm quite new to SC, so apologize if my question is dated and/or lame
>
> i'm trying to build a looper with 2d-interface (for controlling [pos, dur]
> and rate), and wanted to get rid of clicks while looping buffer's content. i
> decided to Xfade start and end of a sample, and thought multiplying PlayBuf
> by Envelope would help. but somehow it didn't ((
>
> here is the example:
>
> b = Buffer.read(s,"sounds/a11wlk01-44_1.aiff");
>
> (
> { var rate, dur, trig, pos, xFade, len;
>         var bufnum = b.bufnum, busnum = 0, bufdur = b.numFrames /
> b.sampleRate, panidx=0, vol=0.8;
>         pos = MouseX.kr(0, bufdur, 0); // arg X: position
>         rate = MouseY.kr(-2, 2, 0);  //arg Y: rate -2..2 linear
>         dur = (bufdur-pos)*(1/max(rate, 0.01));
>         xFade = dur/6; // 1/6 of duration is xfade area
>         len = dur-xFade; // for trigger and envelope
>         trig = Impulse.kr(len.reciprocal);
>         Pan2.ar(
>                 PlayBuf.ar(1, bufnum, rate*BufRateScale.kr(bufnum), trig,
> BufFrames.ir(bufnum)*pos, 1)
>                                 *(EnvGen.kr(Env.new([0, vol, vol, 0],
> [xFade, len, xFade], \welch, 2))),
>         panidx)
> }.scope(2, zoom: 4);
> )
>
>
> duration depends on startPos, but even with MouseX in 0 position samples
> last relatively shorter than they should be. and... clicks are still there
> ((
>
> i feel that i forgot sthn really insubstantial, but can't figure out what
> exactly. so, will be enormously thankful for any kind of advice!
> denis


--
Miguel Negrão // ZLB
http://www.friendlyvirus.org/artists/zlb/

_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/

Re: Env & PlayBuf

by Sciss-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

maybe this helps: you see that it is tricky to update the loop  
region, i'm only allowing it to take place at a new loop begin (using  
latch)

~protMakeDef = { arg defName, numChannels = 1;
        SynthDef.new( defName, { arg out, aInBuf, rate = 1.0, startFrame =  
0, numFrames;
                var lOffset, gate1, gate2, lLength, play1, play2, trig1, trig2,  
duration,
                        dlyDur, env, amp1, amp2, output, gateTrig1, gateTrig2;
               
                trig1 = LocalIn.kr( 1 ); // LFPulse.kr( freq: LocalIn.kr( 1 ).max
( 0.1 ));
                gateTrig1 = PulseDivider.kr( trig: trig1, div: 2, start: 1 );
                gateTrig2 = PulseDivider.kr( trig: trig1, div: 2, start: 0 );
                lOffset = Latch.kr( in: startFrame, trig: trig1 );
                lLength = Latch.kr( in: numFrames, trig: trig1 );
                duration = lLength / (rate * SampleRate.ir) - 2;
                gate1 = Trig1.kr( in: gateTrig1, dur: duration );
                env = Env.asr( 2, 1, 2, \lin ); // \sin
               
                play1 = PlayBuf.ar( numChannels: numChannels, bufnum: aInBuf, rate:  
rate, loop: 0,
                                                        trigger: gateTrig1, startPos: lOffset );
                play2 = PlayBuf.ar( numChannels: numChannels, bufnum: aInBuf, rate:  
rate, loop: 0,
                                                        trigger: gateTrig2, startPos: lOffset );
                amp1 = EnvGen.kr( env, gate1, 0.999 );  // 0.999 = bug fix !!!
                amp2 = 1.0 - amp1.squared;
                amp1 = 1.0 - amp1;
                amp1 = 1.0 - amp1.squared;
                output = (play1 * amp1) + (play2 * amp2);

                Out.ar( out, output );
       
                LocalOut.kr( Impulse.kr( 1.0 / duration.max( 0.1 )));
        });
};

// boot server and create a buffer
s.boot;
~maxFrames = s.sampleRate.asInteger * 6;  // note: net duration is  
minus 2 seconds due to xfade
~buf = Buffer.alloc( s, ~maxFrames );

// create and send the synthdef
~protMakeDef.( \testLoop ).send( s );

// record some sound from the microphone
(
Updater({
        RecordBuf.ar( SoundIn.ar( 0 ), ~buf.bufnum, loop: 0, doneAction:  
2 ); 0;
}.play.register, { arg obj, what; if( what === \n_end, { "Done  
Recording!".postln })});
"Started recording...";
)

// play it back in a loop
~looper = Synth( \testLoop, [ \aInBuf, ~buf.bufnum, \numFrames,  
~maxFrames ]);

// adjust the loop region
(
var w;
w = Window( "Looper", Rect( 100, 100, 400, 430 ), resizable: false );
Slider2D( w, Rect( 4, 4, 392, 392 )).x_( 0 ).y_( 1 )
        .action_({ arg slid;
                ~looper.set( \startFrame, (slid.x * ~maxFrames).asInteger,  
\numFrames, (min( 1 - slid.x, slid.y ) * ~maxFrames).asInteger );
        });
Slider( w, Rect( 4, 396, 392, 24 )).value_( 0.5 )
        .action_({ arg slid;
                ~looper.set( \rate, slid.value.linexp( 0, 1, 0.25, 4 ));
        });
w.front;
)

// clean up
~looper.free;
~buf.free;


ciao, -sciss-



Am 20.04.2009 um 11:43 schrieb dkolokol:

>
> hello, all!
> i'm quite new to SC, so apologize if my question is dated and/or lame
>
> i'm trying to build a looper with 2d-interface (for controlling  
> [pos, dur]
> and rate), and wanted to get rid of clicks while looping buffer's  
> content. i
> decided to Xfade start and end of a sample, and thought multiplying  
> PlayBuf
> by Envelope would help. but somehow it didn't ((
>
> here is the example:
>
> b = Buffer.read(s,"sounds/a11wlk01-44_1.aiff");
>
> (
> { var rate, dur, trig, pos, xFade, len;
>         var bufnum = b.bufnum, busnum = 0, bufdur = b.numFrames /
> b.sampleRate, panidx=0, vol=0.8;
>         pos = MouseX.kr(0, bufdur, 0); // arg X: position
>         rate = MouseY.kr(-2, 2, 0);  //arg Y: rate -2..2 linear
>         dur = (bufdur-pos)*(1/max(rate, 0.01));
>         xFade = dur/6; // 1/6 of duration is xfade area
>         len = dur-xFade; // for trigger and envelope
>         trig = Impulse.kr(len.reciprocal);
>         Pan2.ar(
>                 PlayBuf.ar(1, bufnum, rate*BufRateScale.kr(bufnum),  
> trig,
> BufFrames.ir(bufnum)*pos, 1)
>                                 *(EnvGen.kr(Env.new([0, vol, vol, 0],
> [xFade, len, xFade], \welch, 2))),
>         panidx)
> }.scope(2, zoom: 4);
> )
>
>
> duration depends on startPos, but even with MouseX in 0 position  
> samples
> last relatively shorter than they should be. and... clicks are  
> still there
> ((
>
> i feel that i forgot sthn really insubstantial, but can't figure  
> out what
> exactly. so, will be enormously thankful for any kind of advice!
> denis
> --
> View this message in context: http://www.nabble.com/Env---PlayBuf- 
> tp23019902p23019902.html
> Sent from the Supercollider - User mailing list archive at Nabble.com.
>
>
> _______________________________________________
> sc-users mailing list
>
> info (subscription, etc.): http://www.beast.bham.ac.uk/research/ 
> sc_mailing_lists.shtml
> archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
> search: http://www.listarc.bham.ac.uk/lists/sc-users/search/


_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/

Re: Env & PlayBuf

by dkolokol :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Sciss, thanks a lot, brilliant!

Miguel, thanks for the hint on wslib, a lot of interesting and useful
things there!

cheers!
denis


2009/4/20 Sciss <contact@...>:

> maybe this helps: you see that it is tricky to update the loop region, i'm
> only allowing it to take place at a new loop begin (using latch)
>
> ~protMakeDef = { arg defName, numChannels = 1;
>        SynthDef.new( defName, { arg out, aInBuf, rate = 1.0, startFrame = 0,
> numFrames;
>                var     lOffset, gate1, gate2, lLength, play1, play2, trig1,
> trig2, duration,
>                        dlyDur, env, amp1, amp2, output, gateTrig1,
> gateTrig2;
>
>                trig1   = LocalIn.kr( 1 ); // LFPulse.kr( freq: LocalIn.kr( 1
> ).max( 0.1 ));
>                gateTrig1       = PulseDivider.kr( trig: trig1, div: 2,
> start: 1 );
>                gateTrig2       = PulseDivider.kr( trig: trig1, div: 2,
> start: 0 );
>                lOffset = Latch.kr( in: startFrame, trig: trig1 );
>                lLength = Latch.kr( in: numFrames, trig: trig1 );
>                duration        = lLength / (rate * SampleRate.ir) - 2;
>                gate1   = Trig1.kr( in: gateTrig1, dur: duration );
>                env             = Env.asr( 2, 1, 2, \lin );     // \sin
>
>                play1   = PlayBuf.ar( numChannels: numChannels, bufnum:
> aInBuf, rate: rate, loop: 0,
>                                                        trigger: gateTrig1,
> startPos: lOffset );
>                play2   = PlayBuf.ar( numChannels: numChannels, bufnum:
> aInBuf, rate: rate, loop: 0,
>                                                        trigger: gateTrig2,
> startPos: lOffset );
>                amp1            = EnvGen.kr( env, gate1, 0.999 );  // 0.999 =
> bug fix !!!
>                amp2            = 1.0 - amp1.squared;
>                amp1            = 1.0 - amp1;
>                amp1            = 1.0 - amp1.squared;
>                output  = (play1 * amp1) + (play2 * amp2);
>
>                Out.ar( out, output );
>
>                LocalOut.kr( Impulse.kr( 1.0 / duration.max( 0.1 )));
>        });
> };
>
> // boot server and create a buffer
> s.boot;
> ~maxFrames = s.sampleRate.asInteger * 6;  // note: net duration is minus 2
> seconds due to xfade
> ~buf = Buffer.alloc( s, ~maxFrames );
>
> // create and send the synthdef
> ~protMakeDef.( \testLoop ).send( s );
>
> // record some sound from the microphone
> (
> Updater({
>        RecordBuf.ar( SoundIn.ar( 0 ), ~buf.bufnum, loop: 0, doneAction: 2 );
> 0;
> }.play.register, { arg obj, what; if( what === \n_end, { "Done
> Recording!".postln })});
> "Started recording...";
> )
>
> // play it back in a loop
> ~looper = Synth( \testLoop, [ \aInBuf, ~buf.bufnum, \numFrames, ~maxFrames
> ]);
>
> // adjust the loop region
> (
> var w;
> w = Window( "Looper", Rect( 100, 100, 400, 430 ), resizable: false );
> Slider2D( w, Rect( 4, 4, 392, 392 )).x_( 0 ).y_( 1 )
>        .action_({ arg slid;
>                ~looper.set( \startFrame, (slid.x * ~maxFrames).asInteger,
> \numFrames, (min( 1 - slid.x, slid.y ) * ~maxFrames).asInteger );
>        });
> Slider( w, Rect( 4, 396, 392, 24 )).value_( 0.5 )
>        .action_({ arg slid;
>                ~looper.set( \rate, slid.value.linexp( 0, 1, 0.25, 4 ));
>        });
> w.front;
> )
>
> // clean up
> ~looper.free;
> ~buf.free;
>
>
> ciao, -sciss-
>
>
>
> Am 20.04.2009 um 11:43 schrieb dkolokol:
>
>>
>> hello, all!
>> i'm quite new to SC, so apologize if my question is dated and/or lame
>>
>> i'm trying to build a looper with 2d-interface (for controlling [pos, dur]
>> and rate), and wanted to get rid of clicks while looping buffer's content.
>> i
>> decided to Xfade start and end of a sample, and thought multiplying
>> PlayBuf
>> by Envelope would help. but somehow it didn't ((
>>
>> here is the example:
>>
>> b = Buffer.read(s,"sounds/a11wlk01-44_1.aiff");
>>
>> (
>> { var rate, dur, trig, pos, xFade, len;
>>        var bufnum = b.bufnum, busnum = 0, bufdur = b.numFrames /
>> b.sampleRate, panidx=0, vol=0.8;
>>        pos = MouseX.kr(0, bufdur, 0); // arg X: position
>>        rate = MouseY.kr(-2, 2, 0);  //arg Y: rate -2..2 linear
>>        dur = (bufdur-pos)*(1/max(rate, 0.01));
>>        xFade = dur/6; // 1/6 of duration is xfade area
>>        len = dur-xFade; // for trigger and envelope
>>        trig = Impulse.kr(len.reciprocal);
>>        Pan2.ar(
>>                PlayBuf.ar(1, bufnum, rate*BufRateScale.kr(bufnum), trig,
>> BufFrames.ir(bufnum)*pos, 1)
>>                                *(EnvGen.kr(Env.new([0, vol, vol, 0],
>> [xFade, len, xFade], \welch, 2))),
>>        panidx)
>> }.scope(2, zoom: 4);
>> )
>>
>>
>> duration depends on startPos, but even with MouseX in 0 position samples
>> last relatively shorter than they should be. and... clicks are still there
>> ((
>>
>> i feel that i forgot sthn really insubstantial, but can't figure out what
>> exactly. so, will be enormously thankful for any kind of advice!
>> denis
>> --
>> View this message in context:
>> http://www.nabble.com/Env---PlayBuf-tp23019902p23019902.html
>> Sent from the Supercollider - User mailing list archive at Nabble.com.
>>
>>
>> _______________________________________________
>> sc-users mailing list
>>
>> info (subscription, etc.):
>> http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml
>> archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
>> search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
>
>
> _______________________________________________
> sc-users mailing list
>
> info (subscription, etc.):
> http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml
> archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
> search: http://www.listarc.bham.ac.uk/lists/sc-users/search/
>
>
>



--
all the best!
denis
mailto: dkolokol@...
skype: denis.kolokol

www.indie.org.ua
independent music web-zine from Ukraine

www.gurkit.org
GURKIT - Ukrainian magazine for contemporary music

www.replicafest.org
REPLICA - independent experimental media art fest

_______________________________________________
sc-users mailing list

info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml
archive: http://www.listarc.bham.ac.uk/marchives/sc-users/
search: http://www.listarc.bham.ac.uk/lists/sc-users/search/