From: owner-sc-users-digest@lists.io.com (sc-users-digest) To: sc-users-digest@lists.io.com Subject: sc-users-digest V1 #49 Reply-To: sc-users Sender: owner-sc-users-digest@lists.io.com Errors-To: owner-sc-users-digest@lists.io.com Precedence: bulk sc-users-digest Sunday, July 4 1999 Volume 01 : Number 049 ---------------------------------------------------------------------- Date: Wed, 30 Jun 1999 21:32:02 +0300 From: laurson@amadeus.siba.fi (Mikael Laurson) Subject: Problems with TapA and TapL? James, I found some problems when using TapA and TapL. I used MatLab to test various excitation samples. The samples were fed to a delay-line which uses the interpolation algorithm by Vesa Valimaki. If I understand it well the same algorithm is used by the TapA and TapN ugens in SC2 (am I right?). After this I wrote the following SC2 code and found that there is a strange artefact in the attack. (var filename, sound, signal; var buffer, samp, fltdel, fr, gain, coef, cursstrfret, curinfo, sample; fr = 330.9; coef = 0.0793; gain = 0.9938; filename = "HD:Desktop Folder:ex:ex100"; sound = SoundFile.new; if (sound.read(filename), { signal = sound.data.at(0); Synth.play({ buffer = [Signal.new(Synth.sampleRate * 0.03)]; samp = Line.kr(1,0,0.2)* PlayBuf.ar(signal, sound.sampleRate, 1, 0, 0, signal.size-2); fltdel = OnePole.ar(TapA.ar(buffer, 1/fr, 1, 0), coef, gain, 0); DelayWr.ar(buffer, fltdel+samp); fltdel }); },{ (filename ++ " not found.\n").post }); ) If I change TapA to TapN in some rare cases the artefact disappears and the sound is very close to the one produced by MatLab. In MatLab all the tests produce a clean result. Can there be a problem in the interpolation algorithm used by TapA and TapL? Mikael ================================ Mikael Laurson Hollantilaisentie 1 A 2 00300 Helsinki 33 Finland E-mail: laurson@siba.fi ================================ ------------------------------ Date: Wed, 30 Jun 1999 16:25:45 -0600 From: James McCartney <---@---.---> Subject: Re: Problems with TapA and TapL? At 12:32 PM -0600 6/30/99, Mikael Laurson wrote: >James, > >I found some problems when using TapA and TapL. >I used MatLab to test various excitation samples. >The samples were fed to a delay-line which uses >the interpolation algorithm by Vesa Valimaki. >If I understand it well the same algorithm is >used by the TapA and TapN ugens in SC2 (am I right?). > >After this I wrote the following SC2 code and found >that there is a strange artefact in the attack. ... >If I change TapA to TapN in some rare cases the artefact >disappears and the sound is very close to the one produced by >MatLab. > >In MatLab all the tests produce a clean result. > >Can there be a problem in the interpolation algorithm used >by TapA and TapL? > >Mikael I don't see it. Of course, I do not have your sound file. All of the following work as expected for me. ( var filename, sound, signal; var buffer, samp, fltdel, fr, gain, coef, cursstrfret, curinfo, sample; fr = 330.9; coef = 0.0793; gain = 0.9938; filename = ":Sounds:floating_1"; sound = SoundFile.new; if (sound.read(filename), { signal = sound.data.at(0); Synth.play({ buffer = [Signal.new(Synth.sampleRate * 0.03)]; samp = Line.kr(1,0,0.2)* PlayBuf.ar(signal, sound.sampleRate, 1, 0, 0, signal.size-2); fltdel = OnePole.ar(TapA.ar(buffer, 1/fr, 1, 0), coef, gain, 0); DelayWr.ar(buffer, fltdel+samp); fltdel }); },{ (filename ++ " not found.\n").post }); ) ( var filename, sound, signal; var buffer, samp, fltdel, fr, gain, coef, cursstrfret, curinfo, sample; fr = 330.9; coef = 0.0793; gain = 0.9938; Synth.play({ buffer = [Signal.new(Synth.sampleRate * 0.03)]; samp = Line.kr(1,0,0.2) * Impulse.ar(20); fltdel = OnePole.ar(TapA.ar(buffer, 1/fr, 1, 0), coef, gain, 0); DelayWr.ar(buffer, fltdel+samp); fltdel }); ) ( var filename, sound, signal; var buffer, samp, fltdel, fr, gain, coef, cursstrfret, curinfo, sample; fr = 330.9; coef = 0.0793; gain = 0.9938; Synth.play({ buffer = [Signal.new(Synth.sampleRate * 0.03)]; samp = Impulse.ar(1); fltdel = OnePole.ar(TapA.ar(buffer, 1/fr, 1, 0), coef, gain, 0); DelayWr.ar(buffer, fltdel+samp); fltdel }); ) --- james mccartney james@audiosynth.com http://www.audiosynth.com If you have a PowerMac check out SuperCollider2, a real time synth program: < ------------------------------ Date: Thu, 1 Jul 1999 12:25:39 +0300 From: laurson@amadeus.siba.fi (Mikael Laurson) Subject: Problems with TapA and TapL? >I don't see it. Of course, I do not have your sound file. Should I send you two sound files (the excitation sample "ex100" and the MatLab result) to your personal E-mail address? Is it james@audiosynth.com? Mikael ================================ Mikael Laurson Hollantilaisentie 1 A 2 00300 Helsinki 33 Finland E-mail: laurson@siba.fi ================================ ------------------------------ Date: Thu, 01 Jul 1999 15:09:44 +0200 From: Ioannis Zannos <---@---.---> Subject: Testing MIDIOut(Re: version 2.1.6 available) James McCartney wrote: > Version 2.1.6 is now available via ftp: ... > (You might also try MIDIOut, I've not tested it yet, > but I fixed a bug in it.) I tried the following: (Pbind( \midinote, Pseq(#[60, 62, 64], 10), \ugenFunc, { arg midinote; [\midinote_output, midinote].postln; MIDIOut(0).noteOn(0, midinote, 64); FSinOsc.ar(midinote.midicps, Line.kr(0.1, 0, 0.1)) } ).play(channels: 1) ) With MidiInstruments/QuickTime MIDI as synthesizer. There was no audible tone produced from QT MIDI. I am using OMS 2.3.7 with no MIDI hardware attached at all. OMS preferred device is set to QuickTime MIDI. Did anybody succeed in getting any sound by MIDI out yet? Iannis Zannos SIM ------------------------------ Date: Thu, 1 Jul 1999 09:22:27 -0600 From: James McCartney <---@---.---> Subject: Re: Testing MIDIOut(Re: version 2.1.6 available) At 7:09 AM -0600 7/1/99, Ioannis Zannos wrote: >James McCartney wrote: > >> Version 2.1.6 is now available via ftp: > >... > >> (You might also try MIDIOut, I've not tested it yet, >> but I fixed a bug in it.) > >I tried the following: > > >(Pbind( > \midinote, Pseq(#[60, 62, 64], 10), > \ugenFunc, { arg midinote; > [\midinote_output, midinote].postln; > MIDIOut(0).noteOn(0, midinote, 64); > FSinOsc.ar(midinote.midicps, Line.kr(0.1, 0, 0.1)) } > > ).play(channels: 1) >) > >With MidiInstruments/QuickTime MIDI as synthesizer. >There was no audible tone produced from QT MIDI. >I am using OMS 2.3.7 with no MIDI hardware attached >at all. OMS preferred device is set to QuickTime MIDI. > >Did anybody succeed in getting any sound by MIDI out yet? Yes. I can get QT Music to work. 1. you need to make sure you are sending to the correct port. SC lists the OMS ports on startup. You want to use the value listed there under "index:" as the port number for MIDIOut. 2. 0 is not a legal MIDI channel. MIDI channels start at 1. 3. You must make sure that QT Music is turned on in your OMS Setup. The default is to have it turned off. 4. QT Music must actually be installed. Just because SC and OMS show it available does not mean it is installed. OMS will tell you if it is not installed when you turn it on in your OMS Setup. 5. QT Music appears to cause problems with the Digi drivers. You need to turn off the Digi System Init to use QT Music. Otherwise SC will fail to open DirectIO and the Digi Apple driver then hangs. --- james mccartney james@audiosynth.com http://www.audiosynth.com If you have a PowerMac check out SuperCollider2, a real time synth program: ------------------------------ Date: Thu, 01 Jul 1999 17:56:34 +0200 From: Ioannis Zannos <---@---.---> Subject: [Fwd: passing inval to subpatters ???????] This is a multi-part message in MIME format. - --------------D214F732AF215841F900158F Content-Type: text/plain; charset=us-ascii; x-mac-type="54455854"; x-mac-creator="4D4F5353" Content-Transfer-Encoding: 7bit James McCartney wrote: > If I were to write a class I would write it as follows: > > Pwhatever : Pattern { > var <>pat, <>func, <>repeats; ... > inval = localPat.embedInStream(inval); > localPat = func.value(localPat, i); Thanks for the tip on inval = ... But: The pattern above will work well for pure recursive structures only, not for "lacing." or other similar Pfilter like structures. A pattern for the latter job would be: Pstream : Pattern { var <>state, <>func, <>repeats; *new { arg pat, func, repeats; ^super.new.state_(pat).func_(func).repeats_(repeats) } asStream { ^Routine.new({ arg inval; var localStream; localStream = state.value.asStream; repeats.do({ arg i; inval = func.value(localStream, i, inval).embedInStream(inval); }); }) } } Can do things like: Pbind( \dur, 0.1, \legato, 0.3, \degree, Pstream( Pseq(#[-10, -7, 3, [-17, 10, 15, 18]], inf), { arg stream, n; Pseq([Pseq(#[0, 2, [4, 6], [0, 2, 7, 5], 4]) - (( n%20)-10), stream.next]); }, inf) ).play(channels: 1) ) But I still cannot understand how the inval event is passed: // Debug: Pbind( \degree, Pcstate( Pseq( [Pfuncn({ arg in; ["1. received input for next: ", in].postln; 7 }), - -7, Pfuncn({ arg in; ["2. received input for next: ", in].postln; 4 }), - -3], inf), { arg stream, n, inval; var nstream; ["Passing this as argument to stream next: ", inval].postln; nstream = stream.next(inval); Pseq([Pseq(#[0]), nstream]); }, inf) ).play(channels: 1) This will print the following perplexing results: [ Passing this as argument to stream next: , Event[*29] ] [ 1. received input for next: , Event[*29] ] [ Passing this as argument to stream next: , Event[*29] ] [ Passing this as argument to stream next: , Event[*29] ] [ 2. received input for next: , -7 ] [ Passing this as argument to stream next: , Event[*29] ] [ Passing this as argument to stream next: , Event[*29] ] [ 1. received input for next: , -3 ] [ Passing this as argument to stream next: , Event[*29] ] Question: why is the inval printed out as Event[*29] on the calling function but then one statement later it is received as -7 or -3 by the called stream: nstream = stream.next(inval); ??? Iannis Zannos SIM - --------------D214F732AF215841F900158F Content-Type: message/rfc822 Content-Transfer-Encoding: 7bit Content-Disposition: inline X-Mozilla-Status2: 00000000 Message-ID: <377B7D60.BEC4CDB1@sim.spk-berlin.de> Date: Thu, 01 Jul 1999 16:38:30 +0200 From: Ioannis Zannos <---@---.---> Reply-To: iani@sim.spk-berlin.de Organization: SIM X-Mailer: Mozilla 4.61 (Macintosh; I; PPC) X-Accept-Language: en MIME-Version: 1.0 To: James McCartney Subject: passing inval to subpatters ??????? References: Content-Type: text/plain; charset=us-ascii; x-mac-type="54455854"; x-mac-creator="4D4F5353" Content-Transfer-Encoding: 7bit James McCartney wrote: > If I were to write a class I would write it as follows: > > Pwhatever : Pattern { > var <>pat, <>func, <>repeats; ... > inval = localPat.embedInStream(inval); > localPat = func.value(localPat, i); Thanks for the tip on inval = ... But: The pattern above will work well for pure recursive structures only, not for "lacing." or other similar Pfilter like structures. A pattern for the latter job would be: Pstream : Pattern { var <>state, <>func, <>repeats; *new { arg pat, func, repeats; ^super.new.state_(pat).func_(func).repeats_(repeats) } asStream { ^Routine.new({ arg inval; var localStream; localStream = state.value.asStream; repeats.do({ arg i; inval = func.value(localStream, i, inval).embedInStream(inval); }); }) } } Can do things like: Pbind( \dur, 0.1, \legato, 0.3, \degree, Pstream( Pseq(#[-10, -7, 3, [-17, 10, 15, 18]], inf), { arg stream, n; Pseq([Pseq(#[0, 2, [4, 6], [0, 2, 7, 5], 4]) - (( n%20)-10), stream.next]); }, inf) ).play(channels: 1) ) But I still cannot understand how the inval event is passed: // Debug: Pbind( \degree, Pcstate( Pseq( [Pfuncn({ arg in; ["1. received input for next: ", in].postln; 7 }), - -7, Pfuncn({ arg in; ["2. received input for next: ", in].postln; 4 }), - -3], inf), { arg stream, n, inval; var nstream; ["Passing this as argument to stream next: ", inval].postln; nstream = stream.next(inval); Pseq([Pseq(#[0]), nstream]); }, inf) ).play(channels: 1) This will print the following perplexing results: [ Passing this as argument to stream next: , Event[*29] ] [ 1. received input for next: , Event[*29] ] [ Passing this as argument to stream next: , Event[*29] ] [ Passing this as argument to stream next: , Event[*29] ] [ 2. received input for next: , -7 ] [ Passing this as argument to stream next: , Event[*29] ] [ Passing this as argument to stream next: , Event[*29] ] [ 1. received input for next: , -3 ] [ Passing this as argument to stream next: , Event[*29] ] Question: why is the inval printed out as Event[*29] on the calling function but then one statement later it is received as -7 or -3 by the called stream: nstream = stream.next(inval); ??? Iannis Zannos SIM - --------------D214F732AF215841F900158F-- ------------------------------ Date: Thu, 01 Jul 1999 18:46:25 +0200 From: Staffan Liljegren <---@---.---> Subject: Re: Testing MIDIOut(Re: version 2.1.6 available) I get it to work too, but I get an error when I try to use the method "program" (outcommented below) - -Staffan (Pbind( \midinote, Pseq(#[60, 66, 71], inf), \dur, Prand([ Pseq(#[0.125],4), Pseq(#[0.166],3), 0.5], inf), \ugenFunc, { arg midinote; var ch; ch = MIDIOut(0); //ch.program(1, 24); ch.noteOn(1, midinote, 50); FSinOsc.ar(midinote.midicps, Line.kr(0.1, 0, 0.1)) } ).play(channels: 1) ) James McCartney wrote: > At 7:09 AM -0600 7/1/99, Ioannis Zannos wrote: > >James McCartney wrote: > > > >> Version 2.1.6 is now available via ftp: > > > >... > > > >> (You might also try MIDIOut, I've not tested it yet, > >> but I fixed a bug in it.) > > > >I tried the following: > > > > > >(Pbind( > > \midinote, Pseq(#[60, 62, 64], 10), > > \ugenFunc, { arg midinote; > > [\midinote_output, midinote].postln; > > MIDIOut(0).noteOn(0, midinote, 64); > > FSinOsc.ar(midinote.midicps, Line.kr(0.1, 0, 0.1)) } > > > > ).play(channels: 1) > >) > > > >With MidiInstruments/QuickTime MIDI as synthesizer. > >There was no audible tone produced from QT MIDI. > >I am using OMS 2.3.7 with no MIDI hardware attached > >at all. OMS preferred device is set to QuickTime MIDI. > > > >Did anybody succeed in getting any sound by MIDI out yet? > > Yes. I can get QT Music to work. > > 1. you need to make sure you are sending to the correct port. > SC lists the OMS ports on startup. You want to use the > value listed there under "index:" as the port number for MIDIOut. > > 2. 0 is not a legal MIDI channel. MIDI channels start at 1. > > 3. You must make sure that QT Music is turned on in your OMS Setup. > The default is to have it turned off. > > 4. QT Music must actually be installed. Just because SC and OMS show > it available does not mean it is installed. OMS will tell you > if it is not installed when you turn it on in your OMS Setup. > > 5. QT Music appears to cause problems with the Digi drivers. > You need to turn off the Digi System Init to use QT Music. > Otherwise SC will fail to open DirectIO and the Digi Apple driver > then hangs. > > --- james mccartney james@audiosynth.com http://www.audiosynth.com > If you have a PowerMac check out SuperCollider2, a real time synth program: > ------------------------------ Date: Thu, 1 Jul 1999 12:18:34 -0600 From: James McCartney <---@---.---> Subject: Re: Testing MIDIOut(Re: version 2.1.6 available) At 10:46 AM -0600 7/1/99, Staffan Liljegren wrote: >I get it to work too, but I get an error when I try >to use the method "program" (outcommented below) Oh, easy to fix.. Change a line in MIDIOut.sc from this: write { arg port, len, hiStatus, chan, a, b, c; to this: write { arg port, len, hiStatus, chan, a=0, b=0, c=0; --- james mccartney james@audiosynth.com http://www.audiosynth.com If you have a PowerMac check out SuperCollider2, a real time synth program: < ------------------------------ Date: Thu, 01 Jul 1999 23:39:45 +0200 From: Staffan Liljegren <---@---.---> Subject: Re: Testing MIDIOut(Re: version 2.1.6 available) Thanks. what about chords. Is it supposed to work with sending chord lists to MIDIOut or will noteOn work the MIDI way with one note ? - -Staffan (Pbind( \midinote, Pseq(#[60, \rest, 66, 71], inf) + Prand(#[0,0,0,0,[0,6]], inf), \tempo, 1.3, \dur, Prand([ Pseq(#[0.25],2), Pseq(#[0.166],3), 0.5], inf), \ugenFunc, { arg midinote; var ch; ch = MIDIOut(0); //ch.program(1, 24); ch.noteOn(1, midinote, 50); FSinOsc.ar(midinote.midicps, Line.kr(0.1, 0, 0.2)) } ).play(channels: 2) ) Which gives this error: ERROR: Primitive '_MIDIOut_Write' failed. Wrong type. RECEIVER: Instance of MIDIOut { (094D653C, gc=02, fmt=00, flg=00, set=00) instance variables [1] port : Integer 0 } CALL STACK: Object : primitiveFailed arg this = MIDIOut : write arg this = arg port = 0 arg len = 3 arg hiStatus = 144 arg chan = 1 arg a = [*2] arg b = 50 arg c = nil MIDIOut : noteOn arg this = arg chan = 1 arg note = [*2] arg veloc = 50 arg midinote = [*2] var ch = arg i = 0 var freq = nil arg i = 0 Integer : do arg this = 2 arg function = var i = 0 Meta_Collection : fill arg this = arg size = 2 arg function = var obj = [*0] ... James McCartney wrote: > At 10:46 AM -0600 7/1/99, Staffan Liljegren wrote: > >I get it to work too, but I get an error when I try > >to use the method "program" (outcommented below) > > Oh, easy to fix.. Change a line in MIDIOut.sc from this: > > write { arg port, len, hiStatus, chan, a, b, c; > > to this: > > write { arg port, len, hiStatus, chan, a=0, b=0, c=0; > > --- james mccartney james@audiosynth.com http://www.audiosynth.com > If you have a PowerMac check out SuperCollider2, a real time synth program: > ------------------------------ Date: Thu, 1 Jul 1999 16:57:48 -0600 From: James McCartney <---@---.---> Subject: Re: Testing MIDIOut(Re: version 2.1.6 available) At 3:39 PM -0600 7/1/99, Staffan Liljegren wrote: >Thanks. what about chords. Is it supposed to work >with sending chord lists to MIDIOut or will noteOn >work the MIDI way with one note ? > MIDIOut is just one event at a time. The error happens because \freq is the value that is separated into events, not \midinote. Because \ctranspose could be a list, you could have a case where \midinote's value is not a list, but \freq's value is. --- james mccartney james@audiosynth.com http://www.audiosynth.com If you have a PowerMac check out SuperCollider2, a real time synth program: ------------------------------ Date: Fri, 02 Jul 1999 23:38:46 +0200 From: Ioannis Zannos <---@---.---> Subject: Re: Testing MIDIOut(Re: version 2.1.6 available) James McCartney wrote: > > Yes. I can get QT Music to work. > ... > 4. QT Music must actually be installed. Just because SC and OMS show > it available does not mean it is installed. OMS will tell you > if it is not installed when you turn it on in your OMS Setup. > > 5. QT Music appears to cause problems with the Digi drivers. > You need to turn off the Digi System Init to use QT Music. > Otherwise SC will fail to open DirectIO and the Digi Apple driver > then hangs. Yes. QT Music works for me also - after turning it on. About 5: Digi drivers; that could be the problem I had with trying to use SC with the new 24 bit ProTools hardware. For the record, I would like to cite here below the error messages given by SC before freeze - in case they are relevant for your further debugging (or you could give me any other clues in making SC to work with Digi): Iannis Zannos (SIM) The error messages are: ... o ERROR: SndGetInfo siHardwareFormat error: -50 o ERROR: SndGetInfo siHardwareFormat error: -50 IODriverAcquireDevice: Device Not Available (-6011) o ERROR: digi sound driver could not be opened. using Apple Sound Mgr input and output buffers not the same size?? 512 1024 set to: 512 512 ------------------------------ Date: Fri, 02 Jul 1999 23:56:08 +0200 From: Ioannis Zannos <---@---.---> Subject: Scheduling MIDI Note off in patterns/Re: Testing MIDIOut(Re: version 2.1.6 available) James McCartney wrote: > >> (You might also try MIDIOut, I've not tested it yet, Pbind( \midinote, Pseq(#[60, 62, 64], 10), \ugenFunc, { arg midinote; MIDIOut(0).noteOn(1, midinote, 64); Synth.newSynth.sched(0.2, { [midinote, "Out, out, brief candle!"].postln; MIDIOut(0).noteOn(1, midinote, 0); }); FSinOsc.ar(midinote.midicps, Line.kr(0.1, 0, 0.1)) } ).play(channels: 1) Will post: [ 62, Out, out, brief candle! ] [ 64, Out, out, brief candle! ] [ 60, Out, out, brief candle! ] [ 62, Out, out, brief candle! ] Why is the first Note off scheduled process, which would turn off the first note played = 60, ALWAYS omitted here? Apparently Synth.newSynth returns the next synth, which is already spawned at the moment the first note is played, while the next note has not sounded yet? Iannis Zannos SIM ------------------------------ Date: Fri, 2 Jul 1999 17:18:56 -0600 From: James McCartney <---@---.---> Subject: Re: Scheduling MIDI Note off in patterns/Re: Testing MIDIOut(Re: version 2.1.6 available) At 3:56 PM -0600 7/2/99, Ioannis Zannos wrote: >Why is the first Note off scheduled process, >which would turn off the first note played = 60, >ALWAYS omitted here? Apparently Synth.newSynth >returns the next synth, which is already spawned at >the moment the first note is played, while the next note >has not sounded yet? The synth you are scheduling from ends before the scheduled event happens, so it never does. Synth.newSynth returns the synth currently being spawned. You should spawn a voice to last as long as your midi sequence and have that voice read from a pattern and schedule from it. --- james mccartney james@audiosynth.com http://www.audiosynth.com If you have a PowerMac check out SuperCollider2, a real time synth program: ------------------------------ Date: Sat, 03 Jul 1999 18:16:43 -0400 From: "crucial" <---@---.---> Subject: Streams within a stream One problem I've been trying to crack is how to best use synchronized patterns to control a continuous thing like an Oscillator or effects like delays, and within that to play a pattern that serves as its input. Using the event stream to drive things that don't open and close their EnvGens each time. So I figured out to pass the subpattern as a Ref and deref it inside the efx ugen, then play it asSpawn. This is not explicitly synchronized, though the beats will match up. The simple solution. More preferable would be to leave the subpattern in the tree of patterns, (so it takes part in any global rhythmic happenings) but still be able to have its 'audio' happen inside of another pattern's ugenFunc. So I didn't fully extrapolate this yet, but I thought I would pass the idea out here for comments. ( var e; var synthuF, efxuF; var efx, synth; var tonerows; e=Event.protoEvent; //currentEnvironment=e; synthuF={ EnvGen.ar(Env.adsr, COsc2.ar(Wavetable.sineFill(512, 1.0/[1,2,3,4,5,6]), Wavetable.sineFill(512, 1.0/[6,5,4,3,2,1]), ~freq,1) ,0,~amp,0,~legato)}; efxuF={arg spawn,synth,evnt; var sound, controlevent; /* // see below if(~controls.notNil,{ ~controls=~controls.asEventStream(Event2.protoEvent); synth.sched(0,{arg synth,now,task; controlevent=~controls.next; // drive a bunch of plugs to talk to the ugens here //controlevent.use({drivers.xline(~freq);}); synth.sched(now+controlevent.delta,task) }) }); */ if(~subpattern.notNil,{ sound=~subpattern.dereference.asSpawn(e,2) },{ sound=0.0; }); sound=RLPF.ar(sound,~ffreq,~rq); 2.do({ "building".postln; sound= AllpassN.ar(sound, ~range, [~range.rand, ~range.rand], 1) }); // why still in mono ? doesn't ^^^^ expand ? EnvGen.ar(Env.adsr(0.05,1,1,0.5,1),sound); }; tonerows=[ #[ 8, 0, 4, 13, 4, 10, 5, 9 ], #[ 8, -2, 4, 13, 4, 10, 5, 7 ], #[ 8, 0, 5, 15, 4, 8, 4, 4 ], #[ 10, -1, 17, 8, -2, 6, 3, 6 ], #[ 9, 2, 19, 9, 0, 6, 3, 6 ] ]; synth= // synth Pbind ( \ugenFunc,synthuF, \legato,Pbrown(0.25,0.9,0.1,inf), \dur,0.25, \note,Pstutter(1,Pseq(tonerows.choose,inf)), \octave,3, \db,-20, \tempo,2 ); // efx Pbind(\ugenFunc,efxuF, \dur,8, \range,Pbrown(0.05,0.25,0.05,inf), \ffreq,5000, \rq,0.5, \subpattern,`synth, \legato,1, \tempo,2 ).play(e,2) ) In this case, its a lot of processing power to start up the AllpassN , and it glitches. Probably better to create one chain of Allpass etc. outside the ugen and just plug into it. Or a bunch of them and build a little patch on the fly (out of already existing instances). re: the control section above that would allow the individual events to be brought forth, their property values questioned, and then probably plug.line(~value,0.1) to send it to the oscillator or whatever. but another system looms on the horizon... __________________________________________ :\\_______ http://crucial-systems.com __________________________________________ :\\_______ ------------------------------ Date: Sat, 3 Jul 1999 17:49:50 -0600 From: James McCartney <---@---.---> Subject: Re: Streams within a stream At 4:16 PM -0600 7/3/99, crucial wrote: > COsc2.ar(Wavetable.sineFill(512, 1.0/[1,2,3,4,5,6]), calling sineFill in your instrument function is what is glitching. Never put that in a spawned function. Build your tables before you start playing. --- james mccartney james@audiosynth.com http://www.audiosynth.com If you have a PowerMac check out SuperCollider2, a real time synth program: ------------------------------ Date: Sat, 3 Jul 1999 19:08:54 -0600 From: James McCartney <---@---.---> Subject: Re: Streams within a stream At 4:16 PM -0600 7/3/99, crucial wrote: >( > >var e; >var synthuF, efxuF; >var efx, synth; >var tonerows; > >e=Event.protoEvent; >//currentEnvironment=e; > >synthuF={ EnvGen.ar(Env.adsr, > COsc2.ar(Wavetable.sineFill(512, 1.0/[1,2,3,4,5,6]), > Wavetable.sineFill(512, 1.0/[6,5,4,3,2,1]), > ~freq,1) a) The wavetables should not be built in the synth function. b) It is pointless to use COsc2 with two identical tables. The idea for COsc2 is to use two tables with differing phases. Otherwise use COsc. c) you should not access event variables using the ~ syntax inside the synth function. The function is called using valueEnvir so if you provide appropriately named arguments they will get filled in. e.g. synthuF={ arg freq, amp, legato; >efxuF={arg spawn,synth,evnt; d) The function is not called with spawn, synth, etc arguments. It is called with valueEnvir. Any arguments you provide will get filled in from the current environment, i.e. Event. efxuF = { arg subpattern, ffreq, rq, range, env; > // why still in mono ? doesn't ^^^^ expand ? > EnvGen.ar(Env.adsr(0.05,1,1,0.5,1),sound); e) Don't build your envelope here. It is the same for every event, so build into your event. e.g. Pbind(... \env, Env.adsr(0.05,1,1,0.5,1), Then the envelope gets built once when the Pbind is created instead of built anew for each event. f) This is much more efficient. sound * EnvGen.ar(env) The way you do it above causes two EnvGens to be created due to multichannel expansion. Using a kr envelope is even better. g) It is mono because: sound=subpattern.dereference.asSpawn(e,2) creates a two channel sound but the synthuF function only makes one channel of output. So the right channel is silent. Changing that line to sound=subpattern.dereference.asSpawn(e,1) will make it mono and so it then DOES expand to both channels of the allpass chain. h) tonerows=[ #[ 8, 0, 4, 13, 4, 10, 5, 9 ], #[ 8, -2, 4, 13, 4, 10, 5, 7 ], #[ 8, 0, 5, 15, 4, 8, 4, 4 ], #[ 10, -1, 17, 8, -2, 6, 3, 6 ], #[ 9, 2, 19, 9, 0, 6, 3, 6 ] ]; can be rewritten as: tonerows= #[ [ 8, 0, 4, 13, 4, 10, 5, 9 ], [ 8, -2, 4, 13, 4, 10, 5, 7 ], [ 8, 0, 5, 15, 4, 8, 4, 4 ], [ 10, -1, 17, 8, -2, 6, 3, 6 ], [ 9, 2, 19, 9, 0, 6, 3, 6 ] ]; i) \note,Pstutter(1,Pseq(tonerows.choose,inf)), You do realize that this chooses only one tone row to be played per interpreter session (i.e. from press enter to press cmd period). That choose only executes once and that Pseq gets created with that row. j) 'play' takes a function to use for adding effects to the main pattern. This could be rewritten a little cleaner by using that method, but I'll save that for later. Here is my modified version. Uses much less CPU. (I added a few more harmonics to the wavetables...) ( var e; var synthuF, efxuF; var efx, synth; var tonerows; var t; e=Event.protoEvent; t = Wavetable.sineFill(512, 1.0/[1,2,3,4,5,6,7,8,9,10,11,12]); synthuF={ arg freq, amp, legato; EnvGen.ar(Env.adsr, COsc.ar(t, freq,1) ,0,amp,0,legato)}; efxuF={ arg subpattern, ffreq, rq, range, env; var sound, controlevent; if(subpattern.notNil,{ sound=subpattern.dereference.asSpawn(e,1) },{ sound=0.0; }); sound=RLPF.ar(sound,ffreq,rq); 2.do({ sound = AllpassN.ar(sound, range, [range.rand, range.rand], 1) }); EnvGen.kr(env) * sound; }; tonerows= #[ [ 8, 0, 4, 13, 4, 10, 5, 9 ], [ 8, -2, 4, 13, 4, 10, 5, 7 ], [ 8, 0, 5, 15, 4, 8, 4, 4 ], [ 10, -1, 17, 8, -2, 6, 3, 6 ], [ 9, 2, 19, 9, 0, 6, 3, 6 ] ]; synth= // synth Pbind ( \ugenFunc,synthuF, \legato, Pbrown(0.25,0.9,0.1,inf), \dur,0.25, \note,Pstutter(1,Pseq(tonerows.choose,inf)), \octave,3, \db,-20, \tempo,2 ); // efx Pbind(\ugenFunc, efxuF, \dur,8, \range,Pbrown(0.05,0.25,0.05,inf), \ffreq,5000, \rq,0.5, \subpattern,`synth, \legato,1, \tempo,2, \env,Env.adsr(0.05,1,1,0.5,1) ).play(e,2) ) --- james mccartney james@audiosynth.com http://www.audiosynth.com If you have a PowerMac check out SuperCollider2, a real time synth program: < ------------------------------ Date: Sat, 3 Jul 1999 19:22:22 -0600 From: James McCartney <---@---.---> Subject: Re: Streams within a stream At 4:16 PM -0600 7/3/99, crucial wrote: >synthuF={ EnvGen.ar(Env.adsr, > COsc2.ar(Wavetable.sineFill(512, 1.0/[1,2,3,4,5,6]), > Wavetable.sineFill(512, 1.0/[6,5,4,3,2,1]), > ~freq,1) > ,0,~amp,0,~legato)}; Not sure why you use legato to time scale the envelope? The envelope sustain time is taken care of in the asSpawn method: innersynth.releaseTime = ~sustain; That will cause the synth to release the envelope. Again the same note about using a kr envelope applies. Unless you are doing granular synthesis, kr envelopes are usually preferred. --- james mccartney james@audiosynth.com http://www.audiosynth.com If you have a PowerMac check out SuperCollider2, a real time synth program: < ------------------------------ Date: Sat, 3 Jul 1999 19:45:27 -0600 From: James McCartney <---@---.---> Subject: Re: Streams within a stream Here's a modification using the effects function. This does a differnt thing than you were doing before, but I'm showing it as an example. This one has a single ongoing pattern process that is being processed by effext spawned from a pattern, as opposed to effects that spawn their own pattern processes to effect. I fooled around with the tonerow pattern.. ( var e, pat; var synthuF, efx; var tonerows; var t; e=Event.protoEvent; t = Wavetable.sineFill(512, 1.0/[1,2,3,4,5,6,7,8,9,10,11,12]); synthuF={ arg freq, amp, legato, env; COsc.ar(t, freq,1, EnvGen.kr(env, 1, 0, amp, 0, legato)) }; tonerows=Prand([ Pseq([ 8, 0, 4, 13, 4, 10, 5, 9 ], 4), Pseq([ 8, -2, 4, 13, 4, 10, 5, 7 ], 4), Pseq([ 8, 0, 5, 15, 4, 8, 4, 4 ], 4), Pseq([ 10, -1, 17, 8, -2, 6, 3, 6 ], 4), Pseq([ 9, 2, 19, 9, 0, 6, 3, 6 ], 4) ], inf); // efx efx = { arg outputs; var efxuF, onset; // since the delay line will be getting audio from an ongoing process, // it needs to fade up the amplitude to prevent a click. // this onset envelope is for that purpose. onset = Env([0, 1],[0.01]); // define a ugen func; efxuF={ arg subpattern, ffreq, rq, range, env; var sound; sound = RLPF.ar(outputs,ffreq,rq) * EnvGen.kr(onset); 2.do({ sound = AllpassN.ar(sound, range, [range.rand, range.rand], 1) }); EnvGen.ar(env) * sound; }; Pbind(\ugenFunc, efxuF, \dur,8, \range,Pbrown(0.05,0.25,0.05,inf), \ffreq,5000, \rq,0.5, \legato,1, \tempo,2, \env,Env.adsr(0.05,1,1,0.5,1) ).asSpawn(e, 2) }; pat = Pbind ( \ugenFunc,synthuF, \legato, Pbrown(0.25,0.9,0.1,inf), \dur,0.25, \note,Pstutter(2, tonerows), \octave,3, \db,-20, \tempo,2, \env, Env.adsr ); Synth.scope( pat.asUGenFunc( e, 1, nil, efx ), 0.5); ) --- james mccartney james@audiosynth.com http://www.audiosynth.com If you have a PowerMac check out SuperCollider2, a real time synth program: < ------------------------------ Date: Sun, 04 Jul 1999 06:04:13 -0400 From: "crucial" <---@---.---> Subject: Re: Songs within a song >>synthuF={ EnvGen.ar(Env.adsr, >> COsc2.ar(Wavetable.sineFill(512, 1.0/[1,2,3,4,5,6]), >> Wavetable.sineFill(512, 1.0/[6,5,4,3,2,1]), >> ~freq,1) > >a) The wavetables should not be built in the synth function. Definitely, that cleared the glitch from my example right away. I must admit, I put this example together in less than 5min. I usually supply the wavetables from a library object, but I am surprised the creation of wavetables causes such a peak usage. > >b) It is pointless to use COsc2 with two identical tables. >The idea for COsc2 is to use two tables with differing phases. >Otherwise use COsc. ah... so I only vary the amplitudes. ok, thanks. > > >>efxuF={arg spawn,synth,evnt; > >d) The function is not called with spawn, synth, etc arguments. >It is called with valueEnvir. Any arguments you provide will get >filled in from the current environment, i.e. Event. You used to pass spawn and innersynth into the spawn function, I changed my 2.15 to do that too. The only reason at this point is to access the spawn instance to .releaseAll which has to do with this problem I bring the example up about ! During the course of play, while this efx event is open, things may happen, culminate, get triggered etc. whereby I want to shut the efx event down and go onto a new efx event (eg. different filtered, reverbed space). So I was trying to call spawn.releaseAll to cut the spawn short (from what it was given at its start from event.delta ). >> EnvGen.ar(Env.adsr(0.05,1,1,0.5,1),sound); > >e) Don't build your envelope here. It is the same for every event, so >build into your event. e.g. Pbind(... \env, Env.adsr(0.05,1,1,0.5,1), >Then the envelope gets built once when the Pbind is created instead >of built anew for each event. Again I did this as a quick and G3 lazy example. Some times I am building the Env each time based on ~attack, ~release, ~decay that I like to tweak with . Usually I can just use the same 2 or 3 Envs and modulate them via the EnvGen. It isn't a horrible waste of cpu, but I realize now that my Envelope library object creates new instances more than it needs to. > >f) >This is much more efficient. > > sound * EnvGen.ar(env) > >The way you do it above causes two EnvGens to be created due to >multichannel expansion. >Using a kr envelope is even better. Really ? I was thinking that a * would involve a binop ugen in addition to the two ugens involved. by inserting the sound as the multiply, I thought I was saving a ugen ! > >i) > \note,Pstutter(1,Pseq(tonerows.choose,inf)), > >You do realize that this chooses only one tone row to be played >per interpreter session (i.e. from press enter to press cmd period). >That choose only executes once and that Pseq gets created with that row. Yes I did. Which brings me to the other question I was going to ask : Many times I have wanted to do something like this : tonerows=#[ [ 8, 0, 4, 13, 4, 10, 5, 9 ], [ 8, -2, 4, 13, 4, 10, 5, 7 ], [ 8, 0, 5, 15, 4, 8, 4, 4 ], [ 10, -1, 17, 8, -2, 6, 3, 6 ], [ 9, 2, 19, 9, 0, 6, 3, 6 ] ]; Pseq(Pstutter(16,Pfunc({tonerows.choose}),inf)) Hoping that Pfunc would return one of the rows, repeated 16 times (yes I'm keeping the examples simple) through Pstutter into Pseq. But Pseq is none too happy getting anything but a list. This will always crash sc ! total lock up. which of course james you wouldn't know because you wouldn't try and do something so daft ... :) ( var tonerows; tonerows=#[ [ 8, 0, 4, 13, 4, 10, 5, 9 ], [ 8, -2, 4, 13, 4, 10, 5, 7 ], [ 8, 0, 5, 15, 4, 8, 4, 4 ], [ 10, -1, 17, 8, -2, 6, 3, 6 ], [ 9, 2, 19, 9, 0, 6, 3, 6 ] ]; Pbind( \note,Pswitch1(tonerows,Pfunc({tonerows.size.rand})) ).play ) this produces chords. very sick ones Pbind( \note,Pfunc({Pseq(tonerows.choose,1)}), \tempo,4 ).play this passes a Pbinop ? INPUT: Instance of Pbinop { (026BD88C, gc=00, fmt=00, flg=00, set=02) instance variables [3] operator : Symbol '+' a : instance of Punop (026A5F74, size=0, set=01) b : Float 0 0 0 } Ä ERROR: input 1 to Osc is not a UGen, Float, or Integer. Ä ERROR: internal error: Synth ended already. Your example creates multiple patterns and switches between them (easily can also use Pswitch1 which I have done). I suppose this isn't too much overhead, a couple of small instances sitting around with some memory slots. I keep trying to figure out how to just hot swap lists in a Pseq-like class. how else might lists be hot swapped through a Pseq etc. ? >synthuF={ EnvGen.ar(Env.adsr, > COsc2.ar(Wavetable.sineFill(512, 1.0/[1,2,3,4,5,6]), > Wavetable.sineFill(512, 1.0/[6,5,4,3,2,1]), > ~freq,1) > ,0,~amp,0,~legato)}; >Not sure why you use legato to time scale the envelope? >The envelope sustain time is taken care of in the >asSpawn method: You know I added it in there one day and it just sounded snappier :) I guess the legato setting makes its mark twice, doesn't it. As per your modified example: This will work, but I still want to find a way to have the pattern be a part of the event stream tree of other patterns, but have its 'audio' more independent. It stays in sync to play it 'elsewhere' as asSpawn or ugenFunc, but it would be better compositionally for me if it were reacting with duration, state changes, streams and all that. > > --- james mccartney james@audiosynth.com http://www.audiosynth.com >If you have a PowerMac check out SuperCollider2, a real time synth program: > > > > > __________________________________________ :\\_______ http://crucial-systems.com __________________________________________ :\\_______ ------------------------------ End of sc-users-digest V1 #49 *****************************