|
View:
New views
1 Messages
—
Rating Filter:
Alert me
|
|
|
SF.net SVN: supercollider: [7526] trunk/build
by cruxxial
::
Rate this Message:
Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message Revision: 7526
http://svn.sourceforge.net/supercollider/?rev=7526&view=rev Author: cruxxial Date: 2008-04-19 17:20:05 -0700 (Sat, 19 Apr 2008) Log Message: ----------- big fix: Object was returning rate of \scalar when it should be \noncontrol fixing Patch/InstrSynthDef/PatchOut for this For a SynthDef \scalar means .ir rate input \noncontrol means it will not be in the SynthDef I think and hope this change shouldn't affect anybody. Its mostly related to InstrSynthDef and the PatchOut system. but: generic Objects that aren't controls or players are now rate \noncontrol, not \scalar adding BusSpec adding BusPool, a more secure way to manage Busses that are used by multiple clients. SharedBus is no longer used. moving all Bus allocations into the PatchOut object so that the whole thing can be freed and its always a clean sweep. players' Groups and Synths will move in there too. it should reduce paperwork annotate no longer used for Busses. BusPool.gui is better now .horz and .vert now use GUI.skin.gap so this MAY affect your guis. possibly they will look better, or you may need to adjust GUI.skin.gap to suit color of CXLabel changed from Ye Olde Yellow Paper to White but actually Somewhat Bluish added: Tempo.beats2secsKr GUI debugger added to tools. ServerLog handles large traffic sizes better now. still no scrolling Modified Paths: -------------- trunk/build/Help/Libraries/crucial/Gui/ActionButton.html trunk/build/Help/Libraries/crucial/Gui/PageLayout.html trunk/build/Help/Libraries/crucial/Players/EnvelopedPlayer.html trunk/build/SCClassLibrary/crucial/Crucial.sc trunk/build/SCClassLibrary/crucial/Editors/NumberEditor.sc trunk/build/SCClassLibrary/crucial/Gui/ActionButton.sc trunk/build/SCClassLibrary/crucial/Gui/CXLabel.sc trunk/build/SCClassLibrary/crucial/Gui/PageLayout.sc trunk/build/SCClassLibrary/crucial/Instr/InstrSpawner.sc trunk/build/SCClassLibrary/crucial/Instr/InstrSynthDef.sc trunk/build/SCClassLibrary/crucial/Instr/Interface.sc trunk/build/SCClassLibrary/crucial/Instr/MoreSpecs.sc trunk/build/SCClassLibrary/crucial/Instr/Patch.sc trunk/build/SCClassLibrary/crucial/Instr/instrSupport.sc trunk/build/SCClassLibrary/crucial/Players/AbstractPlayer.sc trunk/build/SCClassLibrary/crucial/Players/AbstractPlayerGui.sc trunk/build/SCClassLibrary/crucial/Players/Patching.sc trunk/build/SCClassLibrary/crucial/Players/PlayerEfxFunc.sc trunk/build/SCClassLibrary/crucial/Players/PlayerMixer.sc trunk/build/SCClassLibrary/crucial/Players/PlayerPool.sc trunk/build/SCClassLibrary/crucial/Players/PlayerSocket.sc trunk/build/SCClassLibrary/crucial/Players/Silence.sc trunk/build/SCClassLibrary/crucial/Players/SimplePlayerEffect.sc trunk/build/SCClassLibrary/crucial/Sample/Sample.sc trunk/build/SCClassLibrary/crucial/Scheduling/Tempo.sc trunk/build/SCClassLibrary/crucial/Scheduling/TempoBus.sc trunk/build/SCClassLibrary/crucial/ServerTools/ServerGui.sc trunk/build/SCClassLibrary/crucial/ServerTools/ServerLog.sc trunk/build/SCClassLibrary/crucial/ServerTools/ServerLogGui.sc trunk/build/SCClassLibrary/crucial/ServerTools/synthDef.sc Added Paths: ----------- trunk/build/SCClassLibrary/crucial/ServerTools/BusPool.sc Modified: trunk/build/Help/Libraries/crucial/Gui/ActionButton.html =================================================================== --- trunk/build/Help/Libraries/crucial/Gui/ActionButton.html 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/Help/Libraries/crucial/Gui/ActionButton.html 2008-04-20 00:20:05 UTC (rev 7526) @@ -5,18 +5,18 @@ <meta http-equiv="Content-Style-Type" content="text/css"> <title></title> <meta name="Generator" content="Cocoa HTML Writer"> -<meta name="CocoaVersion" content="824.42"> +<meta name="CocoaVersion" content="824.47"> <style type="text/css"> p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Helvetica} p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px} p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica} p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco} -p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #0019b7} +p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #001fb3} p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #606060} p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; min-height: 12.0px} span.s1 {color: #000000} span.s2 {color: #606060} -span.s3 {color: #0019b7} +span.s3 {color: #001fb3} span.Apple-tab-span {white-space:pre} </style> </head> @@ -38,7 +38,7 @@ <p class="p7"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p> <p class="p4">)</p> <p class="p7"><br></p> -<p class="p4">(<span class="Apple-tab-span"> </span></p> +<p class="p4">(</p> <p class="p4">// <span class="Apple-converted-space"> </span>bigger title... bigger button</p> <p class="p6"><span class="s1"><span class="Apple-tab-span"> </span></span><span class="s3">ActionButton</span><span class="s1">(</span><span class="s3">nil</span><span class="s1">,</span>"hit me hit me hit me hit me hit me hit me hit me hit me hit me hit me hit me "<span class="s1">,{<span class="Apple-converted-space"> </span></span></p> <p class="p6"><span class="s1"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>"yeah baby"<span class="s1">.postln<span class="Apple-converted-space"> </span></span></p> Modified: trunk/build/Help/Libraries/crucial/Gui/PageLayout.html =================================================================== --- trunk/build/Help/Libraries/crucial/Gui/PageLayout.html 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/Help/Libraries/crucial/Gui/PageLayout.html 2008-04-20 00:20:05 UTC (rev 7526) @@ -14,21 +14,25 @@ p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px} p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco} p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; min-height: 12.0px} -p.p8 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #98281a} -span.s1 {color: #0023b2} +p.p8 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #87311d} +span.s1 {color: #0727ae} span.s2 {color: #606060} -span.s3 {color: #000000} -span.s4 {color: #0000bf} -span.s5 {color: #3e691d} -span.s6 {color: #98281a} +span.s3 {color: #0013bb} +span.s4 {color: #000000} +span.s5 {color: #496722} +span.s6 {color: #87311d} span.Apple-tab-span {white-space:pre} </style> </head> <body> <p class="p1"><b>PageLayout</b></p> <p class="p2"><br></p> +<p class="p3">Deprecated.</p> +<p class="p2"><br></p> <p class="p3">A PageLayout is a window that manages the layout of views added to it.</p> <p class="p2"><br></p> +<p class="p3">Historically this class precedes the FlowLayout decorator.<span class="Apple-converted-space"> </span>MultiPageLayout became the more standardly used class.<span class="Apple-converted-space"> </span>It is essentially a window with a scroll view and a FlowLayout installed as decorator.<span class="Apple-converted-space"> </span>It does not actually create multiple pages, whereas PageLayout DOES.<span class="Apple-converted-space"> </span>Some clean up work needs to be done.</p> +<p class="p2"><br></p> <p class="p4">You request a rectangle using <b>layout.layRight(x,y)</b></p> <p class="p5"><br></p> <p class="p4">the layout manager moves its internal cursor, wrapping to a new line, then to a new window as necessary.</p> @@ -39,7 +43,7 @@ <p class="p6"><span class="Apple-tab-span"> </span>f=<span class="s1">PageLayout</span>.new(<span class="s2">"flow"</span>);</p> <p class="p7"><span class="Apple-tab-span"> </span></p> <p class="p6"><span class="Apple-tab-span"> </span>504.do({ <span class="s1">arg</span> i;</p> -<p class="p6"><span class="s3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span><span class="s4">GUI</span><span class="s3">.button.new</span>( f.window, f.layRight(30,30) )</p> +<p class="p6"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">GUI</span>.button.new( f.window, f.layRight(30,30) )</p> <p class="p6"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>.states_([[i.asString,<span class="s1">Color</span>.black,<span class="s1">Color</span>.white]])</p> <p class="p6"><span class="Apple-tab-span"> </span>});</p> <p class="p7"><span class="Apple-tab-span"> </span></p> @@ -55,9 +59,9 @@ <p class="p7"><span class="Apple-tab-span"> </span></p> <p class="p6"><span class="Apple-tab-span"> </span>800.do({ <span class="s1">arg</span> i;</p> <p class="p6"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s1">var</span> r;</p> -<p class="p8"><span class="s3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>r= f.layRight(30,30); </span>// obtain the rectangle first</p> -<p class="p8"><span class="s3"><span class="Apple-tab-span"> </span></span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>// in case we cascade to the next window</p> -<p class="p6"><span class="s3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span><span class="s4">GUI</span><span class="s3">.button.new</span>( f.window, r )</p> +<p class="p8"><span class="s4"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>r= f.layRight(30,30); </span>// obtain the rectangle first</p> +<p class="p8"><span class="s4"><span class="Apple-tab-span"> </span></span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>// in case we cascade to the next window</p> +<p class="p6"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">GUI</span>.button.new( f.window, r )</p> <p class="p6"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>.states_([[i.asString,Color.black,Color.white]])</p> <p class="p6"><span class="Apple-tab-span"> </span>});</p> <p class="p6"><span class="Apple-tab-span"> </span>f.front;</p> @@ -91,14 +95,14 @@ <p class="p6"><span class="Apple-tab-span"> </span>f= <span class="s1">PageLayout</span>.new("a vaguely practical example");</p> <p class="p7"><span class="Apple-tab-span"> </span></p> <p class="p6"><span class="Apple-tab-span"> </span>sliders=<span class="s1">Array</span>.fill(rrand(16,32),{ <span class="s1">arg</span> i;</p> -<p class="p6"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s4">GUI</span><span class="s3">.slider.new</span>( f.window, f.layRight(10, 150));</p> +<p class="p6"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">GUI</span>.slider.new( f.window, f.layRight(10, 150));</p> <p class="p6"><span class="Apple-tab-span"> </span>});</p> <p class="p7"><br></p> <p class="p6"><span class="Apple-tab-span"> </span>f.within( 50,150,{ <span class="s1">arg</span> subf;</p> -<p class="p6"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s4">GUI</span>.slider.new( subf.window, subf.layDown( 30,30));</p> -<p class="p6"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s4">GUI</span>.slider.new( subf.window, subf.layDown( 30,30));</p> -<p class="p6"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s4">GUI</span>.slider.new( subf.window, subf.layDown( 30,30));</p> -<p class="p6"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s4">GUI</span>.slider.new( subf.window, subf.layDown( 30,30));</p> +<p class="p6"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">GUI</span>.slider.new( subf.window, subf.layDown( 30,30));</p> +<p class="p6"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">GUI</span>.slider.new( subf.window, subf.layDown( 30,30));</p> +<p class="p6"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">GUI</span>.slider.new( subf.window, subf.layDown( 30,30));</p> +<p class="p6"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">GUI</span>.slider.new( subf.window, subf.layDown( 30,30));</p> <p class="p6"><span class="Apple-tab-span"> </span>});</p> <p class="p7"><span class="Apple-tab-span"> </span></p> <p class="p6"><span class="Apple-tab-span"> </span>f.resizeToFit;</p> @@ -151,7 +155,7 @@ <p class="p4"><span class="Apple-tab-span"> </span>You can register to receive that notification:</p> <p class="p7"><span class="Apple-tab-span"> </span></p> <p class="p6"><span class="Apple-tab-span"> </span><span class="s1">NotificationCenter</span>.registerOneShot( f,<span class="s5">\didClose</span>, yourObject,{</p> -<p class="p8"><span class="s3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// stop the model from playing, clean house,<span class="Apple-converted-space"> </span></p> +<p class="p8"><span class="s4"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// stop the model from playing, clean house,<span class="Apple-converted-space"> </span></p> <p class="p8"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>// unregister a keydown etc.</p> <p class="p6"><span class="Apple-tab-span"> </span>});</p> <p class="p5"><span class="Apple-tab-span"> </span></p> Modified: trunk/build/Help/Libraries/crucial/Players/EnvelopedPlayer.html =================================================================== --- trunk/build/Help/Libraries/crucial/Players/EnvelopedPlayer.html 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/Help/Libraries/crucial/Players/EnvelopedPlayer.html 2008-04-20 00:20:05 UTC (rev 7526) @@ -5,15 +5,15 @@ <meta http-equiv="Content-Style-Type" content="text/css"> <title></title> <meta name="Generator" content="Cocoa HTML Writer"> -<meta name="CocoaVersion" content="824.42"> +<meta name="CocoaVersion" content="824.47"> <style type="text/css"> p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Helvetica} p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; min-height: 12.0px} p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco} -p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #0019b7} -p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #a71e12} +p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #001fb3} +p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #942b17} span.s1 {color: #000000} -span.s2 {color: #0019b7} +span.s2 {color: #001fb3} span.Apple-tab-span {white-space:pre} </style> </head> @@ -53,6 +53,7 @@ <p class="p2"><br></p> <p class="p3">p.status</p> <p class="p2"><br></p> +<p class="p3">p.free</p> <p class="p2"><br></p> <p class="p3">p.insp</p> <p class="p2"><br></p> Modified: trunk/build/SCClassLibrary/crucial/Crucial.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/Crucial.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/Crucial.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -214,6 +214,10 @@ ActionButton(menu.startRow,"Listen to Buses",{ Library.at(\menuItems,\tools,'listen to audio busses').value; },minWidth: 250); + ActionButton(menu.startRow,"Gui debugger",{ + Library.at(\menuItems,\tools,\guiDebugger).value; + },minWidth: 250); + ActionButton(menu.startRow,"Annotated Nodes",{ Library.at(\menuItems,\tools,'Annotated Nodes Report').value; },minWidth: 250); @@ -266,7 +270,7 @@ Sheet({ |layout| CXLabel( layout, "Audio Busses",width:685); s.audioBusAllocator.blocks.do({ |b| - var listen; + var listen,bus; listen = Patch({ In.ar( b.start, b.size ) }); layout.startRow; ToggleButton( layout,"listen",{ @@ -276,9 +280,22 @@ }); CXLabel( layout, b.start.asString + "(" ++ b.size.asString ++ ")" ,100 ); - CXLabel( layout, - Library.at(AbstractPlayer, \busAnnotations, s,\audio, b.start) - ,540 ); + + bus = BusPool.findBus(s,b.start); + if(bus.notNil,{ + layout.flow({ |f| + var ann; + ann = BusPool.getAnnotations(bus); + + if(ann.notNil,{ + ann.keysValuesDo({ |client,name| + f.startRow; + Tile(client,f); + CXLabel(f,":"++name); + }); + }); + }) + }); }) },"Audio Busses"); }); @@ -303,7 +320,62 @@ }); }) }); - + Library.put(\menuItems,\tools,\guiDebugger,{ + var g; + CXMenu.newWith( + GUI.window.allWindows.collect({ |w| + w.name -> { + Sheet({ |f| + f.flow({ |f| + g.value(w.view,f) + }).reflowDeep.resizeToFit; + },"GUI: " + w.name) + .resizeToFit + } + }) + ).gui; + + g = { arg view,f,indent=0; + f.startRow; + GUI.staticText.new(f,10@17).background_(Color.clear); + f.flow({ |f| + var oldColor,x; + if(view.respondsTo(\background) and: {view.isKindOf(StartRow).not},{ + if(view.isKindOf(SCViewHolder),{ + oldColor = view.background; + },{ + oldColor = view.background; + }); + ToggleButton(f,view.asString,{ + // various views wont be that noticeable + // some highlight/focus is needed + view.background = Color.cyan; + if(view.canFocus ? false,{view.focus}); + },{ + view.background = oldColor ? Color.clear; + }); + InspectorLink.icon(view,f); + },{ + InspectorLink(view,f); + }); + x = view.bounds.asString.gui(f); + if(view.respondsTo(\parent) + and: {view.parent.notNil} + and: {view.parent.respondsTo('absoluteBounds')} + and: {view.parent.absoluteBounds.containsRect(view.absoluteBounds).not},{ + x.background_(Color.red); + "View exceeds parent bounds !".gui(f); + (view.asString + "bounds exceeds parent !").warn; + }); + if(view.respondsTo(\children),{ + view.children.do({ |kiddy| + g.value(kiddy,f,25); + }); + }); + },Rect(indent,0,f.bounds.width,f.bounds.height)) + .background_(Color.cyan(0.1,alpha: 0.08)) + }; + }); /*Library.put(\menuItems,\post,'post color...',{ GetColorDialog("Color",Color.white,{ arg ok,color; if(ok,{ color.post;}) @@ -328,37 +400,37 @@ UnicodeResponder.tester; }); - Library.put(\menuItems,\introspection,'find class...',{ - GetStringDialog("Classname or partial string","",{ - arg ok,string; - var matches,f,classes; - matches = IdentitySet.new; - if(ok,{ - classes = Class.allClasses.reject({ arg cl; cl.class === Class }); - classes.do({ arg cl; - if(cl.name.asString.containsi(string),{ - matches = matches.add(cl); - }); - }); +// Library.put(\menuItems,\introspection,'find class...',{ +// GetStringDialog("Classname or partial string","",{ +// arg ok,string; +// var matches,f,classes; +// matches = IdentitySet.new; +// if(ok,{ +// classes = Class.allClasses.reject({ arg cl; cl.class === Class }); +// classes.do({ arg cl; +// if(cl.name.asString.containsi(string),{ +// matches = matches.add(cl); +// }); +// }); +// +// Sheet({ arg f; +// matches.do({ arg cl; +// ClassNameLabel(cl,f.startRow,200); +// ActionButton(f,"source",{ +// cl.openCodeFile; +// },60); +// ActionButton(f,"help",{ +// cl.openHelpFile; +// },60); +// }); +// if(matches.isEmpty,{ +// CXLabel(f,"No matches found"); +// }); +// },"matches" + string); +// }) +// }); +// }); - Sheet({ arg f; - matches.do({ arg cl; - ClassNameLabel(cl,f.startRow,200); - ActionButton(f,"source",{ - cl.openCodeFile; - },60); - ActionButton(f,"help",{ - cl.openHelpFile; - },60); - }); - if(matches.isEmpty,{ - CXLabel(f,"No matches found"); - }); - },"matches" + string); - }) - }); - }); - Library.put(\menuItems,\introspection,\classfinder,{ GetStringDialog("Search classes...","",{ arg ok,string; Sheet({ |layout| @@ -367,7 +439,8 @@ if(class.isMetaClass.not and: {class.name.asString.find(string,true).notNil},{ matches = matches.add(class,true); layout.startRow; - ClassNameLabel(class,layout,300); + //ClassNameLabel(class,layout,300); + ActionButton(layout,class.name.asString,{ class.openCodeFile; },300); }); }); if(matches.isNil,{ Modified: trunk/build/SCClassLibrary/crucial/Editors/NumberEditor.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/Editors/NumberEditor.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/Editors/NumberEditor.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -18,6 +18,11 @@ makePatchOut { patchOut = ScalarPatchOut(this) } + stopToBundle { arg b; this.freePatchOutToBundle(b); } + freePatchOutToBundle { arg bundle; + bundle.addFunction({ patchOut.free; patchOut = nil; }) + } + synthArg { ^this.poll } instrArgFromControl { arg control; ^control @@ -119,23 +124,24 @@ connectToPatchIn { arg patchIn,needsValueSetNow = true; patchOut.connectTo(patchIn,needsValueSetNow); } - stopToBundle { arg b; b.addFunction({ patchOut.free; patchOut = nil; }); } - freePatchOut { arg bundle; - bundle.addFunction({ patchOut.free; patchOut = nil; }) - } + guiClass { ^KrNumberEditorGui } } IrNumberEditor : NumberEditor { - rate { ^\control } // irate icontrol ? + rate { ^\scalar } // was \control but this is correct now addToSynthDef { arg synthDef,name; synthDef.addIr(name,this.synthArg); } instrArgFromControl { arg control; ^control } + makePatchOut { + patchOut = ScalarPatchOut(this); + } + connectToPatchIn { } // nothing doing. we are ir only } Modified: trunk/build/SCClassLibrary/crucial/Gui/ActionButton.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/Gui/ActionButton.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/Gui/ActionButton.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -317,14 +317,19 @@ // abstract SCButtonAdapter : SCViewHolder { + classvar <>buttonClass; + *initClass { + Class.initClassTree(GUI); + buttonClass = GUI.button; + } makeView { arg layout,x,y; var rect; if((layout.isNil or: { layout.isKindOf(MultiPageLayout) }),{ layout = layout.asFlowView; }); - this.view = GUI.button.new(layout,Rect(0,0,x,y ? GUI.skin.buttonHeight)); + this.view = buttonClass.new(layout,Rect(0,0,x,y ? GUI.skin.buttonHeight)); if(consumeKeyDowns,{ this.view.keyDownAction_({nil}) }); } flowMakeView { arg layout,x,y; - this.view = GUI.button.new(layout.asFlowView,Rect(0,0,x,y ? GUI.skin.buttonHeight)); + this.view = buttonClass.new(layout.asFlowView,Rect(0,0,x,y ? GUI.skin.buttonHeight)); if(consumeKeyDowns,{ this.view.keyDownAction_({nil}); }); } @@ -347,17 +352,16 @@ s = view.states; s.at(0).put(2,color); view.states = s; + view.refresh; } labelColor_ { arg color; var s; s = view.states; s.at(0).put(1,color); view.states = s; + view.refresh; } - - // bw compat *defaultHeight { ^GUI.skin.buttonHeight } - } // abreviation for a one state button @@ -411,7 +415,7 @@ [title,GUI.skin.fontColor,GUI.skin.onColor] ]; state=init; - view.setProperty(\value,state.binaryValue); + view.value_(state.binaryValue); view.action_({this.prSetState(state.not)}); view.font = font; } Modified: trunk/build/SCClassLibrary/crucial/Gui/CXLabel.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/Gui/CXLabel.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/Gui/CXLabel.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -24,12 +24,13 @@ } CXLabel : CXAbstractLabel { + classvar <>bgcolor; *new { arg layout,string,width,height,minWidth=15,font; var new; new = super.new(layout,string,width,height,minWidth,font); - new.background_(Color.new255(255,255,240)) + new.background_(Color(0.9843137254902, 0.9843137254902, 0.9843137254902, 1.0)) .align_(\left); ^new } Modified: trunk/build/SCClassLibrary/crucial/Gui/PageLayout.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/Gui/PageLayout.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/Gui/PageLayout.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -119,9 +119,7 @@ var b,wb,wbw,wbh; if(this.view.isNil,{ this.insp }); b = this.view.resizeToFit(reflow); - //if(window.isNil,{ - // this.insp; - //}); + window.setInnerExtent(wbw = b.width + 4, wbh = b.height + 17); /* auto-place the window. but we need to know if you explicitly passed in bounds. @@ -142,6 +140,7 @@ }); */ } + reflowAll { view.reflowAll; } Modified: trunk/build/SCClassLibrary/crucial/Instr/InstrSpawner.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/Instr/InstrSpawner.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/Instr/InstrSpawner.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -32,7 +32,7 @@ defName = synthDef.name; numChannels = synthDef.numChannels; rate = synthDef.rate; - this.watchScalars; + this.watchNoncontrols; synthDef } } @@ -68,7 +68,7 @@ ^true } update { arg changed,changer; - // one of my scalar inputs changed + // one of my noncontrol inputs changed if(this.isPlaying,{ "one of my inputs changed, need to send sample change etc.".warn; Modified: trunk/build/SCClassLibrary/crucial/Instr/InstrSynthDef.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/Instr/InstrSynthDef.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/Instr/InstrSynthDef.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -9,7 +9,7 @@ // they are created in the context of the synth def and added // magically/secretly. // this is for adding buffers, samples, inline players, subpatches, spawners etc. - var secretIr, secretKr,stepchildren; + var secretIr, secretKr,stepchildren,synthProxy; var <>tempTempoKr; @@ -46,26 +46,34 @@ // create OutputProxy In InTrig Float etc. outputProxies = this.buildControlsWithObjects(instr,inputs); result = instr.valueArray(outputProxies); - rate = result.rate; - numChannels = max(1,result.size); if(result != 0.0,{ + rate = result.rate; + numChannels = max(1,result.size); + if(outClass === XOut,{ "XOut not tested yet.".error; //out = outClass.perform(if(this.rate == \audio,\ar,\kr), // inputs.at(0),xfader.value,out) }); - if(rate == \audio,{ - result = outClass.ar(Control.names([\out]).ir([0]) , result); - // can still add Out controls if you always use \out, not index - },{ - if(rate == \control,{ + rate.switch( + \audio, { + result = outClass.ar(Control.names([\out]).ir([0]) , result); + // can still add Out controls if you always use \out, not index + }, + \control, { result = outClass.kr(Control.names([\out]).ir([0]) , result); - },{ - ("InstrSynthDef: scalar rate ? result of your function:" + result + rate).error; - }) - }); + }, + \scalar, { // doesn't make sense for a UGen + ("InstrSynthDef: result of your Instr function was a scalar rate object:" + + result + this.buildErrorString).error; + }, + { + ("InstrSynthDef: result of your Instr function was an object with unknown rate:" + + result + rate + this.buildErrorString).error; + } + ); }); }.try({ arg err; var info; @@ -88,6 +96,7 @@ instr.name.do({ arg part; name = name ++ part.asString.asFileSafeString; }); + //name.debug("name"); if(name.size > 8,{ name = name.copyRange(0,7) ++ name.copyRange(8,name.size - 1).hash.asFileSafeString; }); @@ -101,7 +110,9 @@ name = name ++ fixedID.hash.asFileSafeString; */ longName = name ++ this.class.defNameFromObjects(inputs); + //longName.debug("longName"); name = longName.hash.asFileSafeString; + //name.debug("name"); } // passed to Instr function but not to synth @@ -117,14 +128,6 @@ // argi points to the slot in objects (as supplied to secretDefArgs) // selector will be called on that object to produce the synthArg // thus sample can indicate itself and be asked for \tempo or \bufnum -// addSecretIr { arg name,value,argi,selector; -// secretIrPairs = secretIrPairs.add([name,value,argi,selector]); -// ^Control.names([name]).ir([value]) -// } -// addSecretKr { arg name,value,argi,selector; -// secretKrPairs = secretKrPairs.add([name,value,argi,selector]); -// ^Control.names([name]).kr([value]) -// } // initialValue is used for building the synth def // selector is what will be called on the object to obtain the real value @@ -204,7 +207,7 @@ defarg }); outputProxies = this.buildControls; - // the objects themselves know how best to be represented in teh synth graph + // the objects themselves know how best to be represented in the synth graph // they wrap themselves in In.kr In.ar or they add themselves directly eg (Env) ^outputProxies.collect({ arg outp,i; defargs.at(i).instrArgFromControl(outp,i) @@ -311,4 +314,47 @@ Library.put(SynthDef,server,defName.asSymbol,\assumedLoaded); }) } + *buildSynthDef { + var sd; + sd = UGen.buildSynthDef; + if(sd.isNil,{ + Error("Not currently inside a synth def ugenFunc; No synth def is currently being built.").throw; + }); + if(sd.isKindOf(InstrSynthDef).not,{ + Error("This requires an InstrSynthDef.").throw; + }) + ^sd + } + synthProxy { + ^synthProxy ?? { + synthProxy = SynthProxy.new; + stepchildren = stepchildren.add(synthProxy); + synthProxy + } + } } + +// SynthProxy is a way to access the Synth once the SynthDef has started playing +// there is only one SynthProxy per synth def, though there may be multiple synths spawned +// the synthProxy is in stepchildren and in the Patch's stepChildren so it is prepared and spawned. +// it is roughly equivalent to the synth argument in SC2's Spawn +SynthProxy { + var events,sched; + spawnToBundle { |b| + b.addMessage(this,\didSpawn) + } + + didSpawn { + sched = BeatSched.new; + // sched any events + events.do({ |df| + sched.sched(df[0],df[1]) + }) + } + sched { |delta, function| + events = events.add([delta,function]); + } + channelOffset_ { + // shift the Out.ar + } +} Modified: trunk/build/SCClassLibrary/crucial/Instr/Interface.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/Instr/Interface.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/Instr/Interface.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -62,7 +62,7 @@ prepareToBundle { arg agroup,bundle,private=false,bus,defWasLoaded = false; super.prepareToBundle(agroup,bundle,private,bus,defWasLoaded); - environment.use({ onPrepareToBundle.value(this.group,bundle,true,sharedBus); }); + environment.use({ onPrepareToBundle.value(this.group,bundle,true,this.bus); }); } // on play didSpawn { Modified: trunk/build/SCClassLibrary/crucial/Instr/MoreSpecs.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/Instr/MoreSpecs.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/Instr/MoreSpecs.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -129,11 +129,12 @@ // also a scalar spec, but better to inherit ControlSpec canKr { ^false } - rate { ^\scalar } + rate { ^\noncontrol } // builds the constant into the synthDef defaultControl { arg val; ^NumberEditor.new(this.constrain(val ? this.default),this) } } + StaticIntegerSpec : StaticSpec { *new { arg minval=0, maxval=10, default, units; ^super.new(minval.asInteger, maxval.asInteger, \lin, 1, default , units ) @@ -244,6 +245,13 @@ } } +BusSpec : ScalarSpec { + var <>rate,<>numChannels,<>private; + *new { |rate,numChannels,private| + ^super.new.rate_(rate).numChannels_(numChannels).private_(private) + } +} + SampleSpec : ScalarSpec { *initClass { @@ -347,7 +355,7 @@ *new { arg outSpec,hasGate,hasAudioInput; ^super.new(outSpec).hasGate_(hasGate).hasAudioInput_(hasAudioInput) } - rate {^\scalar } + rate {^\noncontrol } canAccept { arg ting; ^(ting.isString and: {Instr(ting).notNil}) } Modified: trunk/build/SCClassLibrary/crucial/Instr/Patch.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/Instr/Patch.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/Instr/Patch.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -13,6 +13,11 @@ this.inputs.at(argi).connectToPatchIn(patchIn,false); }); } + // currently Patch just hold onto the PatchIns but they are disconnected + //freeToBundle { |bundle| + // super.freeToBundle(bundle); + // bundle.addFunction({ patchIns = nil; }); + //} //subclassResponsibility synthArgsIndices { ^this.subclassResponsibility(thisMethod) } inputs { ^this.subclassResponsibility(thisMethod) } @@ -194,17 +199,17 @@ rate { ^rate ?? { if(this.instr.outSpec.notNil,{ - this.instr.outSpec.rate + rate = this.instr.outSpec.rate },{ - //( this.asString + ": rate is unknown, guessing Audio").warn; - ^'audio' + // guess, but don't cache that guess + 'audio' }); }; } numChannels { ^numChannels ?? { if(this.instr.outSpec.notNil,{ - this.instr.outSpec.numChannels + numChannels = this.instr.outSpec.numChannels },{ //( this.asString + ": numChannels is unknown").warn; nil @@ -288,8 +293,8 @@ patchIns = patchIns.add(patchIn); // although input is control, arg could overide that - if(spec.rate != \scalar - and: {ag.rate != \scalar} + if(spec.rate != \noncontrol + and: {ag.rate != \noncontrol} ,{ // if rate is \stream and spec is not EventStream // then fail @@ -298,7 +303,7 @@ synthPatchIns = synthPatchIns.add(patchIn); synthArgsIndices.put(i,synthPatchIns.size - 1); },{ - // watch scalars for changes. + // watch noncontrols for changes. // if Env or Sample or quantity changed, synth def is invalid //if(ag.isNumber.not,{ ag.addDependant(this); }); }); @@ -316,19 +321,26 @@ }); synthDef = InstrSynthDef.build(this.instr,this.args,this.outClass); defName = synthDef.name; - numChannels = synthDef.numChannels; - rate = synthDef.rate; - this.watchScalars; + // the synthDef has now evaluated and can know the number of channels + // but if it returned an Out.ar then it does not know + // so we will have to trust the Instr outSpec + if(synthDef.numChannels.notNil,{ + numChannels = synthDef.numChannels; + }); + if(synthDef.rate.notNil,{ + rate = synthDef.rate; + }); + this.watchNoncontrols; this.instr.addDependant(this); stepChildren = synthDef.secretObjects; synthDef } } - watchScalars { + watchNoncontrols { this.args.do({ arg ag,i; - if(this.specAt(i).rate === \scalar - or: {ag.rate === \scalar} + if(this.specAt(i).rate === \noncontrol + or: {ag.rate === \noncontrol} ,{ // watch scalars for changes. // if Env or Sample or quantity changed, synth def is invalid Modified: trunk/build/SCClassLibrary/crucial/Instr/instrSupport.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/Instr/instrSupport.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/Instr/instrSupport.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -88,7 +88,7 @@ } + Spec { - rate { ^\scalar } + rate { ^\noncontrol } *findKeyForSpec { arg spec; var matching,exact; Modified: trunk/build/SCClassLibrary/crucial/Players/AbstractPlayer.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/Players/AbstractPlayer.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/Players/AbstractPlayer.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -1,13 +1,20 @@ AbstractPlayer : AbstractFunction { - var <path,name; + var <path,>name; + var <synth,<group,<server,<patchOut,defName; + var <status; + // nil, isPreparing, readyForPlay, isPlaying,isStopped, isStopping, isFreeing, isFreed - var <synth,<group,<server,<patchOut, - <status, // nil, isPreparing, readyForPlay, isPlaying,isStopped, isStopping, isFreeing, isFreed - defName; classvar <>bundleClass; + *bundle { |server,atTime,buildFunction| + var bundle; + bundle = AbstractPlayer.bundleClass.new; + buildFunction.value(bundle); + bundle.sendAtTime(server,atTime); + } + play { arg group,atTime,bus; var timeOfRequest; if(this.isPlaying,{ ^this }); @@ -39,7 +46,6 @@ if(server.isLocal,{ InstrSynthDef.loadCacheFromDir(server); }); - //"prPlay->".debug; this.prPlay(atTime,bus,timeOfRequest); nil }); @@ -48,19 +54,6 @@ }); CmdPeriod.add(this); - // this gets removed in stopToBundle - /*Library.put(AbstractPlayer,\serverDeathWatcher, - Updater(server,{ arg s, message; - if(message == \serverRunning and: {s.serverRunning.not},{ - AppClock.sched(5.0,{ // don't panic to quickly - if(s.serverRunning.not,{ - "Server dead ?".inform; - //this.cmdPeriod; // stop everything, she's dead - }) - }) - }); - }) - );*/ } prPlay { arg atTime,bus,timeOfRequest; @@ -69,8 +62,9 @@ if(status === \isPlaying,{ "already playing".debug }); bundle = AbstractPlayer.bundleClass.new; - if(status !== \readyForPlay,{ this.prepareToBundle(group, bundle, false, bus) }); - this.makePatchOut(group,false,bus,bundle); + if(status !== \readyForPlay,{ + this.prepareToBundle(group, bundle, false, bus) + }); this.spawnToBundle(bundle); bundle.sendAtTime(this.server,atTime ? this.defaultAtTime,timeOfRequest); } @@ -98,17 +92,14 @@ this.loadDefFileToBundle(bundle,server); this.makePatchOut(group,private,bus,bundle); this.makeResourcesToBundle(bundle); - //this.makeGroupsToBundle(bundle); this.prepareChildrenToBundle(bundle); this.loadBuffersToBundle(bundle); - //this.makePatchOut(group,private,bus,bundle); - // make extra busses } makeResourcesToBundle {} prepareChildrenToBundle { arg bundle; this.children.do({ arg child; - // and wouldn't it be better if the bundle + // wouldn't it be better if the bundle // could just be asked if the def was in there ? // this pass thru of defWasLoaded was because of some // double loads @@ -119,6 +110,9 @@ var def,bytes,dn; // Patch needs to know children numChannels // before it can know its own. + // this is the only reason we are forcing the children to load + // their defs here rather then letting them each do it in their own + // prepareToBundle this.children.do({ arg child; child.loadDefFileToBundle(bundle,server); }); @@ -130,10 +124,15 @@ if(dn.isNil or: { Library.at(SynthDef,server,dn.asSymbol).isNil },{ + // Patches are discarding their cache on purpose + // just to be on the safe side. + // at some point I'll tighten this up again and honor the cache for Patch + //dn.debug("dn was nil"); // save it in the archive of the player or at least the name. // Patches cannot know their defName until they have built def = this.asSynthDef; defName = def.name; + //defName.debug("defname"); dn = defName.asSymbol; bytes = def.asBytes; @@ -153,84 +152,14 @@ makePatchOut { arg agroup,private = false,bus,bundle; group = agroup.asGroup; server = group.server; - // shouldn't be top unless you are the top out this.topMakePatchOut(group,private,bus); - - //this.childrenMakePatchOut(group,true,bundle); } topMakePatchOut { arg agroup,private = false,bus; - var b; this.group = agroup; - if(patchOut.notNil,{ - if(bus.notNil,{ - this.bus = bus; - ^patchOut - }); - if(this.rate == \audio,{ - //check if private status changed - if(private,{ - if(patchOut.hasBus,{ - if(patchOut.bus.isAudioOut,{ - patchOut.bus.free; - },{ - ^patchOut - }); - }); - patchOut.bus = Bus.audio(group.server,this.numChannels); - this.annotate(patchOut.bus,"top player but private"); - },{ - if(patchOut.hasBus,{ - if(patchOut.bus.isAudioOut,{ // means is main audio out - //something is wrong here... - patchOut.bus.free; - },{ - ^patchOut - }) - }); - patchOut.bus = Bus(\audio,0,this.numChannels,group.server); - this.annotate(patchOut.bus,"top player out"); - }) - }); - ^patchOut - },{ - //Patch doesn't know its numChannels or rate until after it makes the synthDef - if(this.rate == \audio,{// out yr speakers - if(private,{ - this.setPatchOut( - AudioPatchOut(this,group,bus - ?? { - b = Bus.audio(group.server,this.numChannels); - this.annotate(b,"top player but private"); - b - }) - ) - },{ - this.setPatchOut( - AudioPatchOut(this,group,bus - ?? { - b = Bus(\audio,0,this.numChannels,group.server); - this.annotate(b,"top player out"); - b - }) - ) - }) - },{ - if(this.rate == \control,{ - this.setPatchOut( - ControlPatchOut(this,group, - bus ?? {Bus.control(group.server,this.numChannels)}) - ) - },{ - if(this.rate.isNil,{ - this.die("rate is nil"); - }); - this.setPatchOut( - ScalarPatchOut(this,group,bus) - ) - }); - }); + bus = bus ?? {BusSpec(\audio,this.numChannels,private)}; + if(patchOut.isNil,{ + patchOut = PatchOut(this,group,bus); }); - ^patchOut } @@ -291,15 +220,15 @@ } // these always call children stop { arg atTime,andFreeResources = true; - var b; // this was requested : the normal user thinks that stop means stop - // but they want it to also free itself totally - if(andFreeResources,{ this.free }); + // but they want it to also free its resources + // so really most of the time you mean .free + if(andFreeResources,{ ^this.free }); if(server.notNil,{ - b = AbstractPlayer.bundleClass.new; - this.stopToBundle(b,true); - b.sendAtTime(server,atTime); + AbstractPlayer.bundle(server,atTime,{ |bundle| + this.stopToBundle(bundle,true); + }) }); CmdPeriod.remove(this); } @@ -311,15 +240,7 @@ }); this.freeSynthToBundle(bundle); bundle.addMessage(this,\didStop); - /*bundle.addFunction({ // actually if somebody else is playing, you shouldn't remove yet - var sdw; - sdw = Library.at(AbstractPlayer,\serverDeathWatcher); - if(sdw.notNil,{ - sdw.remove; - Library.removeAt(AbstractPlayer,\serverDeathWatcher); - }); - });*/ - this.freePatchOut(bundle); + //this.freePatchOutToBundle(bundle); }) } didStop { @@ -329,59 +250,55 @@ }); } run { arg flag=true,atTime; - var msg,b; if(synth.notNil,{ - b = AbstractPlayer.bundleClass.new; - b.add( synth.runMsg(flag) ); - b.sendAtTime(server,atTime); + AbstractPlayer.bundle(server,atTime,{ |bundle| + bundle.add( synth.runMsg(flag) ); + }) }); // should call children ? // this isn't fully implemented // might be quite useful } release { arg releaseTime,atTime; - var rb; - rb = AbstractPlayer.bundleClass.new; - this.releaseToBundle(releaseTime,rb); - rb.sendAtTime(server,atTime); + AbstractPlayer.bundle(server,atTime,{ |rb| + this.releaseToBundle(releaseTime,rb); + }) } releaseToBundle { arg releaseTime,bundle; - if(synth.notNil,{ + releaseTime = max(releaseTime ? 0.1,0.01); + if(synth.isPlaying,{ bundle.add(synth.releaseMsg(releaseTime)); - }); - if(releaseTime ? 0.0 > 0.01,{ bundle.addFunction({ - SystemClock.sched(releaseTime,{ + SystemClock.sched(releaseTime+0.1,{ this.stop; nil; }) }); },{ - this.stopToBundle(bundle); - }); + this.stopToBundle(bundle) + }) } free { arg atTime; - var bundle; if([\isFreed,\isFreeing].includes(status).not,{ - bundle = AbstractPlayer.bundleClass.new; - this.freeToBundle(bundle); - bundle.sendAtTime(server,atTime); - },{ - status.debug("status at free"); + AbstractPlayer.bundle(server,atTime,{ |bundle| + this.freeToBundle(bundle); + }) }); } freeToBundle { arg bundle; if([\isFreed,\isFreeing].includes(status).not,{ if(status === \isPlaying,{ - //"freeToBundle, status isPlaying".debug; // sends to all the children this.stopToBundle(bundle); }); this.children.do({ arg child; child.freeToBundle(bundle); }); + // these will be the same thing this.freeResourcesToBundle(bundle); + this.freePatchOutToBundle(bundle); + status = \isFreeing; bundle.addMessage(this,\didFree); }) @@ -404,9 +321,9 @@ synth = nil; }); } - freePatchOut { arg bundle; + freePatchOutToBundle { arg bundle; bundle.addFunction({ - patchOut.free; // free the bus + patchOut.free; // frees the busses patchOut = nil; group = nil; //server = nil; @@ -424,20 +341,11 @@ } bus_ { arg b; if(b.notNil,{ - b = b.asBus(this.rate,this.numChannels,this.server); if(patchOut.notNil,{ - if(patchOut.bus != b,{ - patchOut.bus.free; - }); patchOut.bus = b; }); // otherwise we should have had a patchOut // and there is nowhere to store this - - if(b.numChannels != this.numChannels,{ - warn("numChannels mismatch ! this:" + this - + this.numChannels + "vs. supplied bus:" + b); - }); }); } group_ { arg g; @@ -683,6 +591,11 @@ this.class.annotate(thing,"owner:" + this.asString + ":" + note); } *annotate { arg thing,note; + var prev; + prev = this.getAnnotation(thing); + if(prev.notNil,{ + note = prev ++ ";;" + note; + }); if(thing.isKindOf(Node),{ Library.put(AbstractPlayer, \nodeAnnotations, thing.server ?? {"node has no server, cannot annotate".die}, @@ -694,7 +607,7 @@ thing.server ?? {"Bus has no server, cannot annotate".die}, thing.rate ?? {"Bus has no rate, cannot annotate".die}, thing.index ?? {"Bus has no index, cannot annotate".die}, - thing.asString + ":" + note); + note);//thing.asString + ":" + }); }); } @@ -710,21 +623,7 @@ } *removeAnnotation { arg thing; // shouldnt have to do this since its just a lookup by integer indices -/* if(thing.isKindOf(Node),{ - Library.global.removeAt(AbstractPlayer, \nodeAnnotations, - thing.server ?? {"node has no server, cannot un-annotate".die}, - thing.nodeID ?? {"nodeID is nil, cannot un-annotate".die} - ); - },{ - if(thing.isKindOf(Bus),{ - Library.global.removeAt(AbstractPlayer, \busAnnotations, - thing.server ?? {"Bus has no server, cannot un-annotate".die}, - thing.rate ?? {"Bus has no rate, cannot un-annotate".die}, - thing.index ?? {"Bus has no index, cannot un-annotate".die} - ); - }); - }); -*/ + // and its better to know what it once was annotated as (if it failed to be released etc.) } // using the arg passing version @@ -746,51 +645,7 @@ var <isPlaying=false; loadDefFileToBundle { } -// prepareToBundle { arg agroup,bundle,private = false, bus, defWasLoaded = false; -// status = \isPreparing; -// bundle.addFunction({ -// if(status == \isPreparing,{ -// status = \readyForPlay; -// }) -// }); -// group = agroup.asGroup; -// server = group.server; -// if(defWasLoaded.not,{ -// this.loadDefFileToBundle(bundle,server); -// }); -// this.makePatchOut(group,private,bus,bundle); -// this.makeResourcesToBundle(bundle); -// //this.makeGroupsToBundle(bundle); -// this.prepareChildrenToBundle(bundle); -// -// this.loadBuffersToBundle(bundle); -// //this.makePatchOut(group,private,bus,bundle); -// // make extra busses -// } -// -// -// prepareToBundle { arg agroup,bundle,private = false, bus, defWasLoaded = false; -// status = \isPreparing; -// bundle.addFunction({ -// if(status == \isPreparing,{ -// status = \readyForPlay; -// }) -// }); -// group = agroup.asGroup; -// server = group.server; -// if(defWasLoaded.not,{ -// this.loadDefFileToBundle(bundle,server); -// }); -// -// this.makePatchOut(group,private,bus,bundle); -// this.makeResourcesToBundle(bundle); -// //this.makeGroupsToBundle(bundle); -// this.prepareChildrenToBundle(bundle); -// -// this.loadBuffersToBundle(bundle); -// //this.makePatchOut(group,private,bus,bundle); -// // make extra busses -// } + spawnToBundle { arg bundle; this.children.do({ arg child; child.spawnToBundle(bundle); @@ -824,12 +679,6 @@ rate { ^this.voices.first.rate } numChannels { ^this.voices.first.numChannels } -// releaseToBundle { arg releaseTime = 0.1,bundle; -// this.voices.do({ arg pl; -// pl.releaseToBundle(releaseTime,bundle) -// }); -// super.releaseToBundle(releaseTime,bundle); -// } } MultiTrackPlayer : MultiplePlayers { // abstract @@ -843,8 +692,7 @@ */ AbstractPlayerProxy : AbstractPlayer { // won't play if source is nil - var <>source, - sharedBus; + var <>source; var <socketStatus=\isSleeping; asSynthDef { ^this.source.asSynthDef } @@ -885,6 +733,7 @@ //isPlaying = false; //isSleeping = true; status = \isStopped; + socketStatus = \isSleeping; } children { if(this.source.notNil,{ @@ -895,26 +744,29 @@ } prepareChildrenToBundle { arg bundle; this.children.do({ arg child; - child.prepareToBundle(group,bundle,true,sharedBus); + child.prepareToBundle(group,bundle,true,this.bus); }); } - makeResourcesToBundle { arg bundle; +/* makeResourcesToBundle { arg bundle; if(patchOut.hasBus,{ // could be a scalar out - if(sharedBus.notNil,{ sharedBus.releaseBus(this) }); - sharedBus = SharedBus.newFrom(patchOut.bus,this); - this.annotate(sharedBus,"sharedBus"); - patchOut.bus = sharedBus; + //if(sharedBus.notNil,{ sharedBus.releaseBus(this) }); + sharedBus = patchOut.bus; //SharedBus.newFrom(patchOut.bus,this); + //if(sharedBus.owner === this,{ + // this.annotate(sharedBus,"sharedBus"); + //}); + //patchOut.bus = sharedBus; }); } freeResourcesToBundle { arg bundle; bundle.addFunction({ if(status == \isStopping or: status == \isFreeing or: status == \isStopped,{ - if(sharedBus.notNil,{ - sharedBus.releaseBus(this); - }); + //if(sharedBus.notNil,{ + // sharedBus.releaseBus(this); + //}); sharedBus = nil; }) }); } +*/ } Modified: trunk/build/SCClassLibrary/crucial/Players/AbstractPlayerGui.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/Players/AbstractPlayerGui.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/Players/AbstractPlayerGui.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -81,14 +81,15 @@ } synthConsole { arg layout; - var s, server = model.server.asTarget.server; + var s, server; + server = model.server.asTarget.server; server.gui(layout); - s = //SynthConsole(model,layout).play.registerPlayKey.record.pauseableRecord.write({ + //SynthConsole(model,layout).play.registerPlayKey.record.pauseableRecord.write({ // model.timeDuration }).scope.stop.formats.tempo; - SynthConsole(model,layout).play.record.stop.free.tempo; + s = SynthConsole(model,layout).play.record.stop.free.tempo; ServerErrorGui(server).gui(layout); - + //NotificationCenter.register(s,\didRecordOrWrite,model,{ // NotificationCenter.notify(model,\didRecordOrWrite) }); } Modified: trunk/build/SCClassLibrary/crucial/Players/Patching.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/Players/Patching.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/Players/Patching.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -2,7 +2,7 @@ PatchIn { var <>nodeControl,<>connectedTo; - + *new { arg nodeControl; ^super.newCopyArgs(nodeControl) } @@ -21,10 +21,16 @@ *stream { arg nodeControl; ^ScalarPatchIn(nodeControl) } + *noncontrol { arg nodeControl; + ^ObjectPatchIn(nodeControl) + } server { ^nodeControl.server } group { ^nodeControl.group } + disconnectFrom { |patchOut| + connectedTo = nil; + } } - + AudioPatchIn : PatchIn { rate { ^\audio } @@ -36,8 +42,8 @@ // to set the value of audio, would have to set up a bus and set the sample value thisMethod.notYetImplemented; } -} - +} + ControlPatchIn : AudioPatchIn { rate { ^\control } value_ { arg val; @@ -48,16 +54,19 @@ ScalarPatchIn : ControlPatchIn { rate { ^\scalar } value_ { arg val; - // nothing to do + // nothing to do } } +ObjectPatchIn : ScalarPatchIn { + rate { ^\noncontrol } +} - PatchOut { var <>source,<>group,<bus; var <connectedTo,<>patchOutsOfInputs; + var busses; *new { arg source,group,bus; ^this.perform(source.rate,source,group,bus) @@ -76,8 +85,12 @@ } *stream { arg source,group,bus; ^ScalarPatchOut.prNew(source, group,bus) - } + } + *noncontrol { arg source,group,bus; + ^ObjectPatchOut.prNew(source,group,bus) + } init {} + busses { ^(busses ?? {busses = Dictionary.new}) } connectTo { arg patchIn,needsValueSetNow=true; // am i already connected to this client ? if(connectedTo.isNil or: {connectedTo.includes(patchIn).not},{ @@ -87,35 +100,79 @@ this.perform(patchIn.rate,patchIn,needsValueSetNow);// set value, bus etc. } disconnect { - ("disconnect" + this).postln; + connectedTo.do({ |patchIn| + patchIn.disconnectFrom(this) + }) } free { // tell my connectedTo that i'm gone + this.releaseBusses; + this.disconnect; } - /*pause { arg requester; - if(connectedTo.every({ arg cn; cn === requester }),{ - // then we can pause - }) - }*/ + server { ^group.server } isPlaying { ^group.isPlaying } + bus_ { arg b; - bus = b.asBus; - connectedTo.do({ arg pti; - pti.readFromBus(bus); + if(b != bus,{ + bus = b.asBus(this.rate,source.numChannels,this.server); + + if(bus.numChannels != source.numChannels,{ + warn("numChannels mismatch ! source:" + source + + source.numChannels + "vs. supplied bus:" + b); + }); + + BusPool.retain(bus,source,\out); + connectedTo.do({ arg pti; + pti.readFromBus(bus); + }); }) } hasBus { ^bus.notNil and: {bus.index.notNil} } - + + // allocate extra outs for custom use + // and store them here in the PatchOut + allocBus { |name,rate,numChannels| + var b; + b = BusPool.alloc(rate,this.server,numChannels,source,name); + this.busses[name] = b; + ^b + } + releaseBusses { + // main bus + if(bus.notNil and: {bus.index.notNil},{ + BusPool.release(bus,source); + }); + bus = nil; + + // custom requested busses + if(busses.notNil,{ + busses.keysValuesDo({ |name,bus| + BusPool.release(bus,source); + }); + busses = nil; + }) + } } ControlPatchOut : PatchOut { // you are returned from a .kr play - + init { - // nil : speakers - // integer : that out - // server : private on that server - bus = bus.asBus(this.rate,source.numChannels,this.server); + if(bus.isKindOf(BusSpec),{ + bus = BusPool.makeBusFromSpec(bus,this.server,source,\out) + },{ + // nil : speakers + // integer : that out + // server : private on that server + + // temp hack until the \scalar problem is corrected + if(source.isKindOf(IrNumberEditor).not,{ + bus = bus.asBus(this.rate,source.numChannels,this.server); + BusPool.retain(bus,source,\out); + },{ + bus = nil; + }) + }); } rate { ^\control } synthArg { ^bus.index } //need some initialValue @@ -136,21 +193,14 @@ scalar { arg scalarPatchIn; // polling of value not yet implemented on scserver // scalarPatchIn.value = bus.poll; - [this,scalarPatchIn,this.source] - .debug("control -> scalar patch ? this,scalarPatchIn,this.source"); + //[this,scalarPatchIn,this.source] + // .debug("control -> scalar patch ? this,scalarPatchIn,this.source"); thisMethod.notYetImplemented; } - free { - // PlayerMixer has multiple patchOuts sharing the same bus - if(bus.notNil and: {bus.index.notNil},{ - AbstractPlayer.removeAnnotation(bus); - bus.free; - }); - bus = nil; - } } AudioPatchOut : ControlPatchOut { + rate { ^\audio } synthArg { ^bus.index } audio { arg audioPatchIn,needsValueSetNow; @@ -171,12 +221,16 @@ } } -//AbstractScalarPatchOut -ScalarPatchOut : PatchOut { +ScalarPatchOut : PatchOut { + // floats,NumberEditors, numeric pattern players, midi, wacom // things that are not ON the server - + init { + if(bus.isKindOf(BusSpec),{ // ignore + bus = nil; + }); + } rate { ^\scalar } synthArg { ^source.synthArg @@ -196,6 +250,14 @@ } } +ObjectPatchOut : ScalarPatchOut { + +} + +// this class is only used for KrNumberEditor to send its changes to the server +// it sends it directly to the Synthh using the NodeControl +// its not the best design actually + UpdatingScalarPatchOut : ScalarPatchOut { var enabled=false; *new { arg source,bus,enabled=true; @@ -223,7 +285,7 @@ scalar { arg scalarPatchIn; this.enable; } - enable { + enable { if(enabled.not,{ source.addDependant(this); enabled = true; @@ -233,6 +295,7 @@ connectedTo.do({ arg c; c.value = source.value }) } free { + this.releaseBusses; // probably don't have any source.removeDependant(this); enabled = false; } Modified: trunk/build/SCClassLibrary/crucial/Players/PlayerEfxFunc.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/Players/PlayerEfxFunc.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/Players/PlayerEfxFunc.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -25,10 +25,10 @@ makePatchOut { arg parentGroup,private,bus,bundle; // the subject super.makePatchOut(parentGroup,private,bus,bundle); - effect.makePatchOut(effectGroup,true,sharedBus,bundle); + effect.makePatchOut(effectGroup,true,this.bus,bundle); // effect reads from subject's bus playerInputProxy.numChannels_(subject.numChannels).spec_(subject.spec); - playerInputProxy.setInputBus(sharedBus); + playerInputProxy.setInputBus(this.bus); } spawnToBundle { arg bundle; effect.spawnToBundle(bundle); Modified: trunk/build/SCClassLibrary/crucial/Players/PlayerMixer.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/Players/PlayerMixer.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/Players/PlayerMixer.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -113,9 +113,7 @@ gpminit { arg pls; groupings = pls.collect({ |p| loadDocument(p) }); players = groupings.flat; - } -// prepareToBundle { arg agroup,bundle,private = false, bus; makeResourcesToBundle { arg bundle; groups = groupings.collect({ |pls,i| @@ -127,10 +125,6 @@ g }); super.makeResourcesToBundle(bundle); -/* sharedBus = SharedBus.newFrom(patchOut.bus,this); - this.annotate(sharedBus,"Shared Bus"); - patchOut.bus = sharedBus; -*/ } prepareChildrenToBundle { arg bundle; groupings.do({ |pls,gi| Modified: trunk/build/SCClassLibrary/crucial/Players/PlayerPool.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/Players/PlayerPool.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/Players/PlayerPool.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -53,7 +53,7 @@ prepareChildrenToBundle { arg bundle; super.prepareChildrenToBundle(bundle); list.do({ arg child; - child.prepareToBundle(socketGroup,bundle,true,sharedBus); + child.prepareToBundle(socketGroup,bundle,true,this.bus); }); }*/ spawnToBundle { arg bundle; @@ -79,6 +79,8 @@ }); bundle.addMessage(this,\didSpawn); } + // stopToBundle { |bundle| shouldn't bother to stop the whole list + // only the playing one guiClass { ^PlayerPoolGui } } Modified: trunk/build/SCClassLibrary/crucial/Players/PlayerSocket.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/Players/PlayerSocket.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/Players/PlayerSocket.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -25,14 +25,13 @@ sched = OSCSched.new; dee = EnvelopedPlayer(PlayerInputProxy(AudioSpec(numChannels)),env,numChannels); dum = EnvelopedPlayer(PlayerInputProxy(AudioSpec(numChannels)),env,numChannels); + dee.name = this.name + "EnvelopedPlayer1"; + dum.name = this.name + "EnvelopedPlayer2"; // dee and dum are swapped on alternate spawns // now playing: envdSource = dee; // "on bat" is a baseball term : the guy who is up to bat next onBat = dum; - // problem: - // the EnvelopedPlayer needs to dynamically change the numChannels - // it needs to build multiple synth defs or just do some bus copying } prepareAndSpawn { arg player,releaseTime; if(player.readyForPlay.not,{ @@ -55,8 +54,9 @@ preparePlayer { arg player,onComplete; var b; b = AbstractPlayer.bundleClass.new; - player.prepareToBundle(socketGroup,b,bus: sharedBus); - b.doPrepare(this.server,onComplete) + player.prepareToBundle(socketGroup,b,bus: this.bus); + b.addFunction(onComplete); + b.send(this.server) } spawnPlayer { arg player,releaseTime,beatDelta=0.0,forceRespawn=false; @@ -71,7 +71,9 @@ } qspawnPlayer { arg player,releaseTime; // TODO switch to TempoClock so tempo can change after qspawn sent + // needs xqschedBundle // for now it still needs xblock + // and OSCSched needs to handle preparations /* var bundle; if(status == \isPlaying,{ if((player !== lastPlayer) or: forceRespawn or: (socketStatus == \isSleeping),{ @@ -80,7 +82,7 @@ sched.xqschedBundle(round,this.server,bundle); }) }); -*/ +*/ this.spawnPlayer(player,releaseTime,sched.deltaTillNext(round)) } // respawn the currently playing player @@ -89,20 +91,20 @@ } releaseVoice { arg releaseTime; - var bundle; if(socketStatus == \isWaking,{ sched.xblock; - //"blocked isWaking, setting to isSleeping".debug(thisMethod); socketStatus = \isSleeping; ^this.changed; }); if(socketStatus != \isSleeping,{ - //if(envdSource.notNil,{ - bundle = AbstractPlayer.bundleClass.new; + AbstractPlayer.bundle(this.server,nil,{ |bundle| + var currentSubject; + currentSubject = envdSource.subject; envdSource.releaseToBundle(releaseTime,bundle); - bundle.addFunction({ socketStatus = \isSleeping; }); - bundle.send(this.server); - //}); + bundle.addFunction({ + socketStatus = \isSleeping; + }); + }) }); } isSleeping { @@ -115,42 +117,29 @@ this.annotate(socketGroup,"socketGroup"); NodeWatcher.register(socketGroup); bundle.add( socketGroup.addToTailMsg(group) ); - - sharedBus = SharedBus.newFrom(patchOut.bus,this); - this.annotate(sharedBus,"Shared Bus"); - patchOut.bus = sharedBus; } freeResourcesToBundle { arg bundle; socketGroup.freeToBundle(bundle); socketGroup = nil; - + } prepareChildrenToBundle { arg bundle; - dee.prepareToBundle(socketGroup,bundle, true, sharedBus); - dum.prepareToBundle(socketGroup,bundle,true,sharedBus); - if(source.notNil,{ - source.prepareToBundle(socketGroup,bundle,true, sharedBus); + dee.prepareToBundle(socketGroup,bundle, true, this.bus); + dum.prepareToBundle(socketGroup,bundle,true,this.bus); + if(source.notNil,{ + source.prepareToBundle(socketGroup,bundle,true, this.bus); }); } - // no synth of my own - loadDefFileToBundle { arg bundle,server; - // this should all be done when prepareChildrenToBundle is done !! - //if(source.notNil,{ - // source.loadDefFileToBundle(bundle,server) - //}); - - //var envPatch; -/* this.children.do({ arg child; - child.loadDefFileToBundle(bundle,server); - }); - - dee.loadDefFileToBundle(bundle,server); - // same same - dum.loadDefFileToBundle(bundle,server); -*/ + freeToBundle { |bundle| + super.freeToBundle(bundle); + dee.freeToBundle(bundle); + dum.freeToBundle(bundle); } + // no synth of my own + loadDefFileToBundle { arg bundle,server;} + instrArgFromControl { arg control; // avoiding the super which delegates to the source // i control the enveloped players etc. so don't feed it the source's instrArg @@ -170,29 +159,23 @@ Error("AbstractPlayer:instrArgFromControl: rate unknown = "+this.rate).throw } ) + } -/* ^if(source.notNil,{ - source.instrArgFromControl(control) - },{ - ^super.instrArgFromControl(control) - }) -*/ } - spawnToBundle { arg bundle; if(source.notNil,{ this.setSourceToBundle(source,bundle); }); bundle.addMessage(this,\didSpawn); } - synthArg { ^sharedBus.index } + synthArg { ^this.bus.index } // prepared objects only setSource { arg s,atTime,releaseTime; var bundle; if(this.server.notNil,{ // else not even playing, or not loaded - bundle = AbstractPlayer.bundleClass.new; - this.setSourceToBundle(s,bundle,releaseTime); - bundle.sendAtTime(this.server,atTime); + AbstractPlayer.bundle(this.server,atTime,{ |bundle| + this.setSourceToBundle(s,bundle,releaseTime); + }) },{ source = s; }); @@ -200,34 +183,32 @@ // the main switching method // the source should be prepared setSourceToBundle { arg s,bundle,releaseTime; + var currentSubject; if(envdSource.isPlaying,{ envdSource.releaseToBundle(releaseTime,bundle); - if(envdSource === dee,{ - envdSource = dum; - onBat = dee; - },{ - envdSource = dee; - onBat = dum; - }); + # envdSource, onBat = [onBat,envdSource]; }); + if(envdSource.subject.isKindOf(PlayerInputProxy),{ + envdSource.subject.freeToBundle(bundle) + }); + source = s; envdSource.subject = source; - if(sharedBus.rate != source.rate,{ - if(sharedBus.isNil,{ - "PlayerSocket-setSourceToBundle: I am not prepared".error; + if(this.bus.rate != source.rate,{ + if(this.bus.isNil,{ + "PlayerSocket:setSourceToBundle: I am not prepared".error; },{ - ("PlayerSocket-setSourceToBundle bus and source have different rates:" - + sharedBus.rate + source.rate).error(this,source); + ("PlayerSocket:setSourceToBundle bus and source have different rates:" + + this.bus.rate + source.rate).error(this,source); }) }); - envdSource.spawnOnToBundle(socketGroup,sharedBus,bundle); + envdSource.spawnOnToBundle(socketGroup,this.bus,bundle); socketStatus = \switching; bundle.addFunction({ if(socketStatus != \switching, { socketStatus.debug("socket Status changed !!"); }); socketStatus = \isPlaying; - //isSleeping = isWaking = false; lastPlayer = source; { this.changed; nil; }.defer; nil @@ -236,18 +217,15 @@ didFree { super.didFree; socketStatus = \isSleeping; - //isSleeping = true; - if(sharedBus.notNil,{ - sharedBus.releaseBus(this); - AbstractPlayer.removeAnnotation(sharedBus); - sharedBus = nil; - }); } // emergency kill off contents socketFreeAll { socketGroup.freeAll } + name { + ^name ?? {this.class.name.asString} + } } PlayerEffectSocket : PlayerSocket { @@ -255,16 +233,11 @@ var inputBus; setInputBus { arg abus; - // who did we get this from ? - //"PlayerEffectSocket-setInputBus".debug; - inputBus = SharedBus.newFrom(abus.asBus,this); - this.annotate(inputBus,"inputBus"); - // assume not playing yet + BusPool.retain(abus,this,"inputBus"); } setSourceToBundle { arg aplayer,bundle,releaseTime=0.2; aplayer.inputProxies.first.setInputBus(inputBus); - //("setting inputbus",inputBus); super.setSourceToBundle(aplayer,bundle,releaseTime); } } Modified: trunk/build/SCClassLibrary/crucial/Players/Silence.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/Players/Silence.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/Players/Silence.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -30,17 +30,11 @@ synthArg { ^initValue } -// prepareToBundle { arg group,bundle; -// if(initValue.isNil,{ -// // should share this -// nullBus = Bus.performList(this.rate,group.server,this.numChannels); -// initValue = nullBus.index; -// }); -// super.prepareToBundle(group,bundle); -// } - makePatchOut { - // bus is always given to me - patchOut = PatchOut(this,nil,inBus); + + makePatchOut { arg agroup,private = false,bus,bundle; + // bus is usually given to me via setInputBus + super.makePatchOut(agroup,private,inBus ? bus,bundle) + //patchOut = PatchOut(this,nil,inBus); } rate { ^spec.rate } numChannels { ^(spec.numChannels) } Modified: trunk/build/SCClassLibrary/crucial/Players/SimplePlayerEffect.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/Players/SimplePlayerEffect.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/Players/SimplePlayerEffect.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -5,30 +5,20 @@ AbstractSinglePlayerEffect : HasSubject { - var sharedBus; - - - makeResourcesToBundle { arg bundle; - sharedBus = SharedBus.newFrom(patchOut.bus,this); - AbstractPlayer.annotate(sharedBus,"AbstractSinglePlayerEffect"); - patchOut.bus = sharedBus; +/* makeResourcesToBundle { arg bundle; + //sharedBus = SharedBus.newFrom(patchOut.bus,this); + //if(sharedBus.owner === this,{ + // AbstractPlayer.annotate(sharedBus,"AbstractSinglePlayerEffect"); + //}); + sharedBus = patchOut.bus;// = sharedBus; } +*/ prepareChildrenToBundle { arg bundle; - subject.prepareToBundle(this.group,bundle, true,sharedBus); + subject.prepareToBundle(this.group,bundle, true,this.bus); } - preparePlayer { arg player,bus; - ^player.prepareForPlay(this.group,true,sharedBus); + preparePlayer { arg player; + ^player.prepareForPlay(this.group,true,this.bus); } - freeResourcesToBundle { arg bundle; - bundle.addFunction({ - if(status == \isStopping or: status == \isFreeing or: status == \isStopped,{ - if(sharedBus.notNil,{ - sharedBus.releaseBus(this); - }); - sharedBus = nil; - }) - }) - } } PlayerAmp : AbstractSinglePlayerEffect { @@ -84,7 +74,7 @@ in = In.ar(i_bus,pnc); good = BinaryOpUGen('==', CheckBadValues.kr(in, 0, 0), 0); // silence the output if freq is bad - in = in * good * EnvGen.kr(env,gate,doneAction: 2); + in = in * good * EnvGen.kr(env,gate,doneAction:0); if(numChannels.notNil,{ in = NumChannels.ar(in,numChannels,true); }); @@ -95,22 +85,20 @@ env.asCompileString.hash.asFileSafeString } synthDefArgs { ^[\i_bus,patchOut.synthArg,\gate,1.0] } + + // this is a once-only event; you cannot retrigger it releaseToBundle { arg releaseTime,bundle; - status = \isReleaseing; if(releaseTime.isNil,{ releaseTime = env.releaseTime; }); - if(synth.notNil,{ - bundle.add(synth.releaseMsg(releaseTime + (server.latency?0.05))); - }); - if(releaseTime > 0.01,{ + + if(synth.isPlaying,{ + bundle.add(synth.releaseMsg(releaseTime)); bundle.addFunction({ - SystemClock.sched(releaseTime,{ - // want everything but the synthFree in here - this.stop(nil,false); - nil; + AbstractPlayer.bundle(this.server,releaseTime,{ |bundle| + this.freeToBundle(bundle); }) }); },{ - this.stop(stopSynth: false); + this.freeToBundle(bundle) }); } } Modified: trunk/build/SCClassLibrary/crucial/Sample/Sample.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/Sample/Sample.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/Sample/Sample.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -43,11 +43,11 @@ b.sendAtTime(this.server,nil); } freeToBundle { arg bundle; - this.freePatchOut(bundle); + this.freePatchOutToBundle(bundle); bundle.addMessage(this,\freeHeavyResources); readyForPlay = false; } - freePatchOut { arg bundle; + freePatchOutToBundle { arg bundle; bundle.addFunction({ patchOut.free; patchOut = nil; }) } freeHeavyResources { @@ -64,11 +64,14 @@ } numFrames { ^size } bufnum { - if(UGen.buildSynthDef.notNil,{ + /*if(UGen.buildSynthDef.notNil,{ ("Use bufnumIr, not bufnum to obtain a buffer number inside of a synth def. in:" + UGen.buildSynthDef.instrName).warn; - }); + });*/ ^if(buffer.notNil,{ buffer.bufnum }, nil) } + + asUgenInput { ^this.bufnumIr } + synthArg { ^this.bufnum } bufnumIr { // add a secret ir control @@ -127,7 +130,7 @@ ^BufChannels.ir(this.bufnumIr) } - rate { ^\scalar } + rate { ^\noncontrol } } @@ -227,7 +230,7 @@ } storeArgs { ^[ this.class.abrevPath(soundFilePath) ,tempo, startFrame, endFrame ] } - + printOn { |stream| this.storeOn(stream) } load { arg thing,tempo,argStartFrame = 0,argEndFrame = -1; startFrame = argStartFrame; endFrame = argEndFrame; Modified: trunk/build/SCClassLibrary/crucial/Scheduling/Tempo.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/Scheduling/Tempo.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/Scheduling/Tempo.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -59,7 +59,7 @@ kr { ^TempoPlayer(this).kr } *kr { ^TempoPlayer(default).kr } - + *beats2secsKr { |beats| ^TempoPlayer(default).kr.reciprocal * beats } // rare to have more than one tempo, // but any you create you will have to call destroy on to get rid of it Modified: trunk/build/SCClassLibrary/crucial/Scheduling/TempoBus.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/Scheduling/TempoBus.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/Scheduling/TempoBus.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -46,22 +46,11 @@ } init { arg server; + // BusPool bus = Bus.control(server,1); AbstractPlayer.annotate(bus,"TempoBus"); bus.set(tempo.tempo); tempo.addDependant(this); - - /* client crashed ? - SimpleController(server).put(\serverRunning,{ - if(server.serverRunning.not,{ - this.releaseBus; - },{ - bus = Bus.control(server,1); - bus.set(tempo.tempo); - isReady = true; - }) - }) - */ if(server.serverRunning,{ isReady = true; @@ -70,10 +59,7 @@ } update { arg changed,changer; if(changed === tempo,{ - //bus.server.latency ? 0.05 - // why delay ? - bus.server.listSendBundle(0.05, [bus.setMsg(tempo.tempo)]); - //bus.value = tempo.tempo; + bus.server.listSendBundle(0.02, [bus.setMsg(tempo.tempo)]); }) } } Added: trunk/build/SCClassLibrary/crucial/ServerTools/BusPool.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/ServerTools/BusPool.sc (rev 0) +++ trunk/build/SCClassLibrary/crucial/ServerTools/BusPool.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -0,0 +1,104 @@ + +/* + in the style of Objective-C retain/release memory management. + this is useful for situations where many clients may use the same + bus, handing it to each other. each one retains, each one releases. + when the bus is released for the last time it is freed +*/ + +BusPool { + + classvar <counts,<annotations; + + *alloc { |rate=\audio,server,numChannels=1,client,name| + var prev,bus; + bus = Bus.alloc(rate,server,numChannels); + this.retain(bus,client,name); + ^bus + } + *retain { |bus,client,name| + counts.add(bus); + if(annotations.at(bus,client).notNil,{ + Error("A client may only retain a bus once").throw; + }); + //[bus,client,name].debug("retain"); + annotations.put(bus,client,name); + this.watchServer(bus.server); + } + *release { |bus,client| + var dict,key; + counts.remove(bus); + annotations.removeAt(bus,client); + if(counts.itemCount(bus) == 0,{ + //bus.debug("count 0, freeing bus"); + bus.free; + },{ + //bus.debug("count > 0, hanging on"+counts.itemCount(bus)); + }) + } + + *initClass { + this.reset; + } + *reset { + if(counts.notNil,{ + counts.contents.keysValuesDo({ |bus,count| bus.free }); + }); + counts = Bag.new; + annotations = MultiLevelIdentityDictionary.new; + } + *watchServer { |server| + if(NotificationCenter.registrationExists(server,\newAllocators,this).not,{ + NotificationCenter.register(server,\newAllocators,this,{ + //"new allocators, BusPool".debug; + this.reset; + }); + }); + } + *itemCount { |bus| ^counts.itemCount(bus) } + *busses { ^counts.contents.keys.as(Array) } + *gui { + Sheet({ |f| + counts.contents.keysValuesDo({ |bus,count| + f.startRow; + bus.gui(f); + count.gui(f); + f.flow({ |f| + annotations[bus].keysValuesDo({ |client,name| + f.startRow; + Tile(client,f); + CXLabel(f,":"++name); + }); + }) + }); + if(counts.contents.size == 0,{ + CXLabel(f,"No Busses allocated in BusPool"); + }); + }) + } + *getAnnotations { |bus| + ^annotations[bus] + } + *findBus { |server,index| + ^counts.detect({ |bus| + bus.index == index and: {bus.server === server} + }) + } + *makeBusFromSpec { |busSpec,server,client,name| + var bus; + if(busSpec.rate == \audio,{ + if(busSpec.private,{ + bus = this.alloc(\audio,server,busSpec.numChannels,client,name) + },{ + bus = Bus.new(\audio,0,busSpec.numChannels,server); + this.retain(bus,client,name) + }) + },{ + bus = this.alloc(\control,server,busSpec.numChannels,client,name) + }); + ^bus + } + + +} + Modified: trunk/build/SCClassLibrary/crucial/ServerTools/ServerGui.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/ServerTools/ServerGui.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/ServerTools/ServerGui.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -132,21 +132,41 @@ }); failer.add; if(thisThread.exceptionHandler.notNil,{ - "There is already an exception handler installed".inform; + if(thisThread.exceptionHandler.isKindOf(Message) + and: { thisThread.exceptionHandler.receiver.isKindOf(ServerErrorGui) } + and: { thisThread.exceptionHandler.receiver.isClosed },{ + thisThread.exceptionHandler.receiver.remove; + thisThread.exceptionHandler = Message(this,\handleException); + },{ + // its somebody else + "ServerErrorGui : There is already an exception handler installed".inform; + }) },{ - thisThread.exceptionHandler = { |error| - if(Error.handling,{ error.dump; this.halt; }); - Error.handling = true; - { errors.label = error.errorString.copyRange(0,50); nil }.defer; - nil.handleError(error); - } + thisThread.exceptionHandler = Message(this,\handleException); }) } + handleException { |error| + if(Error.handling,{ error.dump; this.halt; }); + Error.handling = true; + { + if(errors.isClosed,{ + this.remove + },{ + errors.label = error.errorString.copyRange(0,50); + }); + nil + }.defer; + nil.handleError(error); + } remove { + // closing large windows fail to call close on all views failer.remove; thisThread.exceptionHandler = nil; super.remove; } + isClosed { + ^errors.isClosed + } } Modified: trunk/build/SCClassLibrary/crucial/ServerTools/ServerLog.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/ServerTools/ServerLog.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/ServerTools/ServerLog.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -1,7 +1,7 @@ ServerLog : NetAddr { - var <sent,<received; + var <msgs; var lastStatus; *start { |server| var addr,new; @@ -20,14 +20,17 @@ ^new } *gui { |tail=1000| - if(Server.default.addr.isKindOf(ServerLog),{ - Server.default.addr.gui(nil,nil,tail) + var events; + if(Server.default.addr.isKindOf(ServerLog),{ + Server.default.addr.getSortedEvents(tail,{ |events| + Server.default.addr.gui(nil,nil,events) + }); },{ "ServerLog has not been running".inform; }); } *report { |tail=1000| - if(Server.default.addr.isKindOf(ServerLog),{ + if(Server.default.addr.isKindOf(ServerLog),{ Server.default.addr.report(tail) },{ "ServerLog has not been running".inform; @@ -39,41 +42,39 @@ }) } - - // private *new { arg hostname, port=0; ^super.new(hostname,port).slinit } - + slinit { thisProcess.recvOSCfunc = { arg time,replyAddr,msg; var status; if(msg[0] == 'status.reply') { status = msg[0..5]; if(status != lastStatus,{ - received = received.add( ServerLogReceivedEvent(time,status) ); + msgs = msgs.add( ServerLogReceivedEvent(time,status) ); lastStatus = status; }); } { - received = received.add( ServerLogReceivedEvent(time,msg) ) + msgs = msgs.add( ServerLogReceivedEvent(time,msg) ) } }; } sendMsg { arg ... args; if(args != ["/status"],{ - sent = sent.add( ServerLogSentEvent( nil, args,false) ); + msgs = msgs.add( ServerLogSentEvent( nil, args,false) ); }); ^super.sendMsg(*args); } sendBundle { arg time ... args; - sent = sent.add( ServerLogSentEvent( time,args,true) ); + msgs = msgs.add( ServerLogSentEvent( time,args,true) ); ^super.sendBundle(*([time]++args)) } guiClass { ^ServerLogGui } - events { arg tail; + getSortedEvents { arg tail,function; // list in logical time order /* @@ -105,24 +106,22 @@ */ - var q,events,since,a,b; - q = PriorityQueue.new; - sent.do({ |it| q.put(it.eventTime,it) }); - received.do({ |it| q.put(it.eventTime,it) }); - events = Array.fill(sent.size + received.size,{ |i| - //if(i % 25 == 0,{0.01.wait}); - q.pop - }); - - /*(if(numMinutes.notNil,{ - since = Main.elapsedTime - (numMinutes * 60); - events = events.select({ |a| a.eventTime >= since }); - });*/ - if(tail.notNil,{ - ^events.copyRange(events.size-tail-1,events.size-1); - },{ - ^events - }) + Routine({ + var q,events,since,a,b; + + q = PriorityQueue.new; + msgs.do({ |it| q.put(it.eventTime,it) }); + events = Array.fill(msgs.size,{ |i| + if(i % 25 == 0,{0.01.wait}); + q.pop + }); + + if(tail.notNil,{ + function.value( events.copyRange(events.size-tail-1,events.size-1) ); + },{ + function.value( events ) + }) + }).play(AppClock) } *cmdString { |cmd| if(cmd.asInteger != 0,{ @@ -154,7 +153,7 @@ } -ServerLogSentEvent { +ServerLogSentEvent { var <>delta,<>msg,<>isBundle,<>timeSent; @@ -185,10 +184,10 @@ ^time } report { - var cmd, one, numUGens, numSynths, numGroups, numSynthDefs, + var cmd, one, numUGens, numSynths, numGroups, numSynthDefs, avgCPU, peakCPU, sampleRate, actualSampleRate; if(msg[0] == 'status.reply',{ - #cmd, one, numUGens, numSynths, numGroups, numSynthDefs, + #cmd, one, numUGens, numSynths, numGroups, numSynthDefs, avgCPU, peakCPU, sampleRate, actualSampleRate = msg; ("<<< % % ugens % synths % groups % synthDefs".format(this.eventTime,numUGens,numSynths,numGroups,numSynthDefs)).postln },{ @@ -203,5 +202,5 @@ - - + + Modified: trunk/build/SCClassLibrary/crucial/ServerTools/ServerLogGui.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/ServerTools/ServerLogGui.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/ServerTools/ServerLogGui.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -5,11 +5,13 @@ var nodeColors; guiBody { arg layout ... args; - var w,tail=500; + var w,events,tail=500; w = layout.bounds.width; nodeColors = Dictionary.new; - model.events(tail).do({ |ev| + events = args.first; + + events.do({ |ev| var eventTime,timeSent,delta,dir,bg,row; eventTime = ev.eventTime; if(ev.isKindOf(ServerLogSentEvent),{ Modified: trunk/build/SCClassLibrary/crucial/ServerTools/synthDef.sc =================================================================== --- trunk/build/SCClassLibrary/crucial/ServerTools/synthDef.sc 2008-04-20 00:09:41 UTC (rev 7525) +++ trunk/build/SCClassLibrary/crucial/ServerTools/synthDef.sc 2008-04-20 00:20:05 UTC (rev 7526) @@ -4,10 +4,10 @@ stopToBundle {} freeToBundle {} - rate { ^\scalar } + rate { ^\noncontrol } // my bad. was \scalar, this should have been \noncontrol makePatchOut {} - patchOut { ^ScalarPatchOut(this) } + patchOut { ^ObjectPatchOut(this) } connectToPatchIn {} prepareToBundle { arg group,bundle; @@ -133,3 +133,5 @@ }); } } + + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. _______________________________________________ sc-dev mailing list sc-dev@... http://lists.create.ucsb.edu/mailman/listinfo/sc-dev |
| Free Forum Powered by Nabble | Forum Help |