From: owner-sc-users-digest@lists.io.com (sc-users-digest) To: sc-users-digest@lists.io.com Subject: sc-users-digest V1 #46 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, June 27 1999 Volume 01 : Number 046 ---------------------------------------------------------------------- Date: Wed, 23 Jun 1999 03:54:50 -0600 From: James McCartney <---@---.---> Subject: Re: Routine At 1:25 PM -0600 6/22/99, Mark Polishook wrote: >James, restating my question more clearly... > >> inval = 1.yield; >> >> When you call 1.yield the Routine suspends its execution >> at that point and returns 1. > >...but why is assignment here made to inval? - > >In other words, I'm not seeing why the example doesn't run as > >1.yield > >instead of the way it DOES run... > >inval = 1.yield OK I'll try again.. The call to yield returns 1 to the calling function. The calling function then passes a value back to the routine via the argument to 'next'. Sort of like alice through the looking glass, the argument becomes the result on the other side, in both directions. In other words the result of 'yield' inside the routine is the argument that was supplied to the call to 'next'. The result of the call to 'next' is the argument that was supplied to 'yield'. The assignment is there to catch the value that was just passed into the routine. --- james mccartney james@audiosynth.com http://www.audiosynth.com If you have a PowerMac check out SuperCollider2, a real time synth program: ------------------------------ Date: Wed, 23 Jun 1999 04:01:46 -0600 From: James McCartney <---@---.---> Subject: Re: FilterPatterns At 1:39 PM -0600 6/22/99, crucial wrote: >James- >In its simplest form : > >Pset( > \degree,3, > > Pbind(\tempo,9, > \degree,Pseq(Array.fill(12,{24.rand - 20}),inf)) > > ).play(Event.protoEvent,1) > > >I was thinking that filter patterns would 'write' into >the events being passed up. They write over the initial >definitions in the Event, but not over anything defined >by for instance a Pbind. No they write as they are passed *down* so that lower levels override upper levels. This allows you to refine events with more specific information. leaves inherit event data from their parents and may override any of it. > >Or am I going the wrong way down the chain ? > >The proto event is passed down the chain (pset to pbind) >as the objects are intialised. Then the event stream >emits from there back up ? > >I suppose this is why you use mtranspose etc. ? Events are passed up and down the chain. They are usually not modified on the way up. Time must not be modified on the way up or Ppar won't work. >Also, is it just me or is 2.15 kind of unstable ? I have had an occasional unexplained crash, but rarely. If you are able to reproduce something repeatedly, I'd like to see it. --- james mccartney james@audiosynth.com http://www.audiosynth.com If you have a PowerMac check out SuperCollider2, a real time synth program: ------------------------------ Date: Wed, 23 Jun 1999 09:45:40 -0600 From: James McCartney <---@---.---> Subject: Re: FilterPatterns At 4:01 AM -0600 6/23/99, James McCartney wrote: >Events are passed up and down the chain. Actually that should be: Events are passed down and then up the chain. --- james mccartney james@audiosynth.com http://www.audiosynth.com If you have a PowerMac check out SuperCollider2, a real time synth program: ------------------------------ Date: Wed, 23 Jun 1999 22:52:33 +0800 From: Mark Ballora <---@---.---> Subject: Re: Routine >>Could you clarify? May I give this a try? I also found this confusing, but I _think_ I worked it out. >When you call 1.yield the Routine suspends its execution >at that point and returns 1. I think the confusion lies in exactly where the Routine's execution is suspended and then resumed. It happens mid-line, at each assignment statement. What we have here is an egg toss between the principal body of code (would be the main() function in C) and the r Routine function. So the order of events would be: outval = what?? We don't know just yet. First we have to call the routine: r.next('a'); We call r with the 'next' method, passing the argument a. Within r, 'a' is assigned to inval. ("->inval was " ++ inval).postln; -- we print the value of inval, a. Moving right along: inval = ?? So we're re-assigning inval, are we? To what? We don't know just yet. First we send a 1 back to the main code, via: 1.yield; Back in the main code, now we have a value for outval, 1. ("<-outval was " ++ outval).postln; -- we print the value. Moving right along: outval = ?? So we're re-assigning outval, are we? To what? We don't know just yet. To get a new value, we call the routine: r.next('b'); We go back to r again. We left off re-assigning a value to inval. Well, now we have the new value: the argument to the next method, 'b'. ("->inval was " ++ inval).postln; -- we print the new value. inval = ?? So we're re-assigning inval, are we? To what? We don't know just yet. First we send a 2 back to the main code, via: 2.yield; Back in the main code, now we have a value for outval, 2. ("<-outval was " ++ outval).postln; -- we print the value. r.reset; "reset".postln; Now we reset r, and print the word out. Moving right along: outval = ?? So we're re-assigning this, are we? To what? We don't know just yet. First we have to call the routine: r.next('c'); Since we reset r, we start again within r from the beginning. We call r with the 'next' method, passing the argument 'c'. Within r, 'c' is assigned to inval. ("->inval was " ++ inval).postln; -- we print the value of inval, c. inval = ?? So we're re-assigning this, are we? To what? We don't know just yet. First we send a 1 back to the main code, via: 1.yield; . . . and so on, until we go through all the steps in r, and return nil. Have I got this right? ------------------------------ Date: Wed, 23 Jun 1999 10:03:57 -0600 From: James McCartney <---@---.---> Subject: Re: Routine At 8:52 AM -0600 6/23/99, Mark Ballora wrote: >Have I got this right? Yes! --- james mccartney james@audiosynth.com http://www.audiosynth.com If you have a PowerMac check out SuperCollider2, a real time synth program: ------------------------------ Date: Wed, 23 Jun 1999 23:46:55 +0100 From: joel ryan <---@---.---> Subject: backside cache A quick SC/hardware question For someone contemplating cost differences among new powerbook G3's Any advice on the question How much does it matter how big the backside cache is on a G3 cpu board for audio applications like superCollider? thanks Joel Ryan _____________________________________________ Joel Ryan Institute of Sonology :: Ballett Frankfurt STEIM [Stichting for Electro-Instrumental Music] Achtergracht 19, 1017 Amsterdam +31 (020) 624-3886 +31 (020) 626-4262 fax http://www.steim.nl http://www.frankfurt-ballett.de/joel.html _______________________ ------------------------------ Date: Wed, 23 Jun 1999 20:55:02 -0600 From: James McCartney <---@---.---> Subject: Re: backside cache At 4:46 PM -0600 6/23/99, joel ryan wrote: >A quick SC/hardware question >For someone contemplating cost differences among new powerbook G3's >Any advice on the question >How much does it matter how big the backside cache is on a G3 cpu board >for audio applications like superCollider? > >thanks >Joel Ryan I don't have any empirical data, but I'd say it could be a big help to have more cache especially when running large patches. It will allow more UGen output buffers to live in the cache at once. --- james mccartney james@audiosynth.com http://www.audiosynth.com If you have a PowerMac check out SuperCollider2, a real time synth program: ------------------------------ Date: Wed, 23 Jun 1999 21:59:07 -0400 From: "crucial" <---@---.---> Subject: Re: FilterPatterns // Prejects all degrees of 3 Pbind(\degree,Preject({arg inval; inval==3}, Pseq([3,6,3,4,3],inf)) ).play(Event.protoEvent,2) // But how can this be done on event streams ? Preject( {arg invalevent; invalevent.postln; invalevent.at('degree')==3 }, Pbind(\degree,Pseq([8,5,3,4,5],inf)) ).play(Event.protoEvent,2) // incorrect, wrong way round ! // still asking the question before the data is there... Pfunc({arg event; event.use({ if(~degree==3,{~rest=true}) }); event }, Pbind(\degree,Pseq([4,3,6,3,5],inf)) ).play(Event.protoEvent,2) // but how do I turn that around ? Can you give a corrected example of the above ? Or how can I affect the event stream on its way back up ? // a more practical example // here I try passing a function into the downward path... Pbindf( \rest,{"?".post; if (~degree==3,{true})}, \finish, { ~freq = ~freq.value + ~detune; ~amp = ~amp.value; ~sustain = ~sustain.value; ~rest= ~rest.value; }, Pbind(\degree,Pseq([4,3,6,3,5],inf)) ).play // ? degree 3 is still playing ? I am wanting to have dynamically switched patterns in place of the simple degree sequence above. And then apply switchable filters and functions to that event stream. Also.. Re: .finish Why not just make sure and .value everything used in Pattern.asSpawn or in the other .protoEvent functions ? Then you could get rid of .finish altogether. Or leave it as a convience for anybody inserting peice specific functions. This makes it easier to add in functions to the event definition (for ~rest, ~degree , ~mtranspose etc.) without having to rewrite finish. __________________________________________ :\\_______ http://crucial-systems.com __________________________________________ :\\_______ ------------------------------ Date: Wed, 23 Jun 1999 21:38:45 -0600 From: James McCartney <---@---.---> Subject: Re: FilterPatterns At 7:59 PM -0600 6/23/99, crucial wrote: OK last things first.. >Also.. > >Re: .finish >Why not just make sure and .value everything used in >Pattern.asSpawn or in the other .protoEvent functions ? >Then you could get rid of .finish altogether. Or leave it as a >convience for anybody inserting peice specific functions. The old way did not have a finish method and did a .value on everything. The problem is that then operations can wind up being redundant and sometimes the order of operations is important. So it is better to have the event do final calculations in a well defined way at a well defined time. >This makes it easier to add in functions to the event definition >(for ~rest, ~degree , ~mtranspose etc.) >without having to rewrite finish. It is intended that you will modify the protoEvent for your particular event model. --- james mccartney james@audiosynth.com http://www.audiosynth.com If you have a PowerMac check out SuperCollider2, a real time synth program: ------------------------------ Date: Wed, 23 Jun 1999 22:36:24 -0600 From: James McCartney <---@---.---> Subject: Re: FilterPatterns At 7:59 PM -0600 6/23/99, crucial wrote: >// Prejects all degrees of 3 >Pbind(\degree,Preject({arg inval; inval==3}, > Pseq([3,6,3,4,3],inf)) > > ).play(Event.protoEvent,2) > > >// But how can this be done on event streams ? >Preject( {arg invalevent; > invalevent.postln; > invalevent.at('degree')==3 > > }, > > Pbind(\degree,Pseq([8,5,3,4,5],inf)) > > ).play(Event.protoEvent,2) > There is a bug in Stream. Replace these methods in Stream.sc : // combination collect { arg argCollectFunc; // modify a stream var nextFunc, resetFunc; nextFunc = { arg inval; inval = this.next(inval); if ( inval.notNil, { argCollectFunc.value(inval) },{ nil }) }; resetFunc = { this.reset }; ^FuncStream.new(nextFunc, resetFunc); } reject { arg function; // reject elements from a stream var nextFunc, resetFunc; nextFunc = { arg inval; inval = this.next(inval); while ({ inval.notNil and: { function.value(inval) } },{ inval = this.next(inval); }); inval }; resetFunc = { this.reset }; ^FuncStream.new(nextFunc, resetFunc); } select { arg function; // select elements from a stream var nextFunc, resetFunc; nextFunc = { arg inval; inval = this.next(inval); while ({ inval.notNil and: { function.value(inval).not } },{ inval = this.next(inval); }); inval }; resetFunc = { this.reset }; ^FuncStream.new(nextFunc, resetFunc); } >// incorrect, wrong way round ! >// still asking the question before the data is there... >Pfunc({arg event; > event.use({ > if(~degree==3,{~rest=true}) > }); > event > }, > Pbind(\degree,Pseq([4,3,6,3,5],inf)) > > ).play(Event.protoEvent,2) > >// but how do I turn that around ? Pfunc is not a FilterPattern, it does not modify a pattern. It is simply a Pattern wrapper for a FuncStream. > > > >// a more practical example >// here I try passing a function into the downward path... >Pbindf( > \rest,{"?".post; if (~degree==3,{true})}, Actually ~rest is never used. In order to get a rest, change the pitch (~freq, ~note, ~degree, etc) to a Symbol. Once the fixes are put in, you can write: Pbind(\degree, Pseq([8,5,3,4,5],inf)).reject({ arg inevent; inevent.at(\degree) == 3 }).play(Event.protoEvent, 2) Pbind(\degree, Pseq([8,5,3,4,5],inf)).collect({ arg inevent; if (inevent.at(\degree) == 3, { inevent.put(\degree, \rest); }); inevent }).play(Event.protoEvent, 2) --- james mccartney james@audiosynth.com http://www.audiosynth.com If you have a PowerMac check out SuperCollider2, a real time synth program: < ------------------------------ Date: Thu, 24 Jun 1999 11:06:41 +0200 From: "Iannis Zannos" <---@---.---> Subject: Simple pop-up widget (Re: bug . . . or mug) >From: andreas pieper <---@---.---> >Subject: Re: bug . . . or mug >Date: Mon, 14 Jun 1999 9:52 PM > >hi, > >I just wandered: Are there any additional gui widgets planned? I am missing >some sort of pop-up menu: in the case of many dynamically generated >user-choices radio groups are sub-ideal because they do need too much >screen space. > Maybe this helps: ItemSelectorPane : GUIWindow { var items, returnFunc; *new { arg itemNames, returnFunc; ^super.new("Select Item", Rect.newBy(200, 200, 206, (itemNames.size * 20) + 6)) .init(itemNames, returnFunc); } init { arg inItemNames, inReturnFunc; items = Array.new(inItemNames.size); returnFunc = inReturnFunc; items = inItemNames.collect( { arg item, i; ButtonView.new( this, Rect.newBy(3, 3+(i*20), 197, 18), item).backColor_(Color.white) .action_({ arg me; this.buttonSelectItem(me) }) }); } buttonSelectItem { arg anItem; returnFunc.value(anItem.label); this.close; } } /* Tests: (ItemSelectorPane.new( #['Class', 'Number', 'String', 'List', 'Array', 'UGen', 'Pattern', 'Instrument'], { arg s; s.asSymbol.asClass.class.postln; } )) (w = GUIWindow.new('Pop-Up!'); b = ButtonView.new(w, Rect.newBy(5, 5, 390, 20), "Select a Class"); b.action_( { arg me; ItemSelectorPane.new( #['Class', 'Number', 'String', 'List', 'Array', 'UGen', 'Pattern', 'Instrument'], { arg s; me.label = "Select a Class. (Current:)" + s } )}); ) */ IZ. ------------------------------ Date: Thu, 24 Jun 1999 12:01:29 +0200 From: andreas pieper <---@---.---> Subject: Re: Simple pop-up widget hi, yep, this helps (although this would be a case where a modal window could be justified :-). thank you! a ps i think the test routine has a little typo: .. 'Instrument'], { arg s; me.label = "Select a Class. (Current:)" + s } should be "++ s" at the end, otherwise this would cause an error on my system. - --On Don, 24. Jun 1999 11:06 Uhr +0200 Iannis Zannos wrote: > >> From: andreas pieper <---@---.---> >> Subject: Re: bug . . . or mug >> Date: Mon, 14 Jun 1999 9:52 PM >> > >> hi, >> >> I just wandered: Are there any additional gui widgets planned? I am >> missing some sort of pop-up menu: in the case of many dynamically >> generated user-choices radio groups are sub-ideal because they do need >> too much screen space. >> > > Maybe this helps: > > > ItemSelectorPane : GUIWindow { > var items, returnFunc; > *new { arg itemNames, returnFunc; > ^super.new("Select Item", > Rect.newBy(200, 200, 206, (itemNames.size * 20) + 6)) > .init(itemNames, returnFunc); > } > > init { arg inItemNames, inReturnFunc; > items = Array.new(inItemNames.size); > returnFunc = inReturnFunc; > > items = inItemNames.collect( { arg item, i; > ButtonView.new( > this, > Rect.newBy(3, 3+(i*20), 197, 18), > item).backColor_(Color.white) > .action_({ arg me; this.buttonSelectItem(me) }) > }); > > } > buttonSelectItem { arg anItem; > returnFunc.value(anItem.label); > this.close; > } > > } > > /* Tests: > > (ItemSelectorPane.new( > #['Class', 'Number', 'String', 'List', 'Array', 'UGen', 'Pattern', > 'Instrument'], { arg s; s.asSymbol.asClass.class.postln; } > )) > > > (w = GUIWindow.new('Pop-Up!'); > b = ButtonView.new(w, Rect.newBy(5, 5, 390, 20), "Select a Class"); > b.action_( { arg me; > ItemSelectorPane.new( > #['Class', 'Number', 'String', 'List', 'Array', 'UGen', 'Pattern', > 'Instrument'], { arg s; me.label = "Select a Class. (Current:)" + s } > )}); > ) > > */ > > IZ. andreas pieper mego@url.de PGP fingerprint A7B1 721D 65E6 1A2D BA28 4112 28B2 C3B8 ------------------------------ Date: Thu, 24 Jun 1999 13:07:40 +0200 From: "Iannis Zannos" <---@---.---> Subject: Simple pop-up widget - generalized (Re: bug . . . or mug) >>From: andreas pieper <---@---.---> >>Subject: Re: bug . . . or mug >>Date: Mon, 14 Jun 1999 9:52 PM >> > >>hi, >> >>I just wandered: Are there any additional gui widgets planned? I am missing >>some sort of pop-up menu: in the case of many dynamically generated >>user-choices radio groups are sub-ideal because they do need too much >>screen space. // This is a somewhat generalized and refined version of // ItemSelectorPane as just posted. // Folds items on multiple columns to accomodate long lists, // Can store and return any kind of object and display any name // for it (using nameFunc as parameter for setting the name. // See third test example below for nameFunc. SelectorPane : GUIWindow { var items, returnFunc; *new { arg itemNames, returnFunc, nameFunc, label = "Select an item:"; ^super.new(label, this.calculateRect(itemNames.size)) .init(itemNames, returnFunc, nameFunc); } *calculateRect { arg numItems; ^Rect.newBy(100, 100, 6 + (150 * (numItems / 45).ceil), 906.min((numItems * 20) + 6) ) } init { arg inItemNames, inReturnFunc, nameFunc; var color; color = this.backColor; returnFunc = inReturnFunc; items = inItemNames.collect( { arg item, i; this.makeButton(item, nameFunc, i, color) }); } makeButton { arg item, nameFunc, i, color; ^ButtonView.new( this, Rect.newBy(3+(150*(i/45).floor), 3+((i%45)*20), 147, 18), this.getItemName(item, nameFunc, i)).backColor_(color) .action_(this.getItemAction(item, i)) } getItemName { arg anItem, nameFunc, i; if ( nameFunc.isNil, { ^anItem.asString; }, { ^nameFunc.value(anItem, i).asString }) } getItemAction { arg anItem, i; ^{ arg me; returnFunc.value(anItem, me, i); me.window.close }; } backColor { ^Color.white } } /* Tests: (SelectorPane.new( #['Class', 'Number', 'String', 'List', 'Array', 'UGen', 'Pattern', 'Instrument'], { arg s; s.postln; } ) ) (w = GUIWindow.new('Pop-Up!'); b = ButtonView.new(w, Rect.newBy(5, 5, 390, 20), "Select a Class"); b.action_( { arg me; SelectorPane.new( [Class, Number, String, List, Array, UGen, Pattern, Instrument], { arg c, button; button.label.post; ", superclass: ".post; c.superclass.postln; "Instance Variables: ".post; c.instVarNames.postln; b.label_("Select a Class. (Current:)" + c.asString) } )}); ) (SelectorPane.new( Class.allClasses .reject({ arg c; c.name.asString.copyRange(0, 4).asSymbol == 'Meta_' }), { arg c, button; button.label.post; ", superclass: ".post; c.superclass.postln; "Instance Variables: ".post; c.instVarNames.postln; b.label_("Select a Class. (Current:)" + c.asString) } ) ) (SelectorPane.new( Class.allClasses .reject({ arg c; c.name.asString.copyRange(0, 4).asSymbol == 'Meta_' }), { arg c, button; button.label.post; ", superclass: ".post; c.superclass.postln; "Instance Variables: ".post; c.instVarNames.postln; b.label_("Select a Class. (Current:)" + c.asString) }, { arg item, i; (i + 1).asString + item.asString } ) ) */ > >>From: andreas pieper <---@---.---> >>Subject: Re: bug . . . or mug >>Date: Mon, 14 Jun 1999 9:52 PM >> > >>hi, >> >>I just wandered: Are there any additional gui widgets planned? I am missing >>some sort of pop-up menu: in the case of many dynamically generated >>user-choices radio groups are sub-ideal because they do need too much >>screen space. >> > >Maybe this helps: > > >ItemSelectorPane : GUIWindow { > var items, returnFunc; > *new { arg itemNames, returnFunc; > ^super.new("Select Item", > Rect.newBy(200, 200, 206, (itemNames.size * 20) + 6)) > .init(itemNames, returnFunc); > } > > init { arg inItemNames, inReturnFunc; > items = Array.new(inItemNames.size); > returnFunc = inReturnFunc; > > items = inItemNames.collect( { arg item, i; > ButtonView.new( > this, > Rect.newBy(3, 3+(i*20), 197, 18), > item).backColor_(Color.white) > .action_({ arg me; this.buttonSelectItem(me) }) > }); > > } > buttonSelectItem { arg anItem; > returnFunc.value(anItem.label); > this.close; > } > >} > >/* Tests: > >(ItemSelectorPane.new( > #['Class', 'Number', 'String', 'List', 'Array', 'UGen', 'Pattern', 'Instrument'], > { arg s; s.asSymbol.asClass.class.postln; } >)) > > >(w = GUIWindow.new('Pop-Up!'); >b = ButtonView.new(w, Rect.newBy(5, 5, 390, 20), "Select a Class"); >b.action_( { arg me; > ItemSelectorPane.new( > #['Class', 'Number', 'String', 'List', 'Array', 'UGen', 'Pattern', 'Instrument'], > { arg s; me.label = "Select a Class. (Current:)" + s } > )}); >) > >*/ > >IZ. ------------------------------ Date: Thu, 24 Jun 1999 07:20:39 -0600 From: James McCartney <---@---.---> Subject: [fwd] SC greenhorn This is a multi-part message in MIME format. - --------------9F635AE427C849D418BE9BEA Content-Type: text/plain; charset=us-ascii; x-mac-type="54455854"; x-mac-creator="4D4F5353" Content-Transfer-Encoding: 7bit hi, I'm new at this list and need some help: I need a bandpassfilter applying to incoming audio data going thru SuperCollider. It should be possible to move the centerfrequenzy of the filter by score (not slider, the moves should be predefined) - and, if possible the bandwidth. So the only parameters defined in the score should be duration of bpf, centerfrequenzy and bandwidth. Is there any help ? thanks a lot regards guenther zechberger - -- Guenther Zechberger - composer "http://www.tribunal.net/ticom/Zechi/GZ_index.html" e-mail: guenther.zechberger@aon.at adress: Galgenfeldstr. 25, A-6060 Hall i. Tirol, Austria fon & fax: +43 5223 44943 - --------------9F635AE427C849D418BE9BEA Content-Type: text/x-vcard; charset=us-ascii; name="guenther.zechberger.vcf" Content-Description: Card for Zechberger Guenther Content-Disposition: attachment; filename="guenther.zechberger.vcf" Content-Transfer-Encoding: 7bit begin:vcard adr;dom:;;Galgenfeldstr. 25;Hall i. Tirol;Austria;A-6020; n:Zechberger;G¸nther x-mozilla-html:FALSE org:ticom version:2.1 email;internet:Guenther.Zechberger@uibk.ac.at tel;fax:+43 5223 44943 tel;home:+43 5223 44943 tel;work:+43 5223 44943 note:http://www.tribunal.net/ticom/Zechi/index.html x-mozilla-cpt:;0 fn:G¸nther Zechberger end:vcard - --------------9F635AE427C849D418BE9BEA-- ------------------------------ Date: Thu, 24 Jun 1999 07:50:45 -0600 From: James McCartney <---@---.---> Subject: Re: [fwd] SC greenhorn At 7:20 AM -0600 6/24/99, James McCartney wrote: >This is a multi-part message in MIME format. >--------------9F635AE427C849D418BE9BEA >Content-Type: text/plain; charset=us-ascii; x-mac-type="54455854"; x-mac-creator="4D4F5353" >Content-Transfer-Encoding: 7bit > >hi, I'm new at this list and need some help: > > >I need a bandpassfilter applying to incoming audio data going thru >SuperCollider. It should >be possible to move the centerfrequenzy of the filter by score (not >slider, the moves should be >predefined) - and, if possible the bandwidth. So the only parameters >defined in the score >should be duration of bpf, centerfrequenzy and bandwidth. >Is there any help ? > >thanks a lot >regards >guenther zechberger This should be simple to do with OrcScore. ( var e; e = Env.asr(0.1, 0.4, 0.4); Synth.play({ OrcScore.ar( // the orchestra [ { arg spawn, i, synth, deltaTime, instrumentNum, freq, rq, dur; // rq is the ratio: bandwidth/freq synth.releaseTime = dur; BPF.ar(AudioIn.ar([1,2]), freq, rq, EnvGen.kr(e)); } ], // the score #[ // deltaTime, instrumentNum, freq, rq, dur... [0, 0, 1000, 0.1, 4], [2, 0, 1200, 0.1, 4], [2, 0, 1400, 0.1, 4], [2, 0, 700, 0.1, 4], [2, 0, 1600, 0.1, 4], [2, -1] // rest before restarting ], 2, // two channels nil, // nil nextTime 4) // repeat 4 times })) // here is a test using WhiteNoise instead of AudioIn. ( var e; e = Env.asr(0.1, 0.4, 0.4); Synth.play({ OrcScore.ar( // the orchestra [ { arg spawn, i, synth, deltaTime, instrumentNum, freq, rq, dur; synth.releaseTime = dur; BPF.ar(WhiteNoise.ar([0.5,0.5]), freq, rq, EnvGen.kr(e)); } ], // the score #[ // deltaTime, instrumentNum, freq, rq, dur... [0, 0, 1000, 0.1, 4], [2, 0, 1200, 0.1, 4], [2, 0, 1400, 0.1, 4], [2, 0, 700, 0.1, 4], [2, 0, 1600, 0.1, 4], [2, -1] // rest ], 2, nil, 4) })) --- james mccartney james@audiosynth.com http://www.audiosynth.com If you have a PowerMac check out SuperCollider2, a real time synth program: < ------------------------------ Date: Thu, 24 Jun 1999 20:58:10 +0100 From: Arie van Schutterhoef <---@---.---> Subject: Re: [OT] SC & stratifier S T R A T I F I E R a multi-dimensional controller for the performance of live electro-acoustic music http://www.xs4all.nl/~schreck/eng/html/strat.html The "stratifier" is new multi-dimensional (sixteen continuous outputs) musical instrument which enables the user to control many aspects of the signal processing and synthesizing capabillities of the computer in realtime, making it a genuime performance tool for concerts. Momentarilly it works alongside STEIM's SensorLab, outputting the necessary control-information to a Power Macintosh running James McCartney's realtime synthesis and processing environment SuperCollider. It was created by Arie van Schutterhoef and built in collaboration with the hard- & software designer Pieter Suurmond and the sculptor/ instrument builder Hans van Koolwijk. Support was given by Het Fonds voor de Podiumkunsten, as part of their grant for the realisation of "The Day", an event which consists of an integrated performance with sound sculptures, live electronics and musicians. <<<<<<<<<<<<<<<<<<<<<<<<<-////||\\\\->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Arie van Schutterhoef artistic director Schreck Ensemble # -laboratory for live electro-acoustic music- # The Netherlands e-mail:arsche@stad.dsl.nl http://www.xs4all.nl/~schreck/ Tel: 00-31-71-5612287 Fax: 00-31-70-3859268 <<<<<<<<<<<<<<<<<<<<<<<<<-////||\\\\->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ------------------------------ Date: Thu, 24 Jun 1999 17:23:02 -0600 From: James McCartney <---@---.---> Subject: Re: Extensions (fixes) to Instrument.edit GUI making. - --============_-1281855910==_============ Content-Type: text/plain; charset="us-ascii" At 12:47 AM -0600 6/22/99, Iannis Zannos wrote: >Following code extensions / fixes make MixerPlayer, >MixerView and Instrument work to permit the editing of instruments. >Code is attached as ascii and as stuffed file. > >Test example: > >( >Instrument(\test, > { arg synth, freq, amp; > FSinOsc.ar(freq, amp) }).play; >) Actually Instruments now do not take synth as an argument. This is so that Instruments can be used like UGens (they respond to .ar). The current Synth can be got from Synth.newSynth if needed. Here is a corrected version of my version MixerPlayer.sc and a fix to Main.sc to remove the synth argument from 'test tone'. The Mixer now remembers settings between edit windows, and copies parameter values when copying. Add your extensions to this one. - --============_-1281855910==_============ Content-Type: text/plain; name="MixerPlayer.sc"; charset="us-ascii" Content-Disposition: attachment; filename="MixerPlayer.sc" Instrument { var <>func, <>name; *new { arg name, func; ^super.new.func_(func).name_(name) } *play { arg name, func, volume = 0.2; this.new(name, func).play(volume); } play { arg volume = 0.2; MixerPlayer.play(MixerVoice.new(this), volume); } // act like a UGen ar { arg ... inputs; ^func.valueArray(inputs); } // Library support *libPut { arg names, func; var instr; instr = this.new(names.last, func); Library.put(names, instr); ^instr } libMenuAction { arg names; this.play; } // OrcScore support spawn { arg spawn, eventCount, synth, inputs; ^{ arg synth, deltaTime, instrumentNum ... inputs; // strip off deltaTime and instrumentNum func.valueArray(inputs) }.valueArray(synth, inputs); } } MixerPlayer { classvar tspawn, <>mixer, inputs, <>numChannels = 2, <>numInputs = 12, env; classvar recBtn, recFile, recID=0; *reset { // in case of an error you may need to reset the MixerPlayer tspawn = nil; mixer = nil; inputs = nil; env = nil; recBtn = nil; recFile = nil; } *play { arg voice, volume = 0.2; var input; this.makeMixer; input = this.findFreeInput; if (input.isNil, {^this}); this.initInput(input, voice, voice.instrument.name, volume); if (tspawn.isNil, { this.prepareRecord; Synth.play(this.playFunc(input)); this.synthDone; },{ tspawn.trigger(input); }); } // PRIVATE *initInput { arg input, voice, name, volume; input.voice = voice; input.name = name.asString; input.nameView.label = input.name; if (voice.canMakeEditWindow, { input.editBtn.label = "Edit"; }); input.volumeSlider.value = volume; input.killBox.value = 1; input.killBox.action = { if (input.killBox.value == 0, { if ( tspawn.notNil and: { input.synth.notNil }, { input.synth.release; }); input.voice.close; input.voice = nil; input.name = nil; input.synth = nil; input.volumeSlider.value = 0.0005; input.killBox.action = nil; input.copyBtn.action = nil; input.editBtn.action = nil; input.nameView.label = "-"; input.editBtn.label = "_"; }); }; input.copyBtn.action = { this.play(input.voice.copy, input.volumeSlider.value); }; input.editBtn.action = { input.voice.makeEditWindow; }; } *playFunc { arg input; ^{ arg synth; var outs; outs = TSpawn.ar({ arg argTSpawn, i, tsynth, argInput; argInput.synth = tsynth; Pause.ar({ argInput.voice.play(synth); }, argInput.volumeSlider.kr - 0.001) * EnvGen.kr(env); }, numChannels); tspawn = outs.source; synth.sched(0, { tspawn.trigger(input) }); if (recFile.notNil, { // record to disk Pause.ar({ DiskOut.ar(recFile, 32768, outs); }, recBtn.kr); }); outs } } *synthDone { if (recFile.notNil, { recFile.endRecord; recID = recID + 1; }); recBtn.value = 0; tspawn = nil; inputs.do({ arg anInput; anInput.killBox.value_(0).doAction; }); } *makeMixer { if (mixer.notNil, { //mixer.toFront; ^mixer }); // make cutoff envelope env = Env.new(#[1,1,0],[1,0.01],'linear',1); mixer = GUIWindow.new("Mixer", Rect.newBy( 80, 80, 550, 80 + (24 * numInputs)) ); recBtn = CheckBoxView.new( mixer, Rect.newBy( 10, 4, 100, 20 ), "Record", 0, 0, 1, 0, 'linear'); inputs = Array.new(numInputs); numInputs.do({ arg i; var vol, box, copybtn, editbtn, str, top; top = 24 * i + 30; vol = SliderView.new( mixer, Rect.newBy( 10, top, 128, 20 ), "SliderView", 0.0, 0.0005, 1, 0, 'exponential'); box = CheckBoxView.new( mixer, Rect.newBy( 142, top, 20, 20 ), "", 0, 0, 1, 0, 'linear'); copybtn = ButtonView.new( mixer, Rect.newBy( 168, top, 40, 20 ), "Copy", 0, 0, 1, 0, 'linear'); editbtn = ButtonView.new( mixer, Rect.newBy( 212, top, 40, 20 ), "_", 0, 0, 1, 0, 'linear'); str = StringView.new( mixer, Rect.newBy( 264, top, 128, 20 ), "-"); inputs.add( MixerInputSpec.new(i, nil, nil, nil, vol, box, copybtn, editbtn, str) ); }); mixer.onClose = { inputs.do({ arg anInput; anInput.killBox.value_(0).doAction; }); mixer = nil; }; ^mixer; } *findFreeInput { ^inputs.detect({ arg anInput; anInput.voice.isNil }); } *prepareRecord { var filename; if (thisProcess.isDemo.not, { // make record file recFile = SoundFile.new; recFile.numChannels = numChannels; recFile.headerFormat = 'AIFF'; recFile.sampleFormat = '16 big endian signed'; filename = ":Sounds:MixerOut_" ++ (recID%10); if (recFile.writeHeader(filename), { recFile.prepareRecord; },{ ("write record file header failed : " ++ filename).postln; recFile = nil; }); }); } } MixerVoice { var <>instrument, <>editWindow, <>plugs, <>params; *new { arg instrument; ^super.new.instrument_(instrument); } init { } copy { var copy; copy = this.class.new(instrument) ; copy.params = Array.fill(plugs.size, { arg i; plugs.at(i).source.value; }); copy.params.postln; ^copy } canMakeEditWindow { ^instrument.func.def.argNames.size >= 1 } makeEditWindow { var def, defargs, defvals; if (editWindow.notNil, { ^editWindow }); if (plugs.isNil, { ^nil }); def = instrument.func.def; defargs = def.argNames; defvals = def.prototypeFrame; if (defargs.size < 1, { ^nil }); editWindow = GUIWindow.new(instrument.name.asString, Rect.newBy( 80, 80, 550, 60 + (24 * defargs.size)) ); editWindow.onClose = { editWindow = nil; }; defargs.do({ arg argName, i; var spec, top, val, numer, slider, plug; top = 24 * i + 30; StringView.new( editWindow, Rect.newBy( 10, top, 100, 20 ), argName ); spec = ParamSpec.specs.at(argName); plug = plugs.at(i); if (spec.notNil, { //val = defvals.at(i) ? 0.0; val = plug.source.value; slider = SliderView.new( editWindow, Rect.newBy( 114, top, 128, 20 ), nil, val, spec.minval, spec.maxval, spec.step, spec.warp ); numer = NumericalView.new( editWindow, Rect.newBy( 246, top, 60, 20 ), nil, val, spec.minval, spec.maxval, spec.step, spec.warp ); slider.action = { numer.value = slider.value }; numer.action = { slider.value = numer.value }; },{ numer = NumericalView.new( editWindow, Rect.newBy( 114, top, 60, 20 ), nil, defvals.at(i) ? 0.0, -1e10, 1e10 ); }); plugs.at(i).source = numer; }); } close { if (editWindow.notNil, { editWindow.close; }); } play { arg synth; var def, size; def = instrument.func.def; size = def.argNames.size; plugs = Array.new(size); if (params.notNil, { size.do({ arg i; plugs.add(Plug.kr(params.at(i))); }); },{ size.do({ arg i; plugs.add(Plug.kr(def.prototypeFrame.at(i))); }); }); ^instrument.func.valueArray(plugs) } } MixerInputSpec { var <>index, <>voice, <>name, <>synth, <>volumeSlider, <>killBox, <>copyBtn, <>editBtn, <>nameView; *new { arg index, voice, name, synth, volumeSlider, killBox, copyBtn, editBtn, nameView; ^super.new.init(index, voice, name, synth, volumeSlider, killBox, copyBtn, editBtn, nameView) } init { arg argIndex, argMixerVoice, argName, argSynth, argVolumeSlider, argKillBox, argCopyBtn, argEditBtn, argNameView; index = argIndex; voice = argMixerVoice; name = argName; synth = argSynth; volumeSlider = argVolumeSlider; killBox = argKillBox; copyBtn = argCopyBtn; editBtn = argEditBtn; nameView = argNameView; } } ParamSpec { classvar <>specs; var <>minval, <>maxval, <>step, <>warp; *new { arg minval=0.0, maxval=1.0, step=0.0, warp='linear'; ^super.new.minval_(minval).maxval_(maxval).step_(step).warp_(warp) } *default { specs = Environment.new; // set up some default param specs // you can add your own after the fact. specs.use({ ~freq = ParamSpec(20,20000,0,\exponential); ~ffreq = ParamSpec(20,20000,0,\exponential); // filter freq ~rq = ParamSpec(0.001,5,0,\exponential); ~amp = ParamSpec(0.0001, 1.0, 0.0, \exponential); ~pan = ParamSpec(-1, 1); ~velocity = ParamSpec(0, 127); ~detune = ParamSpec(-20,20); ~beats = ParamSpec(0,20); ~rate = ParamSpec(0.125, 8 ,0, \exponential); // sample playback rate ~vibRate = ParamSpec(0, 20); // vibrato LFO ~vibDepth = ParamSpec(0, 1); ~tremRate = ParamSpec(0, 20); // tremolo LFO ~tremDepth = ParamSpec(0, 1); ~panRate = ParamSpec(0, 20); ~panDepth = ParamSpec(0, 1); ~delay = ParamSpec(0.0001, 1, 0, \exponential); }); } } - --============_-1281855910==_============ Content-Type: text/plain; name="Main.sc"; charset="us-ascii" Content-Disposition: attachment; filename="Main.sc" Main : Process { startUp { false.trace; currentEnvironment = Environment.new; this.initLib; ParamSpec.default; } hardwareSetup { false.trace; if (Synth.hardwareName == 'Korg', { // I want the analog ports mapped to channels 1 & 2 Synth.setOutputRouting([1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 1, 2]); Synth.setInputRouting([9, 10, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]); },{ Synth.normalRouting; }); } initLib { var s, r; Library.put(['Wavetables','Define new...'], { GetStringDialog.new("Wavetable Name :", "new wave", { arg ok, string; var w; if (ok, { Library.put( ['Wavetables', string.asSymbol], w = Wavetable.sineFill(1024, [1]) ); w.plot(string); }); }); }); Library.bar(['Wavetables']); Library.put(['Wavetables','sine'], Wavetable.sineFill(1024, [1])); Library.put(['Wavetables','triang9'], Wavetable.sineFill(1024, [1,0,1/9,0,1/25,0,1/49,0,1/81], [0,0,pi,0,0,0,pi,0,0]) ); Library.put(['Wavetables','square9'], Wavetable.sineFill(1024, [1,0,1/3,0,1/5,0,1/7,0,1/9])); Library.put(['Wavetables','saw8'], Wavetable.sineFill(1024, 1/[1,2,3,4,5,6,7,8])); Library.put(['Sounds', 'Open...'], { GetFileDialog.new({ arg ok, path; var s; if (ok, { s = SoundFile.new; if ( s.readHeader(path), { Library.put(['Sounds', path.asSymbol], s); }); }); }); }); Library.bar(['Sounds']); s = SoundFile.new; if ( s.readHeader(":Sounds:floating_1"), { Library.put(['Sounds', 'floating_1'], s); }); Instrument.libPut(['Play', 'pink noise'], { PinkNoise.ar(0.5) }); Instrument.libPut(['Play', 'test tone'], { arg freq=1000; SinOsc.ar(freq, 0, 0.5) } ); Library.bar(['Play']); Library.put(['Play', 'disk file...'], { GetFileDialog.new({ arg ok, pathName; var res, sf; if (ok, { sf = SoundFile.new; if (sf.readHeader(pathName), { Instrument.play(pathName, { DiskIn.ar(sf, false, 0, 32768) }, 1.0); }); }); }); }); Library.put(['Play', 'analog daze'], { this.demo2 }); Library.put(['Play', 'native algorithms'], { this.demo3 }); r = [ [{ // hell is busy Pan2.ar( SinOsc.ar(400 + 2000.0.rand, 0, LFPulse.kr(1 + 10.0.rand, 0.7.rand, 0.04)), 1.0.rand2) }, 'busy signal'], [{ // pond life Pan2.ar( SinOsc.ar(SinOsc.kr(20+30.rand, 0, 100+300.rand, 500 + 2000.0.linrand), 0, LFPulse.kr(3/(1 + 8.0.rand), 0.2+0.3.rand, 0.04)), 1.0.rand2) }, 'frog'], [{ // rocks on rails var n=20; Pan2.ar( Klank.ar( // n resonant modes `[ // filter bank specification array: Array.fill(n, { 200 + 3000.0.linrand }), // resonant frequencies nil, // amplitudes default to 1.0 Array.fill(n, { 0.2 + 1.0.rand }) // ring times ], Resonz.ar( Dust.ar(100, 0.04), // excitation XLine.kr(3000,300,8), // sweep filter down 0.2 // band width ratio ) ), Line.kr(1.0.rand2, 1.0.rand2, 8) // sweep pan ) }, 'rocks on rails'], [{ // clustered sines var n=30, f1, f2, y, z; f1 = 100 + 1000.0.rand; f2 = 4.0 * f1; z = Array.fill(2, { `[ // sine oscil bank specification : y = Array.fill(n, { f1 + f2.rand} ), // frequencies f1 / y, // amplitudes nil // phases default to zero ] }); Klang.ar(z, 1, 0, 0.3/n); }, 'clustered sines'], [{ // Klank - bank of resonators excited by impulses var m = 15, z; z = `[ // filter bank specification : Array.fill(m, { 80 + 10000.0.linrand} ), // frequencies Array.fill(m, { 1.0.rand2 }), // amplitudes Array.fill(m, { 0.2 + 8.0.rand } ) // ring times ]; Pan2.ar(Klank.ar(z, Dust.ar(0.9, 0.01), 1, 0, 1, 8), 1.0.rand2); }, 'Klank 1'], [{ // Klank - excited by noise bursts var m = 8, z, s; s = Decay.ar(Dust.ar(0.6, 0.0004), 3.1, WhiteNoise.ar); z = Array.fill(2, { `[ Array.fill(m, { 80 + 10000.0.linrand} ), Array.fill(m, { 1.0.rand2 }), // amplitudes Array.fill(m, { 0.2 + 4.0.rand } ) ] }); Klank.ar(z, s, 1, 0, 1, 8) }, 'Klank 2'], [{ // pulsing bottle Pan2.ar( Resonz.ar( WhiteNoise.ar( LFPulse.kr(4 + 10.0.rand, 0.7.rand, 0.2) ), 400 + 7000.0.linrand, 0.01 ), SinOsc.kr(0.1 + 0.4.rand, 2pi.rand) ) }, 'pulsing bottle'], [{ // police state Pan2.ar( SinOsc.ar( SinOsc.kr(0.1.rand + 0.02, 2pi.rand, 600.rand, 1000 + 300.rand2), 0, LFNoise2.ar(100 + 20.0.rand2, 0.1) ), 1.0.rand2 ) }, 'siren'], [{ // uplink var freq; freq = LFPulse.kr(20.0.rand, 1.0.rand, LFPulse.kr(4.0.rand, 1.0.rand, 8000.rand, 2000.rand)); freq = freq + LFPulse.kr(20.0.rand, 1.0.rand, LFPulse.kr(4.0.rand, 1.0.rand, 8000.rand, 2000.rand)); Pan2.ar( LFPulse.ar(freq, 0.5, 0.02), 0.8.rand2) }, 'uplink'], [{ // data space var freq, dtime; freq = LFPulse.kr(200.0.rand, 1.0.rand, LFPulse.kr(40.0.rand, 1.0.rand, 8000.rand, 2000.rand)); freq = freq + LFPulse.kr(20.0.rand, 1.0.rand, LFPulse.kr(4.0.rand, 1.0.rand, 8000.rand, 2000.rand)); freq = freq + LFPulse.kr(20.0.rand, 1.0.rand, LFPulse.kr(4.0.rand, 1.0.rand, 8000.rand, 2000.rand)); dtime = 0.25.rand + 0.1; CombL.ar(Pan2.ar( LFPulse.ar(freq, 0.5, 0.02), LFNoise0.kr(3.0.rand, 0.8)), dtime, dtime, 3) }, 'data space'], [{ // narrow band filtered crackle noise var rf,rf2; rf = 2000.0.rand + 80; rf2 = rf + (0.2.rand2 * rf); Pan2.ar( Resonz.ar(Crackle.ar(1.97 + 0.03.rand,0.05), XLine.kr(rf,rf2,9), 0.8), 1.0.rand2 ) }, 'crackle'], [{ // string reson var n=12, s, y, f1, f2; s = BrownNoise.ar(0.0005); // a list representing a just diatonic scale expressed as ratios. // one value is chosen at random and multiplied by a 120 Hz fundamental f1 = #[ 1.0, 1.125, 1.25, 1.333, 1.5, 1.667, 1.875, 2.0, 2.25, 2.5, 2.667, 3.0, 3.333, 3.75, 4.0 ].choose * 120.0; y = Array.fill(2, { `[ Array.series(n, f1, f1 ) + Array.fill(n, { 0.5.rand2 }), nil, Array.fill(n, { 0.5 + 4.0.rand } ) ] }); Klank.ar(y, s) }, 'string reson'], [{ // pipe reson var n=12, s, y, f1, f2; s = LFNoise2.ar(8000, 0.0004); // a list representing a just diatonic scale expressed as ratios. // one value is chosen at random and multiplied by a 120 Hz fundamental f1 = #[ 1.0, 1.125, 1.25, 1.333, 1.5, 1.667, 1.875, 2.0, 2.25, 2.5, 2.667, 3.0, 3.333, 3.75, 4.0 ].choose * 120.0; y = Array.fill(2, { `[ Array.series(n, f1, 2*f1 ) + Array.fill(n, { 0.5.rand2 }), nil, Array.fill(n, { 0.2 + 0.8.rand } ) ] }); Klank.ar(y, s) }, 'pipe reson'] ]; r.do({ arg item; var func, name; #func, name = item; Instrument.libPut(['Play', name], func); }); } run { // this method is called when you choose 'Run' from the Lang menu. // this is a demo. You can put whatever you like in the run method. "Running method Main::run.\n".post; "This is a demo - you can put any code here.\n".post; this.demo1; } demo1 { var r, z, y, j; // put lots of the other examples in an array of functions and choose them at // random for each event. // there are no samples here, this is all synthesized. r = [ { // hell is busy Pan2.ar( SinOsc.ar(400 + 2000.0.rand, 0, LFPulse.kr(1 + 10.0.rand, 0.7.rand, 0.04)), 1.0.rand2) }, { // pond life Pan2.ar( SinOsc.ar(SinOsc.kr(20+30.rand, 0, 100+300.rand, 500 + 2000.0.linrand), 0, LFPulse.kr(3/(1 + 8.0.rand), 0.2+0.3.rand, 0.04)), 1.0.rand2) }, { // rocks on rails var n=20; Pan2.ar( Klank.ar( // n resonant modes `[ // filter bank specification array: Array.fill(n, { 200 + 3000.0.linrand }), // resonant frequencies nil, // amplitudes default to 1.0 Array.fill(n, { 0.2 + 1.0.rand }) // ring times ], Resonz.ar( Dust.ar(100, 0.04), // excitation XLine.kr(3000,300,8), // sweep filter down 0.2 // band width ratio ) ), Line.kr(1.0.rand2, 1.0.rand2, 8) // sweep pan ) }, { // clustered sines var n=30, f1, f2; f1 = 100 + 1000.0.rand; f2 = 4.0 * f1; z = Array.fill(2, { `[ // sine oscil bank specification : y = Array.fill(n, { f1 + f2.rand} ), // frequencies f1 / y, // amplitudes nil // phases default to zero ] }); Klang.ar(z, 1, 0, 0.3/n); }, { // Klank - bank of resonators excited by impulses var m = 15, z; z = `[ // filter bank specification : Array.fill(m, { 80 + 10000.0.linrand} ), // frequencies Array.fill(m, { 1.0.rand2 }), // amplitudes Array.fill(m, { 0.2 + 8.0.rand } ) // ring times ]; Pan2.ar(Klank.ar(z, Dust.ar(0.9, 0.01), 1, 0, 1, 8), 1.0.rand2); }, { // Klank - excited by noise bursts var m = 8, z, s; s = Decay.ar(Dust.ar(0.6, 0.0004), 3.1, WhiteNoise.ar); z = Array.fill(2, { `[ Array.fill(m, { 80 + 10000.0.linrand} ), Array.fill(m, { 1.0.rand2 }), // amplitudes Array.fill(m, { 0.2 + 4.0.rand } ) ] }); Klank.ar(z, s, 1, 0, 1, 8) }, { // pulsing bottle Pan2.ar( Resonz.ar( WhiteNoise.ar( LFPulse.kr(4 + 10.0.rand, 0.7.rand, 0.2) ), 400 + 7000.0.linrand, 0.01 ), SinOsc.kr(0.1 + 0.4.rand, 2pi.rand) ) }, { // police state Pan2.ar( SinOsc.ar( SinOsc.kr(0.1.rand + 0.02, 2pi.rand, 600.rand, 1000 + 300.rand2), 0, LFNoise2.ar(100 + 20.0.rand2, 0.1) ), 1.0.rand2 ) }, { // uplink var freq; freq = LFPulse.kr(20.0.rand, 1.0.rand, LFPulse.kr(4.0.rand, 1.0.rand, 8000.rand, 2000.rand)); freq = freq + LFPulse.kr(20.0.rand, 1.0.rand, LFPulse.kr(4.0.rand, 1.0.rand, 8000.rand, 2000.rand)); Pan2.ar( LFPulse.ar(freq, 0.5, 0.02), 0.8.rand2) }, { // data space var freq, dtime; freq = LFPulse.kr(200.0.rand, 1.0.rand, LFPulse.kr(40.0.rand, 1.0.rand, 8000.rand, 2000.rand)); freq = freq + LFPulse.kr(20.0.rand, 1.0.rand, LFPulse.kr(4.0.rand, 1.0.rand, 8000.rand, 2000.rand)); freq = freq + LFPulse.kr(20.0.rand, 1.0.rand, LFPulse.kr(4.0.rand, 1.0.rand, 8000.rand, 2000.rand)); dtime = 0.25.rand + 0.1; CombL.ar(Pan2.ar( LFPulse.ar(freq, 0.5, 0.02), LFNoise0.kr(3.0.rand, 0.8)), dtime, dtime, 3) }, { // narrow band filtered crackle noise var rf,rf2; rf = 2000.0.rand + 80; rf2 = rf + (0.2.rand2 * rf); Pan2.ar( Resonz.ar(Crackle.ar(1.97 + 0.03.rand,0.05), XLine.kr(rf,rf2,9), 0.8), 1.0.rand2 ) }, { // string reson var n=12, s, y, f1, f2; s = BrownNoise.ar(0.0005); // a list representing a just diatonic scale expressed as ratios. // one value is chosen at random and multiplied by a 120 Hz fundamental f1 = #[ 1.0, 1.125, 1.25, 1.333, 1.5, 1.667, 1.875, 2.0, 2.25, 2.5, 2.667, 3.0, 3.333, 3.75, 4.0 ].choose * 120.0; y = Array.fill(2, { `[ Array.series(n, f1, f1 ) + Array.fill(n, { 0.5.rand2 }), nil, Array.fill(n, { 0.5 + 4.0.rand } ) ] }); Klank.ar(y, s) }, { // pipe reson var n=12, s, y, f1, f2; s = LFNoise2.ar(8000, 0.0004); // a list representing a just diatonic scale expressed as ratios. // one value is chosen at random and multiplied by a 120 Hz fundamental f1 = #[ 1.0, 1.125, 1.25, 1.333, 1.5, 1.667, 1.875, 2.0, 2.25, 2.5, 2.667, 3.0, 3.333, 3.75, 4.0 ].choose * 120.0; y = Array.fill(2, { `[ Array.series(n, f1, 2*f1 ) + Array.fill(n, { 0.5.rand2 }), nil, Array.fill(n, { 0.2 + 0.8.rand } ) ] }); Klank.ar(y, s) }, { Pan2.ar( // resonant filter bank simulates resonant modes of bouncing objects Klank.ar( `[ Array.fill(4, { 400 + 8000.0.rand }), // resonant freqs Array.fill(4, { 1.0.rand }), // amplitudes Array.fill(4, { 0.01 + 0.1.rand }) // ring times ], // decays excite filter bank Decay.ar( // each impulse triggers a decay Impulse.ar( // impulses trigger decay envelope XLine.kr(5 + 2.0.rand2, 600, 4), // accellerating frequency XLine.kr(0.4, 0.00004, 4) // decaying impulse amplitude ), 0.001 // decay time - very short ) ), 1.0.rand2 // place each bouncer at a random position in the stereo field ) } ]; j = r.size.rand * 4; Instrument.play('soup', { OverlapTexture.ar({ arg sp, i; r.wrapAt((i + j) div: 4).value }, 3.75, 0.25, 4, 2) }, 1.0) } demo2 { var pattern, f; pattern = #[55,63,60,63,57,65,62,65]; f = { arg octave, clockRate, pwmrate, fltrate; RLPF.ar( LFPulse.ar( Lag.kr( Sequencer.kr( `((pattern + (12 * octave)).midicps), // sequencer pattern Impulse.kr(clockRate) // sequencer trigger ), 0.05 // Lag time coefficient ), SinOsc.kr(pwmrate, 2pi.rand, 0.4, 0.5), // pulse width modulator 0.1 // pulse amplitude ), SinOsc.kr(fltrate, 2pi.rand, 1400, 2000), // cutoff freq LFO 1/15 ) }; Instrument.play('analog daze', { var x, g, z, e; x = Decay.ar(Impulse.ar(2), 0.15, LFNoise0.ar(LFNoise1.kr(0.3,6000,8000), [0.07,0.07])); g = [f.value(1,8,0.31,0.2), f.value(0,2,0.13,0.11)] + x; z = 0.4 * (CombN.ar(g, 0.375, 0.375, 5) + g.reverse); e = Env.linen(2, 56, 2); // one minute trapezoid envelope z * EnvGen.kr(e) }); } demo3 { // native algorhythms var n, pat, texture; n = 8; // n = number of partials for percussion instruments // create an algorhythmic rhythm pattern pat = Prand([ // choose one of the following patterns at random Pseq(#[2.0, 0.0, 2.0, 0.0, 1.0, 0.0, 1.0, 1.0]), Pseq(#[2.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0]), Pseq(#[2.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0]), Pseq(#[2.0, 0.3, 0.3, 1.0, 0.3, 0.3, 1.0, 0.3]), Pseq(#[2.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0]), Pseq(#[2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]), Pseq(#[0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0]), Pseq(#[1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0]) ],inf ); Instrument.play('native algorhythms', { OverlapTexture.ar({ // make an overlapping texture var freq, seq, excitation, resonator; freq = 40 + 300.0.rand; // random base frequency seq = ImpulseSequencer.ar( // outputs a sequence of single sample triggers pat.asStream, // create a stream to iterate over pattern Impulse.ar(10) // a clock for the sequencer at 10 beats per second ); excitation = Decay.ar( // a decaying envelope for the noise seq, // impulse sequence triggers decay envelopes 0.1, // 60 dB decay time PinkNoise.ar(0.007) // noise is the exciter ); resonator = Klank.ar( // use Klank as a percussion resonator `[ // filter bank specification array: Array.fill(n, { freq + (4.0*freq).linrand }), // resonant frequencies nil, // amplitudes default to 1.0 Array.fill(n, { 0.2 + 3.0.linrand }) // ring times ], excitation ); Pan2.ar(resonator, 1.0.rand2) // random pan position // return the Pan2 }, 8, 4, 4, 2); // sustainTime, fadeTime, overlapDensity, number of channels }); } } - --============_-1281855910==_============ Content-Type: text/plain; charset="us-ascii" --- james mccartney james@audiosynth.com http://www.audiosynth.com If you have a PowerMac check out SuperCollider2, a real time synth program: - --============_-1281855910==_============-- ------------------------------ End of sc-users-digest V1 #46 *****************************