├── .gitignore ├── Classes ├── Extensions │ ├── extBoolean-asFloat.sc │ ├── plusBoolean-blend.sc │ ├── extSimpleNumber-calcCurve.sc │ ├── extServerMeterView-setters.sc │ ├── extSymbol-uEnvirPut.sc │ ├── plusEnv-put.sc │ ├── extSynthDef-justWriteDefFile.sc │ ├── extString-uNamemidi.sc │ ├── extBuffer-uSendCollection.sc │ ├── extNilObject.sc │ ├── plusContiguousBlockAllocator-uReserve.sc │ ├── extObject-isXlike.sc │ └── extEZGui-makeParentView.sc ├── Arg │ ├── Gain.sc │ ├── UMapOut.sc │ └── USharedValueIO.sc ├── Misc │ ├── plusScaledUserView.sc │ ├── GroupWithChildren.sc │ ├── UAuxOut.sc │ ├── IndexL2D.sc │ ├── Angle.sc │ └── OSCMethodPatternDispatcher.sc ├── SyncCenter │ ├── + OSCBundle.sc │ └── + Server.sc ├── GUI │ ├── Misc │ │ ├── IntegerNumberBox.sc │ │ ├── ClearDragSink.sc │ │ ├── UDragBin.sc │ │ └── UDragSource.sc │ ├── plusMenu-uFront.sc │ └── Core │ │ └── UdefsGUI.sc └── Core │ └── MassEditUPattern.sc ├── HelpSource └── Classes │ ├── U-example1.png │ ├── U-example2.png │ ├── UChain-GUI.png │ ├── UScoreGUi.png │ ├── ULib screenshot.png │ └── ULib.schelp ├── Unit-Lib.quark ├── UnitDefs ├── multiply.scd ├── saw.scd ├── tanhDistort.scd ├── freeverb.scd ├── displayName.scd ├── sine.scd ├── envelope.scd ├── pulse.scd ├── gain.scd ├── syncSaw.scd ├── duplicateChannel.scd ├── combFilter.scd ├── peak.scd ├── blip.scd ├── allPass.scd ├── lowPass.scd ├── whiteNoise.scd ├── brownNoise.scd ├── mixer.scd ├── leakDC.scd ├── highPass.scd ├── privateIn.scd ├── crackle.scd ├── grayNoise.scd ├── default.scd ├── formlet.scd ├── pinkNoise.scd ├── bitCrusher.scd ├── freqShift.scd ├── bandStop.scd ├── formant.scd ├── dust.scd ├── privateOut.scd ├── impulse.scd ├── simpleEQ.scd ├── selectChannel.scd ├── lowShelf.scd ├── highShelf.scd ├── soundIn.scd ├── bandPass.scd ├── fullEQ.scd ├── limiter.scd ├── noiseGate.scd ├── tremolo.scd ├── babblingbrook_jmc.scd ├── lfNoise.scd ├── pitchShift.scd ├── delay.scd ├── tiltEQ.scd ├── blipTest.scd ├── median.scd ├── balance.scd ├── rmsCompressor.scd ├── peakCompressor.scd ├── ringMod.scd ├── moogVCF.scd ├── decodeB2.scd ├── output.scd ├── shared_buffer.scd ├── magFreeze.scd ├── mda_piano.scd ├── outputWithSubwoofer.scd ├── divide.scd ├── auxIn.scd ├── cymbalic_mcld.scd ├── sample_delay.scd ├── sos_bell.scd └── bufSoundFile.scd ├── Examples ├── Simple Reverb.scd ├── UMap example.scd ├── UMod example.scd ├── USession example.scd ├── mass edit example.scd ├── Spec guis test.scd ├── UScore example.scd ├── UChain example.scd ├── UEnvGen examples.scd ├── Test FilePlayers 0.1.scd └── test UPattern.scd └── UMapDefs ├── max.scd ├── min.scd ├── dust.scd ├── x_y.scd ├── amp.scd ├── deg_rad.scd ├── lo_hi.scd ├── p_post.scd ├── crossfade.scd ├── gate.scd ├── sustain_time.scd ├── function.scd ├── slew.scd ├── p_alternate.scd ├── impulse.scd ├── lfo_sine.scd ├── legato_time.scd ├── envelope_map.scd ├── p_coin.scd ├── lfo_pulse.scd ├── uchain_track.scd ├── upattern_duration.scd ├── uchain_duration.scd ├── sample_and_hold.scd ├── upattern_sustain.scd ├── toggle_ff.scd ├── upattern_timeToNext.scd ├── start_delay.scd ├── trig_random.scd ├── set_reset_ff.scd ├── lag_lpf.scd ├── lfo_saw.scd ├── db_amp.scd ├── uchain_startTime.scd ├── semitones_rate.scd ├── median.scd ├── value_to_range.scd ├── integer.scd ├── p_stutter.scd ├── slope.scd ├── single_chord.scd ├── scale_time.scd ├── p_select.scd ├── time_freq.scd ├── direction_change.scd ├── density_overlap.scd ├── peak.scd ├── random_time.scd ├── p_brown.scd ├── lfo_step_noise.scd ├── shared_buffer_in.scd ├── lag_linear.scd ├── envelope_rel.scd ├── p_crossfade.scd ├── greater_than.scd ├── add.scd ├── center_range.scd ├── phasor.scd ├── lfo_noise.scd ├── trigger.scd ├── line.scd ├── delay.scd ├── linear.scd ├── p_sine.scd ├── schmidt.scd ├── pulse_divider.scd ├── ringz.scd ├── poll.scd ├── in_range.scd ├── envelope.scd ├── shared_buffer_out.scd ├── expand.scd ├── p_wchoose.scd ├── polar.scd ├── p_select_8.scd ├── rho_theta.scd ├── p_time_humanize.scd ├── multiply.scd ├── p_index_soundFile.scd ├── p_choose.scd ├── round.scd ├── shared_out.scd ├── note_freq.scd ├── select_8.scd ├── tempo_time.scd ├── select_16.scd ├── tempo_factor.scd ├── p_time_quantize.scd ├── p_wchoose_8.scd └── global_control.scd /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /Classes/Extensions/extBoolean-asFloat.sc: -------------------------------------------------------------------------------- 1 | + Boolean { 2 | asFloat { ^this.binaryValue.asFloat } 3 | } -------------------------------------------------------------------------------- /HelpSource/Classes/U-example1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameOfLife/Unit-Lib/HEAD/HelpSource/Classes/U-example1.png -------------------------------------------------------------------------------- /HelpSource/Classes/U-example2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameOfLife/Unit-Lib/HEAD/HelpSource/Classes/U-example2.png -------------------------------------------------------------------------------- /HelpSource/Classes/UChain-GUI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameOfLife/Unit-Lib/HEAD/HelpSource/Classes/UChain-GUI.png -------------------------------------------------------------------------------- /HelpSource/Classes/UScoreGUi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameOfLife/Unit-Lib/HEAD/HelpSource/Classes/UScoreGUi.png -------------------------------------------------------------------------------- /HelpSource/Classes/ULib screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameOfLife/Unit-Lib/HEAD/HelpSource/Classes/ULib screenshot.png -------------------------------------------------------------------------------- /Classes/Extensions/plusBoolean-blend.sc: -------------------------------------------------------------------------------- 1 | + Boolean { 2 | blend { |that, blendFrac = 0.5| 3 | that = that.asBoolean; 4 | ^if( blendFrac >= 0.5 ) { that } { this }; 5 | } 6 | } -------------------------------------------------------------------------------- /Classes/Arg/Gain.sc: -------------------------------------------------------------------------------- 1 | // a level gain that can be used in a EQdef 2 | 3 | Gain : Filter { 4 | *ar { |in, db = 0| 5 | ^in * db.dbamp; 6 | } 7 | 8 | *coeffs { |sr = 44100, db = 0| 9 | ^[[ db.dbamp ], [0]] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Classes/Misc/plusScaledUserView.sc: -------------------------------------------------------------------------------- 1 | + ScaledUserView { 2 | 3 | doScale { |point| 4 | ^point*this.scale*this.drawBounds.extent / this.fromBounds.extent 5 | } 6 | 7 | doReverseScale{ |point| 8 | ^point / (this.drawBounds.extent / this.fromBounds.extent * this.scale ) 9 | } 10 | } -------------------------------------------------------------------------------- /Classes/Misc/GroupWithChildren.sc: -------------------------------------------------------------------------------- 1 | GroupWithChildren : Group { 2 | 3 | var <>children; 4 | 5 | addChild { |child| 6 | children = children.add( child ); 7 | } 8 | 9 | removeChild { |child| 10 | ^children.remove( child ); 11 | } 12 | 13 | at { |index| ^children.at( index ) } 14 | 15 | } -------------------------------------------------------------------------------- /Classes/Extensions/extSimpleNumber-calcCurve.sc: -------------------------------------------------------------------------------- 1 | + SimpleNumber { 2 | 3 | // calculate a curve value for a specific center point 4 | // to be used as curve value for a ControlSpec or lincurve 5 | calcCurve { |min = 0, max = 1| 6 | ^(this.linlin(min,max,0,1).max(1e-154).reciprocal-1).squared.log; 7 | } 8 | 9 | } -------------------------------------------------------------------------------- /Unit-Lib.quark: -------------------------------------------------------------------------------- 1 | ( 2 | name: "Unit-Lib", 3 | summary: "The Unit Library is a system that provides high level abstractions on top of the SuperCollider language.", 4 | version: "2.0.1", 5 | schelp: "Unit Library", 6 | dependencies: ["wslib", "NetLib"], 7 | license: "GPL3", 8 | copyright: "Miguel Negrão, Wouter Snoei 2006-2024" 9 | ) 10 | -------------------------------------------------------------------------------- /Classes/Extensions/extServerMeterView-setters.sc: -------------------------------------------------------------------------------- 1 | + ServerMeterView { 2 | 3 | *updateFreq_ { |new = 10| 4 | updateFreq = new; 5 | } 6 | 7 | *dBLow_ { |new = -80| 8 | dBLow = new; 9 | } 10 | 11 | *meterWidth_ { |new = 15| 12 | meterWidth = new; 13 | } 14 | 15 | *gapWidth_ { |new = 4| 16 | gapWidth = new; 17 | } 18 | 19 | *height_ { |new = 230| 20 | height = new; 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /UnitDefs/multiply.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \multiply 3 | 4 | A simple amplitude multiplication Udef. 5 | 6 | mul: amplitude multiplication value (can be UMap) 7 | 8 | -- 9 | this is an Udef definition file 10 | part of the Unit lib default Udefs set 11 | */ 12 | 13 | Udef( \multiply, { |mul = 1| 14 | var in; 15 | in = UIn.ar(0, 1 ); 16 | in = in * mul; 17 | UOut.ar( 0, in ); 18 | }) 19 | .category_( \utility ) 20 | .setSpec( \mul, [-1,1,\lin,0,1].asSpec ); -------------------------------------------------------------------------------- /UnitDefs/saw.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \saw 3 | 4 | A band-limited sawtooth wave generator. 5 | http://en.wikipedia.org/wiki/Sawtooth_wave 6 | 7 | freq: frequency (Hz) 8 | amp: amplitude (0-1) 9 | 10 | -- 11 | this is an Udef definition file 12 | part of the Unit lib default Udefs set 13 | */ 14 | 15 | Udef( \saw, { |freq = 440, amp = 0.1| 16 | UMixOut.ar( 0, Saw.ar( freq, amp ), 0, true ) 17 | } ).category_( \oscillator ) 18 | .setSpec( \freq, FreqSpec( 2, 20000 ) ); -------------------------------------------------------------------------------- /UnitDefs/tanhDistort.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \tanhDistort 3 | 4 | Distorts the sound via a hyperbolic tangent function. 5 | 6 | inGain: input gain (dB). 7 | outGain:output gain (dB). 8 | 9 | -- 10 | this is an Udef definition file 11 | part of the Unit lib default Udefs set 12 | */ 13 | 14 | Udef( \tanhDistort, { |inGain = 0, outGain = 0| 15 | UOut.ar( 0, (UIn.ar( 0 ) * inGain.dbamp).tanh * outGain.dbamp ) 16 | } ) 17 | .category_( \distortion ) 18 | .setSpec( \inGain, [0, 60].asSpec ) 19 | .setSpec( \outGain, [-60, 0].asSpec ); -------------------------------------------------------------------------------- /UnitDefs/freeverb.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \freeverb 3 | 4 | a simple reverb. 5 | 6 | mix: wet/dry mix (0-1) 7 | room: room size (0-1) 8 | damp: damp (0-1) (0 means no damping) 9 | */ 10 | 11 | Udef( \freeverb, { |mix = 0.33, room = 0.5, damp = 0.5| 12 | var in, delayed; 13 | in = UIn.ar( 0, 1 ); 14 | in = FreeVerb.ar( in, mix, room, damp ); 15 | UOut.ar( 0, in ) 16 | } ) 17 | .category_( \effect ) 18 | .setSpec( \mix, [ 0, 1, \lin, 0, 0.33 ] ) 19 | .setSpec( \room, [ 0.1, 1.0, \lin, 0, 0.5 ] ) 20 | .setSpec( \damp, [0,1,\lin,0,0.5] ); -------------------------------------------------------------------------------- /UnitDefs/displayName.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \displayName 3 | 4 | A simple Udef for showing a custom name in the Score editor. It produces no sound. 5 | 6 | name: the name to display (String) 7 | 8 | -- 9 | this is an Udef definition file 10 | part of the Unit lib default Udefs set 11 | */ 12 | 13 | FreeUdef( \displayName, [ 14 | [ \name, "name", StringSpec().default_( "name" ), false, \init ], 15 | ]) 16 | .apxCPU_( 0 ) 17 | .createsSynth_( false ) 18 | .nameFunc_({ |unit| 19 | unit.get( \name ); 20 | }) 21 | .category_( 'utility' ); -------------------------------------------------------------------------------- /Examples/Simple Reverb.scd: -------------------------------------------------------------------------------- 1 | ( 2 | ~points = all {: Point(6*x,6*y), x <- [-1,1], y <- [-1,1]}; 3 | Udef(\justAPoint, 4 | { |point = #[0,0]| UOut.kr(0, point.asArray) }, 5 | [[ \point: 0@0, WFSPointSpec( 200, 0.1 ) ]]).sendSynthDef(s); 6 | UChain(*([\diskSoundFile, \justAPoint 7 | 8 | ]++4.collect{|i|[ 9 | U(\simpleReverb) 10 | .setAudioOut(0,i+1) 11 | .set(\amp,0.8), 12 | U(\wfsStaticPlane) 13 | .setAudioIn(0,i+1) 14 | .point_(~points[i]) 15 | ] 16 | }.flat++[\wfsDynamicPoint])).gui 17 | ) 18 | 19 | UChain().gui 20 | 21 | -------------------------------------------------------------------------------- /Classes/Extensions/extSymbol-uEnvirPut.sc: -------------------------------------------------------------------------------- 1 | + Symbol { 2 | 3 | uEnvirPut { |value, spec| 4 | var default; 5 | value = value.value; 6 | if( value.isArray && { spec.notNil } ) { 7 | spec = spec.massEditSpec( value ).default_( { spec.default }!(value.size) ); 8 | }; 9 | currentEnvironment.put( this, value ); 10 | if( spec.notNil ) { 11 | currentEnvironment[ \u_specs ] = currentEnvironment[ \u_specs ] ?? {()}; 12 | currentEnvironment[ \u_specs ].put( this, spec ); 13 | }; 14 | currentEnvironment.changed( this ); 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /UnitDefs/sine.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \sine 3 | 4 | A sine wave oscillator. 5 | http://en.wikipedia.org/wiki/Sine_wave 6 | 7 | freq: frequency (Hz) 8 | phase: phase (-pi - pi) 9 | amp: amplitude (0-1) 10 | 11 | -- 12 | this is an Udef definition file 13 | part of the Unit lib default Udefs set 14 | */ 15 | 16 | Udef( \sine, { |freq = 440, phase = 0, amp = 0.1| 17 | UMixOut.ar( 0, SinOsc.ar( freq, phase, amp ), 0, true ) 18 | } ).category_( \oscillator ) 19 | .setSpec( \freq, FreqSpec( 2, 20000 ) ) 20 | .setSpec( \phase, AngleSpec() ) 21 | .setSpecMode( \amp, \normal ); -------------------------------------------------------------------------------- /UnitDefs/envelope.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \envelope_amp 3 | 4 | An amplitude envelope with audio-rate precision. 5 | 6 | env: an Env. It should have levels between 0 and 1, which will be mapped with according to the \amp ControlSpec. 7 | timeScale: time scale multiplier 8 | 9 | -- 10 | this is an Udef definition file 11 | part of the Unit lib default Udefs set 12 | */ 13 | 14 | MultiChannelUdef( \envelope_amp, { 15 | var in; 16 | in = UIn.ar(0, Udef.numChannels ); 17 | in = in * UEnvGen.ar( \env, \amp, \timeScale ); 18 | UOut.ar( 0, in ); 19 | }) 20 | .category_( \utility ) -------------------------------------------------------------------------------- /UMapDefs/max.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \max 3 | 4 | This UMap outputs the highest (maximum) out of two input values 5 | 6 | a: the first value 7 | b: the second value 8 | 9 | a and b arg ranges are mapped to that of the parameter to which the UMap is connected. 10 | 11 | -- 12 | this is an UMapDef definition file 13 | part of the Unit lib default UMapDefs set 14 | */ 15 | 16 | HybridUMapDef( \max, { |a = 0.5, b = 0.5| 17 | UMapOut.kr( a.max(b) ); 18 | }, { |unit, a = 0.5, b = 0.5| 19 | a.max(b); 20 | }) 21 | .mappedArgs_([ \a, \b ]) 22 | .setSpec( \a, UAdaptSpec() ) 23 | .setSpec( \b, UAdaptSpec() ) 24 | .category_( 'math' ) -------------------------------------------------------------------------------- /UMapDefs/min.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \min 3 | 4 | This UMap outputs the lowest (minumum) out of two input values 5 | 6 | a: the first value 7 | b: the second value 8 | 9 | a and b arg ranges are mapped to that of the parameter to which the UMap is connected. 10 | 11 | -- 12 | this is an UMapDef definition file 13 | part of the Unit lib default UMapDefs set 14 | */ 15 | 16 | HybridUMapDef( \min, { |a = 0.5, b = 0.5| 17 | UMapOut.kr( a.min(b) ); 18 | }, { |unit, a = 0.5, b = 0.5| 19 | a.min(b); 20 | }) 21 | .mappedArgs_([ \a, \b ]) 22 | .setSpec( \a, UAdaptSpec() ) 23 | .setSpec( \b, UAdaptSpec() ) 24 | .category_( 'math' ) -------------------------------------------------------------------------------- /UnitDefs/pulse.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \pulse 3 | 4 | A band-limited pulse wave generator. 5 | http://en.wikipedia.org/wiki/Sawtooth_wave 6 | 7 | freq: frequency (Hz) 8 | width: relative width (0-1) of the pulse. 0.5 means a square wave. 9 | amp: amplitude (0-1) 10 | 11 | -- 12 | this is an Udef definition file 13 | part of the Unit lib default Udefs set 14 | */ 15 | 16 | Udef( \pulse, { |freq = 440, width = 0.5, amp = 0.1| 17 | UMixOut.ar( 0, Pulse.ar( freq, width, amp ), 0, true ) 18 | } ).category_( \oscillator ) 19 | .setSpec( \freq, FreqSpec( 2, 20000 ) ) 20 | .setSpecMode( \amp, \normal ) 21 | .setSpecMode( \width, \normal ); -------------------------------------------------------------------------------- /UnitDefs/gain.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \gain 3 | 4 | A simple gain stage. Can set a gain in dB and inverse phase. 5 | 6 | gain: added gain (dB) 7 | inverse: inverse phase (false/true) 8 | numChannels: number of channels 9 | 10 | -- 11 | this is an Udef definition file 12 | part of the Unit lib default Udefs set 13 | */ 14 | 15 | MultiChannelUdef( \gain, { |gain = 0, inverse = 0| 16 | var in; 17 | in = UIn.ar(0, Udef.numChannels ); 18 | in = in * gain.dbamp * inverse.linlin(0,1,1,-1); 19 | UOut.ar( 0, in ); 20 | }) 21 | .category_( \utility ) 22 | .setSpec( \gain, [-96,24,\lin,0,0].asSpec ) 23 | .setSpec( \inverse, BoolSpec(false) ); -------------------------------------------------------------------------------- /UnitDefs/syncSaw.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \syncSaw 3 | 4 | A synced saw wave generator. 5 | http://en.wikipedia.org/wiki/Oscillator_sync 6 | 7 | syncFreq: fundamental frequency (Hz) 8 | sawFreq: frequency of synced saw - prefferably > syncFreq (Hz) 9 | amp: amplitude (0-1) 10 | 11 | -- 12 | this is an Udef definition file 13 | part of the Unit lib default Udefs set 14 | */ 15 | 16 | Udef( \sync_saw, { |syncFreq = 440, sawFreq = 440, amp = 0.1| 17 | UMixOut.ar( 0, SyncSaw.ar( syncFreq, sawFreq, amp ), 0, true ) 18 | } ).category_( \oscillator ) 19 | .setSpec( \syncFreq, FreqSpec( 2, 20000 ) ) 20 | .setSpec( \sawFreq, FreqSpec( 2, 20000 ) ); -------------------------------------------------------------------------------- /UnitDefs/duplicateChannel.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \duplicateChannel 3 | 4 | duplicates a single channel to multiple outputs. 5 | 6 | numChannels: number of output channels (*). 7 | 8 | (*) only the following numbers of channels are allowed: 9 | 1,2,3,4,5,6,7,8,10,12,16,24,32 10 | 11 | -- 12 | this is an Udef definition file 13 | part of the Unit lib default Udefs set 14 | */ 15 | 16 | MultiChannelUdef( \duplicateChannel, { 17 | var amps; 18 | amps = Udef.numChannels.collect({ |i| 19 | ("amp" ++ i).asSymbol.ukr( 1, warp: 'amp' ) 20 | }); 21 | UOut.ar( 0, UIn.ar( 0, 1 ).dup( Udef.numChannels ) * amps ); 22 | }) 23 | .category_( \utility ) -------------------------------------------------------------------------------- /UnitDefs/combFilter.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \combFilter 3 | 4 | A comb filter. 5 | 6 | freq: frequency. 7 | decayTime: decay time in seconds 8 | dry: level of dry (unprocessed) signal 9 | 10 | -- 11 | this is an Udef definition file 12 | part of the Unit lib default Udefs set 13 | */ 14 | 15 | Udef( \combFilter, { |freq = 440, decayTime = 1, dry = 0| 16 | var in; 17 | in = UIn.ar(0,1); 18 | in = CombC.ar( in, 1/2, 1/freq, decayTime ) + (in * dry); 19 | UOut.ar( 0, in ); 20 | }) 21 | .category_( \filter ) 22 | .setSpec( \freq, FreqSpec( 2, 20000 )) 23 | .setSpec( \decayTime, [ 0.01, 10, \exp, 0, 0.1 ].asSpec ) 24 | .setSpec( \dry, \amp.asSpec ) -------------------------------------------------------------------------------- /UnitDefs/peak.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \peak 3 | 4 | Parametric equalizer 5 | 6 | freq: cutoff frequency. 7 | rq: the reciprocal of Q. bandwidth / cutoffFreq 8 | db: boost/cut the center frequency (in dBs). 9 | 10 | -- 11 | this is an Udef definition file 12 | part of the Unit lib default Udefs set 13 | */ 14 | 15 | Udef( \peak, { |freq = 440, rq = 1, db = 0| 16 | var in; 17 | in = UIn.ar(0,1); 18 | in = BPeakEQ.ar( in, freq.clip(20,20000), rq, db ); 19 | UOut.ar( 0, in ); 20 | }) 21 | .category_( \filter ) 22 | .setSpec( \freq, \freq.asSpec ) 23 | .setSpec( \rq, [ 0.01, 10, \exp, 0, 1 ].asSpec ) 24 | .setSpec( \db, [-24,24,\lin].asSpec ) 25 | -------------------------------------------------------------------------------- /Classes/Extensions/plusEnv-put.sc: -------------------------------------------------------------------------------- 1 | + Env { 2 | 3 | put { |time = 0, level = 1, precision = 0.001| // put a level at an absolute time 4 | var absTimes, index; 5 | absTimes = [0] ++ this.times.integrate; 6 | index = absTimes.detectIndex({ |item| time.equalWithPrecision( item, precision ) }); 7 | if( index.notNil ) { 8 | this.levels = this.levels.copy.put( index, level ); 9 | } { 10 | index = absTimes.detectIndex({ |item| item > time }) ?? { absTimes.size }; 11 | absTimes = absTimes.insert( index, time ); 12 | this.times = absTimes.differentiate[1..]; 13 | this.levels = this.levels.copy.insert( index, level ); 14 | }; 15 | } 16 | } -------------------------------------------------------------------------------- /UnitDefs/blip.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \blip 3 | 4 | Band Limited ImPulse generator. All harmonics have equal amplitude. This is the equivalent of 'buzz' in MusicN languages. 5 | 6 | freq: frequency (Hz) 7 | numharm: number of harmonics (1-...) 8 | amp: amplitude (0-1) 9 | 10 | -- 11 | this is an Udef definition file 12 | part of the Unit lib default Udefs set 13 | */ 14 | 15 | Udef( \blip, { |freq = 440, numharm = 200, amp = 0.1| 16 | UMixOut.ar( 0, Blip.ar( freq, numharm, amp ), 0, true ) 17 | } ).category_( \oscillator ) 18 | .setSpec( \freq, FreqSpec( 2, 20000 ) ) 19 | .setSpec( \numharm, PositiveIntegerSpec(200,1, 1000) ) 20 | .setSpecMode( \amp, \normal ); -------------------------------------------------------------------------------- /UnitDefs/allPass.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \allPass 3 | 4 | An all-pass filter based on a cubic interpolated delay line. 5 | 6 | freq: frequency. 7 | decayTime: decay time in seconds 8 | dry: level of dry (unprocessed) signal 9 | 10 | -- 11 | this is an Udef definition file 12 | part of the Unit lib default Udefs set 13 | */ 14 | 15 | Udef( \allPass, { |freq = 440, decayTime = 1, dry = 0| 16 | var in; 17 | in = UIn.ar(0,1); 18 | in = AllpassC.ar( in, 1/2, 1/freq, decayTime ) + (in * dry); 19 | UOut.ar( 0, in ); 20 | }) 21 | .category_( \filter ) 22 | .setSpec( \freq, FreqSpec( 2, 20000 )) 23 | .setSpec( \decayTime, [ 0.01, 10, \exp, 0, 0.1 ].asSpec ) 24 | .setSpec( \dry, \amp.asSpec ); -------------------------------------------------------------------------------- /UMapDefs/dust.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \dust 3 | 4 | Creates an UMap for producing random single-frame impulses. 5 | 6 | density: average number of impulses per second 7 | range: the output range 8 | 9 | The 'range' arg range is mapped to that of the parameter to which the UMap is connected. 10 | 11 | -- 12 | this is an UMapDef definition file 13 | part of the Unit lib default UMapDefs set 14 | */ 15 | 16 | UMapDef( \dust, { |density = 20, range = #[0.0,1.0]| 17 | var sig; 18 | URandSeed.ir(); 19 | sig = Dust.kr( density ).range(*range); 20 | UMapOut.kr(sig); 21 | }) 22 | .setSpec( \density, [0.01,1000,\exp, 0, 20].asSpec ) 23 | .mappedArgs_( [ \range ] ) 24 | .category_( 'trigger' ) 25 | -------------------------------------------------------------------------------- /UMapDefs/x_y.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \x_y 3 | 4 | Creates an UMap intended for use on modulatable point parameters. It converts the point into two linear controls for x and y, which on their turn can be used to assign other UMaps to. 5 | 6 | x: the x value 7 | y: the y value 8 | 9 | The 'x' and 'y' arg ranges are mapped to that of the parameter to which the UMap is connected. 10 | 11 | -- 12 | this is an UMapDef definition file 13 | part of the Unit lib default UMapDefs set 14 | */ 15 | 16 | UMapDef( \x_y, { |x = 0.5, y = 0.5| 17 | UMapOut.kr([x,y]); 18 | }) 19 | .uchainInitFunc_({ |unit, chain| 20 | unit.def = \expand; 21 | }) 22 | .mappedArgs_( [ \x, \y ] ) 23 | .category_( 'private' ); 24 | -------------------------------------------------------------------------------- /UnitDefs/lowPass.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \lowPass 3 | 4 | A resonant low-pass filter 5 | 6 | freq: cutoff frequency. 7 | rq: the reciprocal of Q. bandwidth / cutoffFreq 8 | 9 | -- 10 | this is an Udef definition file 11 | part of the Unit lib default Udefs set 12 | */ 13 | 14 | Udef( \lowPass, { |freq = 440, rq = 1| 15 | var in; 16 | in = UIn.ar(0,1); 17 | in = BLowPass.ar( in, freq.clip(20,20000), rq ); 18 | UOut.ar( 0, in ); 19 | }) 20 | .category_( \private ) 21 | .setSpec( \freq, \freq.asSpec ) 22 | .setSpec( \rq, [ 0.01, 10, \exp, 0, 1 ].asSpec ) 23 | .uchainInitFunc_({ |unit| 24 | var args; 25 | if( unit.def.category == \private ) { 26 | unit.defName = \filter; 27 | }; 28 | }); -------------------------------------------------------------------------------- /UnitDefs/whiteNoise.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \whiteNoise 3 | 4 | A white noise generator. Generates noise whose spectrum has equal power at all frequencies. 5 | http://en.wikipedia.org/wiki/White_noise 6 | 7 | amp: amplitude (0-1) of the noise 8 | seed: random seed (positive whole number). The same seed will always result in exactly the same noise on any computer. If you want decorrelated noise from multiple sources, change the seed on each source to a different number. 9 | 10 | -- 11 | this is an Udef definition file 12 | part of the Unit lib default Udefs set 13 | */ 14 | 15 | Udef( \whiteNoise, { |amp = 0.1| 16 | URandSeed.ir(); 17 | UMixOut.ar( 0, WhiteNoise.ar * amp, 0, true ) 18 | } ).category_( \noise ) -------------------------------------------------------------------------------- /Classes/Misc/UAuxOut.sc: -------------------------------------------------------------------------------- 1 | UAuxIn { 2 | 3 | classvar <>offset = 64; 4 | classvar <>specs; 5 | 6 | *initClass { 7 | Class.initClassTree(Spec); 8 | specs = IdentityDictionary(); 9 | specs.put( \bus, PositiveIntegerSpec(0,0,64) ); 10 | } 11 | 12 | *ar { |bus = 0, numChannels = 1| 13 | ^In.ar( bus + FirstPrivateBus.ir + this.offset, numChannels ); 14 | } 15 | 16 | } 17 | 18 | UAuxOut : UAuxIn { 19 | 20 | *ar { |bus = 0, channelsArray| 21 | ^Out.ar( bus + FirstPrivateBus.ir + this.offset, channelsArray ); 22 | } 23 | 24 | } 25 | 26 | UPrivateIn : UAuxIn { 27 | 28 | classvar <>offset = 128; 29 | 30 | } 31 | 32 | UPrivateOut : UAuxOut { 33 | 34 | classvar <>offset = 128; 35 | 36 | } -------------------------------------------------------------------------------- /UMapDefs/amp.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \amp 3 | 4 | A simple amplitude gain stage. Can set an amplitude (multiplier) and inverse phase. Note that this Udef can only make the input signal softer, not louder. 5 | 6 | amp: amplitude (0-1) 7 | inverse: inverse phase (false/true) 8 | numChannels: number of channels 9 | 10 | -- 11 | this is an Udef definition file 12 | part of the Unit lib default Udefs set 13 | */ 14 | 15 | MultiChannelUdef( \amp, { |amp = 0.1, inverse = 0| 16 | var in; 17 | in = UIn.ar(0, Udef.numChannels ); 18 | in = in * amp * inverse.linlin(0,1,1,-1); 19 | UOut.ar( 0, in ); 20 | }) 21 | .category_( \utility ) 22 | .setSpec( \amp, \amp.asSpec, \normal ) 23 | .setSpec( \inverse, BoolSpec(false) ); -------------------------------------------------------------------------------- /UMapDefs/deg_rad.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \deg_rad 3 | 4 | Creates an UMap for converting radians to degrees, to be used on any UMap with an angle setting in radians (-pi to pi) 5 | 6 | deg: amount of degrees (-180-180) 7 | 8 | -- 9 | this is an UMapDef definition file 10 | part of the Unit lib default UMapDefs set 11 | */ 12 | 13 | HybridUMapDef( \deg_rad, { |deg = 0| 14 | UMapDef.useMappedArgs = false; // use raw values instead of mapped (0-1) 15 | UMapOut.kr( deg * pi / 180 ); 16 | }, { |unit, deg = 0| 17 | deg * pi / 180; 18 | }) 19 | .setSpec( \deg, [-180, 180, \lin, 0, 1 ] ) 20 | .canUseUMapFunc_({ |unit, key, umapdef| 21 | unit.getSpec( key ).isKindOf( AngleSpec ); 22 | }) 23 | .category_( 'convert' ) -------------------------------------------------------------------------------- /UnitDefs/brownNoise.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \brownNoise 3 | 4 | A brownian noise generator. Generates noise whose spectrum falls off in power by 6 dB per octave. 5 | http://en.wikipedia.org/wiki/Brownian_noise 6 | 7 | amp: amplitude (0-1) of the noise 8 | seed: random seed (positive whole number). The same seed will always result in exactly the same noise on any computer. If you want decorrelated noise from multiple sources, change the seed on each source to a different number. 9 | 10 | -- 11 | this is an Udef definition file 12 | part of the Unit lib default Udefs set 13 | */ 14 | 15 | Udef( \brownNoise, { |amp = 0.1| 16 | URandSeed.ir(); 17 | UMixOut.ar( 0, BrownNoise.ar * amp, 0, true ) 18 | } ).category_( \noise ) -------------------------------------------------------------------------------- /UnitDefs/mixer.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \mixer 3 | 4 | mixes multiple channels together to a single one by summing 5 | 6 | amp0 .. ampN: amplitude of each input signal 7 | numChannels: number of channels (*). 8 | 9 | (*) only the following numbers of channels are allowed: 10 | 1,2,3,4,5,6,7,8,10,12,16,24,32 11 | 12 | -- 13 | this is an Udef definition file 14 | part of the Unit lib default Udefs set 15 | */ 16 | 17 | MultiChannelUdef( \mixer, { 18 | var sig, amps; 19 | sig = UIn.ar( 0, Udef.numChannels, endPoint: true ); 20 | amps = Udef.numChannels.collect({ |i| 21 | ("amp" ++ i).asSymbol.ukr( 1/Udef.numChannels.sqrt, warp: 'amp' ) 22 | }); 23 | UOut.ar( 0, (sig * amps).sum ); 24 | }) 25 | .category_( \utility ) -------------------------------------------------------------------------------- /UMapDefs/lo_hi.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \lo_hi 3 | 4 | Creates an UMap intended for use on modulatable range parameters. It converts the range into two linear controls for lo and hi, which on their turn can be used to assign other UMaps to. 5 | 6 | lo: the lower value 7 | hi: the higher value 8 | 9 | The 'lo' and 'hi' arg ranges are mapped to that of the parameter to which the UMap is connected. 10 | 11 | -- 12 | this is an UMapDef definition file 13 | part of the Unit lib default UMapDefs set 14 | */ 15 | 16 | UMapDef( \lo_hi, { |lo = 0.0, hi = 1.0| 17 | UMapOut.kr([lo,hi]); 18 | }) 19 | .uchainInitFunc_({ |unit, chain| 20 | unit.def = \expand; 21 | }) 22 | .mappedArgs_( [ \lo, \hi ] ) 23 | .category_( 'private' ); 24 | -------------------------------------------------------------------------------- /UnitDefs/leakDC.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \leakDC 3 | 4 | Removes DC offset from signal. 5 | 6 | cutFreq: frequencies below the cutFreq (Hz) will be reduced or removed. A lower cutFreq will make the DC offset removal less effective, a higher cutFreq will result in better offset removal but also in audible loss of bass frequencies in the sound 7 | 8 | -- 9 | this is an Udef definition file 10 | part of the Unit lib default Udefs set 11 | */ 12 | 13 | Udef( \leakDC, { |cutFreq = 20| 14 | var in; 15 | in = UIn.ar(0,1); 16 | cutFreq = cutFreq.clip(1,200); 17 | in = LeakDC.ar( in, (-2pi * (cutFreq/SampleRate.ir)).exp ); 18 | UOut.ar( 0, in ); 19 | }) 20 | .category_( \filter ) 21 | .setSpec( \cutFreq, [1,200,\exp,1,20].asSpec); -------------------------------------------------------------------------------- /UMapDefs/p_post.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \p_post 3 | 4 | Creates an pattern UMap for posting values in the post window. 5 | 6 | input: value or UMap to post 7 | 8 | The 'input' arg ranges is mapped to that of the parameter to which the UMap is connected 9 | 10 | -- 11 | this is an UMapDef definition file 12 | part of the Unit lib default UMapDefs set 13 | */ 14 | 15 | UPatDef( \p_post, { |unit, input = 0| 16 | { 17 | loop { input.next.postln.yield }; 18 | }.r 19 | }) 20 | .setSpec( \input, UAdaptSpec() ) 21 | .canUseUMapFunc_({ |unit, key, umapdef| unit.isKindOf( UPattern ).not && { UAdaptSpec().canAdapt( unit.getSpec( key ) ) } }) 22 | .useMappedArgs_( false ) 23 | .mappedArgs_([ \input ]) 24 | .category_( 'pattern_utility' ); -------------------------------------------------------------------------------- /UnitDefs/highPass.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \highPass 3 | 4 | A resonant high-pass filter 5 | 6 | freq: cutoff frequency. 7 | rq: the reciprocal of Q. bandwidth / cutoffFreq 8 | 9 | -- 10 | this is an Udef definition file 11 | part of the Unit lib default Udefs set 12 | */ 13 | 14 | Udef( \highPass, { |freq = 440, rq = 1| 15 | var in; 16 | in = UIn.ar(0,1); 17 | in = BHiPass.ar( in, freq.clip(20,20000), rq ); 18 | UOut.ar( 0, in ); 19 | }) 20 | .category_( \private ) 21 | .setSpec( \freq, \freq.asSpec ) 22 | .setSpec( \rq, [ 0.01, 10, \exp, 0, 1 ].asSpec ) 23 | .uchainInitFunc_({ |unit| 24 | var args; 25 | if( unit.def.category == \private ) { 26 | unit.defName = \filter; 27 | unit.set( \type, \highPass ); 28 | }; 29 | }); -------------------------------------------------------------------------------- /UnitDefs/privateIn.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \privateIn 3 | 4 | Read sound from a private audio bus. A private bus in Unit-Lib is a bus that is not used by hardware, internal UChain or aux i/o. 5 | 6 | bus: the bus that you want to use to read audio from. 7 | numChannels: number of channels (*). 8 | 9 | (*) only the following numbers of channels are allowed: 10 | [1,2,3,4,5,6,7,8,9,10,12,16,24,25,32,36,48,49,64] 11 | 12 | -- 13 | this is an Udef definition file 14 | part of the Unit lib default Udefs set 15 | */ 16 | 17 | MultiChannelUdef( \privateIn, { |bus = 0| 18 | var input; 19 | input = UPrivateIn.ar( bus, Udef.numChannels ); 20 | UOut.ar( 0, input ); 21 | }, category: \private ).setSpec( \bus, PositiveIntegerSpec(0,0,inf) ); 22 | 23 | -------------------------------------------------------------------------------- /UnitDefs/crackle.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \crackle 3 | 4 | A noise generator based on a chaotic function. 5 | 6 | chaosParam: value between 1 and 2; higher values produce more crackling 7 | amp: amplitude (0-1) of the noise 8 | seed: random seed (positive whole number). The same seed will always result in exactly the same noise on any computer. If you want decorrelated noise from multiple sources, change the seed on each source to a different number. 9 | 10 | -- 11 | this is an Udef definition file 12 | part of the Unit lib default Udefs set 13 | */ 14 | 15 | Udef( \crackle, { |chaosParam = 1.5, amp = 0.1| 16 | URandSeed.ir(); 17 | UMixOut.ar( 0, Crackle.ar( chaosParam, amp ), 0, true ) 18 | } ).category_( \noise ) 19 | .setDefault( \seed, 12345 ) -------------------------------------------------------------------------------- /UMapDefs/crossfade.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \crossfade 3 | 4 | Creates an UMap for linear crossfading between two values (or other UMaps) 5 | 6 | a: the first value 7 | b: the second value 8 | crossfade: (0-1) the crossfading position (a to b) 9 | 10 | The 'a' and 'b' arg ranges are mapped to that of the parameter to which the UMap is connected. 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the Unit lib default UMapDefs set 15 | */ 16 | 17 | HybridUMapDef( \crossfade, { |a = 0.0, b = 1.0, crossfade = 0.5| 18 | UMapOut.kr( (a * (1-crossfade)) + (b * crossfade) ); 19 | }, { |unit, a = 0.0, b = 1.0, crossfade = 0.5| 20 | (a * (1-crossfade)) + (b * crossfade) 21 | }) 22 | .category_( 'selection' ) 23 | .mappedArgs_( [ \a, \b ] ); -------------------------------------------------------------------------------- /UnitDefs/grayNoise.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \grayNoise 3 | 4 | Generates noise which results from flipping random bits in a word. This type of noise has a high RMS level relative to its peak to peak level. The spectrum is emphasized towards lower frequencies. 5 | 6 | amp: amplitude (0-1) of the noise 7 | seed: random seed (positive whole number). The same seed will always result in exactly the same noise on any computer. If you want decorrelated noise from multiple sources, change the seed on each source to a different number. 8 | 9 | -- 10 | this is an Udef definition file 11 | part of the Unit lib default Udefs set 12 | */ 13 | 14 | Udef( \grayNoise, { |amp = 0.1| 15 | URandSeed.ir(); 16 | UMixOut.ar( 0, GrayNoise.ar * amp, 0, true ) 17 | } ).category_( \noise ) -------------------------------------------------------------------------------- /Classes/Extensions/extSynthDef-justWriteDefFile.sc: -------------------------------------------------------------------------------- 1 | + SynthDef { 2 | justWriteDefFile { arg dir, overwrite = (true); 3 | super.writeDefFile(name, dir, overwrite); 4 | } 5 | 6 | uWriteDefFile { arg dir, overwrite = (true), makeSynthDesc = (false); 7 | if( makeSynthDesc ) { 8 | this.writeDefFile(dir, overwrite); 9 | } { 10 | super.writeDefFile(name, dir, overwrite); 11 | }; 12 | } 13 | 14 | uLoad { arg server, completionMsg, dir(synthDefDir), makeSynthDesc = (false); 15 | server = server ? Server.default; 16 | dir = dir ? synthDefDir; 17 | this.uWriteDefFile( dir, makeSynthDesc: makeSynthDesc ); 18 | server.asCollection.do({ |srv| 19 | srv.sendMsg("/d_load", dir ++ name ++ ".scsyndef", completionMsg) 20 | }); 21 | } 22 | 23 | } 24 | 25 | -------------------------------------------------------------------------------- /Examples/UMap example.scd: -------------------------------------------------------------------------------- 1 | 2 | x = UChain( \sine, \output ); 3 | 4 | x[0].freq = UMap( \envelope, [ \env, Env([0.5,0.75,0.25],[2,3]) ] ); 5 | 6 | x[0].freq = UMap( \line, [ \range, [440,880], \duration, 4 ] ); 7 | 8 | x.prepareAndStart; 9 | x.release; 10 | x.gui; 11 | 12 | ( 13 | UMapDef( \mapkr, { |bus = 0, range = #[0.0,1.0]| 14 | var sig; 15 | sig = In.kr(bus + UIn.firstControlBus); 16 | sig = sig.linlin(0,1,*range); 17 | UMapOut.kr(sig); 18 | }); 19 | 20 | Udef( \lfo, { |freq = 2, amp = 1| 21 | var sig; 22 | sig = SinOsc.kr(freq, 0, amp).range(0,1); 23 | UOut.kr(0,sig); 24 | }).setSpec( \freq, FreqSpec(0.01,100) ); 25 | ) 26 | 27 | y = UChain( \lfo, \sine, \output ); 28 | y[1].freq = UMap( \mapkr, [ \range, [0.5,0.7]]); 29 | 30 | y.prepareAndStart; 31 | y.release; -------------------------------------------------------------------------------- /UnitDefs/default.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \default 3 | 4 | The SuperCollider default sound. 5 | 6 | freq: frequency (Hz) of the bell 7 | amp: amplitude (0-1) 8 | seed: random seed (positive whole number). The same seed will always result in exactly the same signal on any computer. 9 | 10 | -- 11 | this is an Udef definition file 12 | part of the Unit lib default Udefs set 13 | */ 14 | 15 | Udef(\default,{ |freq = 440, amp = 0.1| 16 | var z; 17 | URandSeed.ir(); // always the same sound 18 | z = LPF.ar( 19 | Mix(VarSaw.ar(freq + [0, Rand(-0.4,0.0), Rand(0.0,0.4)], 0, 0.3, 0.3)), 20 | XLine.kr(Rand(4000,5000), Rand(2500,3200), 1) 21 | ) * Linen.kr(1, 0.01, 0.7, 0.3, 0); 22 | 23 | UMixOut.ar(0, z * amp, 0, true ); 24 | 25 | }).category_( \synthesis ) 26 | .setSpec( \freq, FreqSpec() ) -------------------------------------------------------------------------------- /UnitDefs/formlet.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \formlet 3 | 4 | An FOF-like formant filter. 5 | 6 | freq: frequency. 7 | attackTime: attack time in seconds 8 | decayTime: decay time in seconds 9 | dry: level of unprocessed sound 10 | 11 | -- 12 | this is an Udef definition file 13 | part of the Unit lib default Udefs set 14 | */ 15 | 16 | Udef( \formlet, { |freq = 440, attackTime = 0.05, decayTime = 0.1, dry = 0| 17 | var in; 18 | in = UIn.ar(0,1); 19 | in = Formlet.ar( in, freq.clip(20,20000), attackTime, decayTime ) + (in * dry); 20 | UOut.ar( 0, in ); 21 | }) 22 | .category_( \filter ) 23 | .setSpec( \freq, FreqSpec( 20, 20000 )) 24 | .setSpec( \attackTime, [ 0.01, 1, \exp, 0, 0.1 ].asSpec ) 25 | .setSpec( \decayTime, [ 0.01, 1, \exp, 0, 0.1 ].asSpec ) 26 | .setSpec( \dry, \amp.asSpec ); -------------------------------------------------------------------------------- /UMapDefs/gate.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \gate 3 | 4 | This UMap implements a gating process. It allows a modulating input value to pass when gate is on, otherwise holds last value. 5 | 6 | value: the value or UMap to sample 7 | gate: if true (on), the signal is passed through, if false the signal is kept at the last value 8 | the value arg range is mapped to that of the parameter to which the UMap is connected. 9 | 10 | -- 11 | this is an UMapDef definition file 12 | part of the Unit lib default UMapDefs set 13 | */ 14 | 15 | UMapDef( \gate, { 16 | var value, gate, output; 17 | value = \value.kr(0.0); 18 | gate = \gate.kr( 1 ); 19 | output = Gate.kr( value, gate); 20 | UMapOut.kr( output ); 21 | }) 22 | .mappedArgs_([ \value ]) 23 | .setSpec( \gate, BoolSpec( true ) ) 24 | .category_( 'filter' ) -------------------------------------------------------------------------------- /UnitDefs/pinkNoise.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \pinkNoise 3 | 4 | A pink noise generator. Generates noise whose spectrum falls off in power by 3 dB per octave. This gives equal power over the span of each octave. This version gives 8 octaves of pink noise. 5 | http://en.wikipedia.org/wiki/Pink_noise 6 | 7 | amp: amplitude (0-1) of the noise 8 | seed: random seed (positive whole number). The same seed will always result in exactly the same noise on any computer. If you want decorrelated noise from multiple sources, change the seed on each source to a different number. 9 | 10 | -- 11 | this is an Udef definition file 12 | part of the Unit lib default Udefs set 13 | */ 14 | 15 | Udef( \pinkNoise, { |amp = 0.1| 16 | URandSeed.ir(); 17 | UMixOut.ar( 0, PinkNoise.ar * amp, 0, true ) 18 | } ).category_( \noise ) -------------------------------------------------------------------------------- /UMapDefs/sustain_time.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \sustain_time 3 | 4 | This is the standard UMap for UPattern. The UMap passes on the sustain and timeToNext values to the UPattern engine. 5 | 6 | sustain: sustain of pattern event (in seconds) 7 | timeToNext: time to next pattern event (in seconds) 8 | 9 | -- 10 | this is an UMapDef definition file 11 | part of the Unit lib default UMapDefs set 12 | */ 13 | 14 | FuncUMapDef( \sustain_time, { |unit, sustain = 1, timeToNext = 1| 15 | [ sustain, timeToNext ] 16 | }) 17 | .category_( 'upattern' ) 18 | .valueIsMapped_( false ) 19 | .setSpec( \sustain, SMPTESpec(0,3600) ) 20 | .setSpec( \timeToNext, SMPTESpec(0.01,3600) ) 21 | .dontStoreValue_( true ) 22 | .canUseUMapFunc_({ |unit, key, umapdef| 23 | unit.getSpec( key ).isKindOf( UPatternSpec ); 24 | }) -------------------------------------------------------------------------------- /UnitDefs/bitCrusher.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \bitCrusher 3 | 4 | Introduces quantization noise to a signal by downsampling and bit-rate rounding 5 | 6 | rate: fraction of the original sampling rate. If fs == 44100; rate == 0.25 means fs becomes 11025 7 | bits: virtual number of bits (1-24), can be fractional 8 | 9 | -- 10 | this is an Udef definition file 11 | part of the Unit lib default Udefs set 12 | */ 13 | 14 | Udef( \bitCrusher, { |rate = 1.0, bits = 24| 15 | var sig; 16 | sig = UIn.ar( 0 ); 17 | sig = Gate.ar( sig, Impulse.ar( rate * SampleRate.ir ) ); 18 | sig = sig.linlin(-1,1,0,1,\none).round( 2** (bits-1).neg ).linlin(0,1,-1,1,\none); 19 | UOut.ar( 0, sig ) 20 | } ) 21 | .category_( \distortion ) 22 | .setSpec( \rate, [0, 1, 2, 0, 1].asSpec ) 23 | .setSpec( \bits, [1,24,\lin,0,24].asSpec ); -------------------------------------------------------------------------------- /UnitDefs/freqShift.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \freqShift 3 | 4 | freqShift implements single sideband amplitude modulation, also known as frequency shifting, but not to be confused with pitch shifting. Frequency shifting moves all the components of a signal by a fixed amount but does not preserve the original harmonic relationships. 5 | 6 | freq: the amount of shifting (Hz) 7 | phase: phase of the freq shift (radians) 8 | 9 | -- 10 | this is an Udef definition file 11 | part of the Unit lib default Udefs set 12 | */ 13 | 14 | Udef( \freqShift, { |freq = 0, phase = 0| 15 | var sig; 16 | sig = UIn.ar( 0, 1 ); 17 | sig = FreqShift.ar( sig, freq, phase ); 18 | UMixOut.ar(0, sig ); 19 | }) 20 | .category_( \effect ) 21 | .setSpec( \freq, [-22050,22050,\lin,0,0].asSpec ) 22 | .setSpec( \phase, AngleSpec() ); -------------------------------------------------------------------------------- /UMapDefs/function.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \function 3 | 4 | Creates an UMap that evaluates a SuperCollider function every time the UChain is started 5 | 6 | function: the function. The result of the function should be a value between 0 and 1 7 | value: the result of the function (for display only) 8 | 9 | The 'value' arg range is mapped to that of the parameter to which the UMap is connected 10 | 11 | -- 12 | this is an UMapDef definition file 13 | part of the Unit lib default UMapDefs set 14 | */ 15 | 16 | FuncUMapDef( \function, { |unit, function| 17 | function.value( unit ) ? 0; 18 | }) 19 | .setDefault( \function, { |unit| 20 | // result shoud be between 0 and 1 21 | // and will be mapped to the output spec 22 | 1.0.rand; 23 | } ) 24 | .setSpec( \function, CodeSpec() ) 25 | .category_( 'function' ) -------------------------------------------------------------------------------- /UMapDefs/slew.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \slew 3 | 4 | An UMap that limits the speed of value changes 5 | 6 | value: the value upon which the lag is applied (this can be another UMap as well) 7 | timeUp: the time it takes to move upwards across the whole range 8 | timeDown: the time it takes to move downwards across the whole range 9 | 10 | The value arg range is mapped to that of the parameter to which the UMap is connected. 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the Unit lib default UMapDefs set 15 | */ 16 | 17 | UMapDef( \slew, { |value = 0.0, timeUp = 0.0, timeDown = 0.0| 18 | UMapOut.kr( Slew.kr( value, 1/timeUp, 1/timeDown )); 19 | }) 20 | .setSpec( \timeUp, [0,10,\lin].asSpec ) 21 | .setSpec( \timeDown, [0,10,\lin].asSpec ) 22 | .mappedArgs_([ \value ]) 23 | .category_( 'filter' ) -------------------------------------------------------------------------------- /UnitDefs/bandStop.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \bandStop 3 | 4 | A band-stop filter 5 | 6 | freq: center frequency. 7 | bw: the bandwidth in octaves between -3 dB frequencies. 8 | 9 | -- 10 | this is an Udef definition file 11 | part of the Unit lib default Udefs set 12 | */ 13 | 14 | Udef( \bandStop, { |freq = 440, bw = 1| 15 | var in; 16 | in = UIn.ar(0,1); 17 | in = BBandStop.ar( in, freq.clip(20,20000), bw ); 18 | UOut.ar( 0, in ); 19 | }) 20 | .category_( \private ) 21 | .setSpec( \freq, \freq.asSpec ) 22 | .setSpec( \bw, [ 0.01, 10, \exp, 0, 1 ].asSpec ) 23 | .uchainInitFunc_({ |unit| 24 | var args; 25 | if( unit.def.category == \private ) { 26 | args = [ \bw, unit.get( \bw ) ]; 27 | unit.defName = \filter; 28 | unit.set( \type, \bandStop ); 29 | unit.set( *args ); 30 | }; 31 | }); -------------------------------------------------------------------------------- /UnitDefs/formant.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \formant 3 | 4 | A formant generator. Generates a set of harmonics around a formant frequency at a given fundamental frequency. 5 | 6 | freq: frequency (Hz) 7 | fromant: frequency of the formant (Hz) 8 | bw: bandwidth of the formant as multiplier of the freq 9 | amp: amplitude (0-1) 10 | 11 | -- 12 | this is an Udef definition file 13 | part of the Unit lib default Udefs set 14 | */ 15 | 16 | Udef( \formant, { |freq = 440, formant = 1760, bw = 2, amp = 0.1| 17 | var sig; 18 | sig = Formant.ar( freq, formant, (bw * freq), amp ); 19 | UMixOut.ar( 0, sig, 0, true ) 20 | } ).category_( \oscillator ) 21 | .setSpec( \freq, FreqSpec( 2, 20000 ) ) 22 | .setSpec( \formant, FreqSpec( 2, 20000 ) ) 23 | .setSpec( \bw, [1, 20, \exp ].asSpec ) 24 | .setSpec( \lag, [0,1,\lin].asSpec ); -------------------------------------------------------------------------------- /UnitDefs/dust.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \dust 3 | 4 | A random impulse generator. Generates impulses of random amplitude (positive and negative) with random time intervals in between. 5 | 6 | density: the average amount of impulses per second 7 | amp: maximum amplitude (0-1) of the pulses 8 | seed: random seed (positive whole number). The same seed will always result in exactly the signal on any computer. If you want decorrelated noise from multiple sources, change the seed on each source to a different number. 9 | 10 | -- 11 | this is an Udef definition file 12 | part of the Unit lib default Udefs set 13 | */ 14 | 15 | Udef( \dust, { |density = 100, amp = 0.1| 16 | URandSeed.ir(); 17 | UMixOut.ar( 0, Dust2.ar(density) * amp, 0, true ) 18 | } ).category_( \noise ) 19 | .setSpec( \density, [ 1, 10000, \exp, 1, 100 ].asSpec ) -------------------------------------------------------------------------------- /UMapDefs/p_alternate.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \p_alternate 3 | 4 | Creates an pattern UMap that switches back and forth between two values. 5 | 6 | a: first value 7 | b: second value 8 | 9 | The 'a' and 'b' arg ranges are mapped to that of the parameter to which the UMap is connected 10 | 11 | -- 12 | this is an UMapDef definition file 13 | part of the Unit lib default UMapDefs set 14 | */ 15 | 16 | UPatDef( \p_alternate, { |unit, a = 0.0, b = 1.0| 17 | { 18 | inf.do { |i| 19 | [a,b].wrapAt( i ).next.yield; 20 | }; 21 | }.r; 22 | }).mappedArgs_([\a, \b]) 23 | .useMappedArgs_( false ) 24 | .canUseUMapFunc_({ |unit, key, umapdef| unit.isKindOf( UPattern ).not && { UAdaptSpec().canAdapt( unit.getSpec( key ) ) } }) 25 | .setSpec( \a, UAdaptSpec() ) 26 | .setSpec( \b, UAdaptSpec() ) 27 | .category_( 'pattern_selection' ); 28 | -------------------------------------------------------------------------------- /UMapDefs/impulse.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \impulse 3 | 4 | Creates an UMap for producing single-frame impulses 5 | 6 | freq: the frequency of the impulses wave 7 | phase: the initial phase (0-1) of the pulse wave 8 | range: the output range 9 | 10 | The 'range' arg range is mapped to that of the parameter to which the UMap is connected. 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the Unit lib default UMapDefs set 15 | */ 16 | 17 | UMapDef( \impulse, { |freq = 2, phase = 0, range = #[0.0,1.0]| 18 | var sig; 19 | sig = Impulse.ar(freq, (phase + (\u_startPos.kr(0) * freq)).wrap(0,1)).range(*range); 20 | sig = T2K.kr( sig ); 21 | UMapOut.kr(sig); 22 | }) 23 | .setSpec( \phase, [0,1,\lin,0,0] ) 24 | .setSpec( \freq, FreqSpec(0.001,300, default: 2) ) 25 | .mappedArgs_( [ \range ] ) 26 | .category_( 'trigger' ) 27 | -------------------------------------------------------------------------------- /UMapDefs/lfo_sine.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \lfo_sine 3 | 4 | Creates an UMap with a low frequency sine wave oscillator. 5 | 6 | freq: the frequency of the sine wave 7 | phase: (-pi - pi) the start phase of the sine wave (can be modulated) 8 | range: the output range 9 | 10 | The 'range' arg range is mapped to that of the parameter to which the UMap is connected. 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the Unit lib default UMapDefs set 15 | */ 16 | 17 | UMapDef( \lfo_sine, { |freq = 2, phase = 0, range = #[0.0,1.0]| 18 | var sig; 19 | sig = SinOsc.kr(freq, phase + DC.kr(\u_startPos.kr(0) * freq * 2pi).wrap(0,2pi)).range(*range); 20 | UMapOut.kr(sig); 21 | }) 22 | .setSpec( \phase, AngleSpec() ) 23 | .setSpec( \freq, FreqSpec(0.001,300, default: 2) ) 24 | .mappedArgs_( [ \range ] ) 25 | .category_( 'lfo' ) 26 | -------------------------------------------------------------------------------- /Classes/Extensions/extString-uNamemidi.sc: -------------------------------------------------------------------------------- 1 | + String { 2 | 3 | // bypass cents and alt methods, causes crashes on post 3.14.0-dev 4 | uNamemidi { arg cents; 5 | // format "[notename][bb/b/#/x][octave(-9/9)]" 6 | // examples: "C#-2" , "Gbb7" 7 | // min notenr = -84 (C-9) 8 | // max notenr = 145 (Bx9) 9 | var notename, addition, octave = 0; 10 | cents = cents ? 0; 11 | ^(this.notesDict.at(this.getNote) + 24 12 | + this.uGetAlt + (this.getOctave * 12) + (cents * 0.01) ); 13 | } 14 | 15 | uNamecps { arg cents; 16 | ^this.uNamemidi( cents ).midicps; 17 | } 18 | 19 | uGetAlt { 20 | var addition = 0; 21 | this.do({ |item| 22 | if (item == $#) {addition = addition + 1}; 23 | if (item == $b) {addition = addition - 1}; 24 | if (item == $x) {addition = addition + 2}; 25 | }); 26 | ^addition 27 | } 28 | } -------------------------------------------------------------------------------- /UnitDefs/privateOut.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \privateOut 3 | 4 | Write sound to a private audio bus. A private bus in Unit-Lib is a bus that is not used by hardware, internal UChain or aux i/o. 5 | 6 | bus: the bus that you want to use to read audio from. Starts counting from 0; 0 means the first input of your audio device. 7 | numChannels: number of channels (*). 8 | 9 | (*) only the following numbers of channels are allowed: 10 | [1,2,3,4,5,6,7,8,9,10,12,16,24,25,32,36,48,49,64] 11 | 12 | -- 13 | this is an Udef definition file 14 | part of the Unit lib default Udefs set 15 | */ 16 | 17 | MultiChannelUdef( \privateOut, { |bus = 0| 18 | var sig; 19 | sig = UIn.ar(0, Udef.numChannels ); 20 | UPrivateOut.ar( bus, sig * UEnv.kr( extraSilence: 0.2, useGlobalGain: 0 ) ); 21 | }, category: \private ).setSpec( \bus, PositiveIntegerSpec(0,0,inf) ); -------------------------------------------------------------------------------- /UnitDefs/impulse.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \impulse 3 | 4 | A non-bandlimited impulse generator. Outputs single sample impulses. 5 | 6 | freq: frequency (Hz) 7 | scale: a multiplier for the frequency (if scale is 0, only a single impulse is produced) 8 | numSamples: width of the impulse in number of samples (1-100) 9 | amp: amplitude (0-1) 10 | 11 | -- 12 | this is an Udef definition file 13 | part of the Unit lib default Udefs set 14 | */ 15 | 16 | Udef( \impulse, { |freq = 440, scale = 1, numSamples = 1, amp = 0.1| 17 | var sig; 18 | sig = Impulse.ar( freq * scale ) * amp; 19 | sig = Trig.ar( sig, numSamples / SampleRate.ir ); 20 | UMixOut.ar( 0, sig, 0, true ) 21 | } ).category_( \oscillator ) 22 | .setSpec( \freq, FreqSpec( 2, 20000 ) ) 23 | .setSpec( \scale, [0,2,\lin,0.125,1].asSpec ) 24 | .setSpec( \numSamples, [1,100,\lin,1,1].asSpec ); -------------------------------------------------------------------------------- /UnitDefs/simpleEQ.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \simpleEQ 3 | 4 | This is a filter with a lowshelf filter, 1 parametric filter and a hihgshelf filter. 5 | 6 | Clicking the [edit] button in UChainGUI opens the EQ Edit window. You can set the filter by dragging in the window, setting the values in combination with the popup menu or choosing from the presets. 7 | 8 | lowMidHi: an UEQ object, holding all settings for the eq. 9 | 10 | -- 11 | this is an Udef definition file 12 | part of the Unit lib default Udefs set 13 | */ 14 | 15 | EQdef( \low, BLowShelf, \mid, BPeakEQ, \hi, BHiShelf ) 16 | .defaultSetting_([ 17 | [ 250, 1, 0 ], 18 | [ 1000, 1, 0 ], 19 | [ 6000, 1, 0 ] 20 | ]) 21 | .name_( \simpleEQ ); 22 | 23 | Udef( \simpleEQ, { 24 | var in; 25 | in = UIn.ar( 0, 1 ); 26 | UOut.ar(0, UEQ.ar( in, \lowMidHi, \simpleEQ ) ); 27 | }) 28 | .category_( 'eq' ); 29 | -------------------------------------------------------------------------------- /UMapDefs/legato_time.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \legato_time 3 | 4 | This UMap is intended for use on the 'pattern' value of an UPattern. It allows the sustain value of the pattern to be set relative to the timeToNext. 5 | 6 | legato: sustain time as multiplier of timeToNext (0-8) 7 | timeToNext: time to next pattern event (in seconds) 8 | 9 | -- 10 | this is an UMapDef definition file 11 | part of the Unit lib default UMapDefs set 12 | */ 13 | 14 | FuncUMapDef( \legato_time, { |unit, legato = 1, timeToNext = 1| 15 | [ legato * timeToNext, timeToNext ] 16 | }) 17 | .category_( 'upattern' ) 18 | .valueIsMapped_( false ) 19 | .mappedArgs_( [] ) 20 | .setSpec( \legato, [0,10,\lin,0,1].asSpec ) 21 | .setSpec( \timeToNext, SMPTESpec(0.01,3600) ) 22 | .dontStoreValue_( true ) 23 | .canUseUMapFunc_({ |unit, key, umapdef| 24 | unit.getSpec( key ).isKindOf( UPatternSpec ); 25 | }) -------------------------------------------------------------------------------- /UnitDefs/selectChannel.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \selectChannel 3 | 4 | select a single channel to multiple inputs, with optional crossfade time. 5 | 6 | index: the index of the channel (0 - numChannels-1) 7 | fadeTime: a crossfade time in seconds (0 - 1) 8 | numChannels: number of input channels (*). 9 | 10 | (*) only the following numbers of channels are allowed: 11 | 2,3,4,5,6,7,8 12 | 13 | -- 14 | this is an Udef definition file 15 | part of the Unit lib default Udefs set 16 | */ 17 | 18 | MultiChannelUdef( \selectChannel, { 19 | var index; 20 | var fadeTime; 21 | var in; 22 | index = \index.ukr( 0, IntegerSpec(0, 0, Udef.numChannels - 1 ) ); 23 | fadeTime = \fadeTime.ukr( 0, 0, 1, \lin ); 24 | in = UIn.ar( 0, Udef.numChannels, true ); 25 | UOut.ar( 0, SelectCF.ar( index, in, fadeTime ) ); 26 | }, channels: [ 2,3,4,5,6,7,8,10,12,16,24,32]) 27 | .category_( \utility ) 28 | -------------------------------------------------------------------------------- /UMapDefs/envelope_map.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \envelope_map 3 | 4 | Creates an UMap for indexing an envelope. 5 | 6 | index: the index (0-1, modulatable) 7 | env: an Env or EnvM object, containing time and level values. 8 | 9 | 10 | The 'env' arg range is mapped to that of the parameter to which the UMap is connected. 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the Unit lib default UMapDefs set 15 | */ 16 | 17 | var def; 18 | 19 | def = HybridUMapDef( \envelope_map, { |index = 0.0| 20 | UMapOut.kr( UIEnvGen.kr( \env, nil, index ) ); 21 | }, { |unit, index = 0.0, env = 0| 22 | if( env.isKindOf( EnvM ) ) { 23 | env.at( index.linlin(0,1,0, env.duration) ); 24 | } { 25 | 0; 26 | }; 27 | }) 28 | .setSpec( \env, UEnvSpec( EnvM() ) ) 29 | .category_( 'convert' ) 30 | .mappedArgs_( [ \env ] ); 31 | 32 | def.udefs[1].setDefault( \env, EnvM() ); 33 | 34 | def; -------------------------------------------------------------------------------- /UMapDefs/p_coin.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \p_coin 3 | 4 | Creates an pattern UMap that chooses randomly between two values. 5 | 6 | a: first value 7 | b: second value 8 | prob: probability for second value 9 | 10 | The 'a' and 'b' arg ranges are mapped to that of the parameter to which the UMap is connected 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the Unit lib default UMapDefs set 15 | */ 16 | 17 | UPatDef( \p_coin, { |unit, a = 0.0, b = 1.0, prob = 0.5| 18 | { 19 | inf.do { |i| 20 | [a,b][ prob.next.coin.binaryValue ].next.yield; 21 | }; 22 | }.r; 23 | }).mappedArgs_([\a, \b]) 24 | .useMappedArgs_( false ) 25 | .canUseUMapFunc_({ |unit, key, umapdef| 26 | unit.isKindOf( UPattern ).not && { 27 | UAdaptSpec().canAdapt( unit.getSpec( key ) ) 28 | }; 29 | }) 30 | .setSpec( \a, UAdaptSpec() ) 31 | .setSpec( \b, UAdaptSpec() ) 32 | .category_( 'pattern_random' ); 33 | -------------------------------------------------------------------------------- /UMapDefs/lfo_pulse.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \lfo_pulse 3 | 4 | Creates an UMap with a low frequency pulse wave oscillator. 5 | 6 | freq: the frequency of the pulse wave 7 | phase: the initial phase (0-1) of the pulse wave 8 | width: the width of the pulse. 0.5 (default) creates a square wave 9 | range: the output range 10 | 11 | The 'range' arg range is mapped to that of the parameter to which the UMap is connected. 12 | 13 | -- 14 | this is an UMapDef definition file 15 | part of the Unit lib default UMapDefs set 16 | */ 17 | 18 | UMapDef( \lfo_pulse, { |freq = 2, phase = 0, width = 0.5, range = #[0.0,1.0]| 19 | var sig; 20 | sig = LFPulse.kr(freq, phase + (\u_startPos.kr(0) * freq), width).range(*range); 21 | UMapOut.kr(sig); 22 | }) 23 | .setSpec( \phase, [0,1,\lin,0,0], \init ) 24 | .setSpec( \freq, FreqSpec(0.001,300, default: 2) ) 25 | .mappedArgs_( [ \range ] ) 26 | .category_( 'lfo' ) 27 | -------------------------------------------------------------------------------- /UnitDefs/lowShelf.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \lowShelf 3 | 4 | Low Shelf filter 5 | 6 | freq: cutoff frequency. 7 | rs: the reciprocal of S. Shell boost/cut slope 8 | db: boost/cut the center frequency (in dBs). 9 | 10 | -- 11 | this is an Udef definition file 12 | part of the Unit lib default Udefs set 13 | */ 14 | 15 | Udef( \lowShelf, { |freq = 440, rs = 1, db = 0| 16 | var in; 17 | in = UIn.ar(0,1); 18 | in = BLowShelf.ar( in, freq.clip(20,20000), rs, db ); 19 | UOut.ar( 0, in ); 20 | }) 21 | .category_( \private ) 22 | .setSpec( \freq, \freq.asSpec ) 23 | .setSpec( \rs, [ 0.6, 10, \exp, 0, 1 ].asSpec ) 24 | .setSpec( \db, [-24,24,\lin].asSpec ) 25 | .uchainInitFunc_({ |unit| 26 | var args; 27 | if( unit.def.category == \private ) { 28 | args = [ \rs, unit.get( \rs ), \db, unit.get( \db ) ]; 29 | unit.defName = \filter; 30 | unit.set( \type, \lowShelf ); 31 | unit.set( *args ); 32 | }; 33 | }); -------------------------------------------------------------------------------- /UnitDefs/highShelf.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \highShelf 3 | 4 | High Shelf filter 5 | 6 | freq: cutoff frequency. 7 | rs: the reciprocal of S. Shell boost/cut slope 8 | db: boost/cut the center frequency (in dBs). 9 | 10 | -- 11 | this is an Udef definition file 12 | part of the Unit lib default Udefs set 13 | */ 14 | 15 | Udef( \highShelf, { |freq = 440, rs = 1, db = 0| 16 | var in; 17 | in = UIn.ar(0,1); 18 | in = BHiShelf.ar( in, freq.clip(20,20000), rs, db ); 19 | UOut.ar( 0, in ); 20 | }) 21 | .category_( \private ) 22 | .setSpec( \freq, \freq.asSpec ) 23 | .setSpec( \rs, [ 0.6, 10, \exp, 0, 1 ].asSpec ) 24 | .setSpec( \db, [-24,24,\lin].asSpec ) 25 | .uchainInitFunc_({ |unit| 26 | var args; 27 | if( unit.def.category == \private ) { 28 | args = [ \rs, unit.get( \rs ), \db, unit.get( \db ) ]; 29 | unit.defName = \filter; 30 | unit.set( \type, \highShelf ); 31 | unit.set( *args ); 32 | }; 33 | }); -------------------------------------------------------------------------------- /UnitDefs/soundIn.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \soundIn 3 | 4 | Read sound from a hardware audio input. 5 | 6 | bus: the bus that you want to use to read audio from. Starts counting from 0; 0 means the first input of your audio device. 7 | numChannels: number of channels (*). 8 | 9 | (*) only the following numbers of channels are allowed: 10 | 1,2,3,4,5,6,7,8,10,12,16,24,32 11 | 12 | -- 13 | this is an Udef definition file 14 | part of the Unit lib default Udefs set 15 | */ 16 | 17 | var def = MultiChannelUdef( \soundIn, { |bus = 0| 18 | var input; 19 | input = ((..Udef.numChannels - 1) + bus).collect({ |item| SoundIn.ar( item ) }); 20 | input = input.collect({ |input| 21 | input * if( bus > (NumInputBuses.ir - 1), 0, 1 ); 22 | }); 23 | UOut.ar( 0, input ); 24 | } ) 25 | .category_( \input ); 26 | 27 | def.udefs.do({ |def| 28 | def.setSpec( \bus, HardwareBusSpec(\input, def.name ) ); 29 | }); 30 | 31 | def -------------------------------------------------------------------------------- /UMapDefs/uchain_track.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \uchain_track 3 | 4 | Creates an UMap that passes on the track number of the current UChain. 5 | 6 | max: maximum track number (scales to range upper value) 7 | range: range to which the track number will be scaled (track 0 = lower value) 8 | 9 | The 'range' arg range is mapped to that of the parameter to which the UMap is connected 10 | -- 11 | this is an UMapDef definition file 12 | part of the Unit lib default UMapDefs set 13 | */ 14 | 15 | FuncUMapDef( \uchain_track, { |unit, max = 16, range = #[0.0,1.0]| 16 | var chain, out; 17 | chain = UChain.nowPreparingChain ?? { UPattern.nowCallingPattern }; 18 | out = if( chain.notNil ) { 19 | chain.track; 20 | } { 21 | 0; 22 | }; 23 | out.linlin(0,max,*range); 24 | }) 25 | .category_( 'uchain_info' ) 26 | .mappedArgs_( [ \range ] ) 27 | .setSpec( \max, IntegerSpec(16,0, inf) ) 28 | .setSpec( \value, private: true ); -------------------------------------------------------------------------------- /UMapDefs/upattern_duration.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \upattern_duration 3 | 4 | Creates an UMap that passes on the duration of the current UPattern. It can only be applied to SMPTESpec arguments (i.e. time arguments). 5 | 6 | factor: a multiplication factor for the returned duration (0.1-10) 7 | 8 | -- 9 | this is an UMapDef definition file 10 | part of the Unit lib default UMapDefs set 11 | */ 12 | 13 | FuncUMapDef( \upattern_duration, { |unit, factor = 1.0| 14 | (UPattern.duration ? 1) * factor; 15 | }) 16 | .category_( 'uchain_info' ) 17 | .valueIsMapped_( false ) 18 | .mappedArgs_( [] ) 19 | .setSpec( \factor, [ 0, 10, 1.calcCurve(0,10) ].asSpec ) 20 | .setSpec( \value, DisplaySpec( SMPTESpec(), _.asSMPTEString(1000) ), private: true ) 21 | .canUseUMapFunc_({ |unit, key, umapdef| 22 | var spec; 23 | spec = unit.getSpec( key ); 24 | [ SMPTESpec, UAdaptSpec ].any({ |item| spec.isKindOf( item ) }); 25 | }) -------------------------------------------------------------------------------- /Examples/UMod example.scd: -------------------------------------------------------------------------------- 1 | ( 2 | UModDef( \sine_lfo, ( 3 | start: { |mod, unit, key, startPos = 0| 4 | var func, time = startPos; 5 | func = { |time = 0| 6 | time.sin.linlin(-1,1, *mod.get( \range ) ); 7 | }; 8 | ~lfo.stop; 9 | unit.mapSet( key, func.value( time ) ); 10 | ~lfo = { 11 | inf.do({ 12 | mod.get(\res).wait; 13 | time = time + (mod.get(\res) * mod.get( \speed )); 14 | unit.mapSet( key, func.value( time ) ); 15 | }); 16 | }.fork; 17 | }, 18 | dispose: { |mod, unit| 19 | if( unit.isPlaying.not ) { 20 | ~lfo.stop; 21 | ~lfo = nil; 22 | }; 23 | } 24 | ), [ 25 | [ \speed, 1, [ 0.1, 20, \exp ].asSpec], 26 | [ \res, 0.05, [0.01,0.2,\exp].asSpec ], 27 | [ \range, [0,1], RangeSpec( 0,1 ) ] 28 | ] 29 | ); 30 | ) 31 | 32 | a = UScore( UChain([ 'sine', [ 'lag', 0.1 ], UMod( \freq, \sine_lfo ) ], 'output')); 33 | a.gui; 34 | 35 | UGUI( unit: a[0][0].mod ); 36 | -------------------------------------------------------------------------------- /UMapDefs/uchain_duration.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \uchain_duration 3 | 4 | Creates an UMap that passes on the duration of the current UChain. If applied in a 'pattern' arg of an UPattern, the duration of the UPattern is used instead. 5 | 6 | factor: a multiplication factor for the returned duration (0.1-10) 7 | 8 | -- 9 | this is an UMapDef definition file 10 | part of the Unit lib default UMapDefs set 11 | */ 12 | 13 | FuncUMapDef( \uchain_duration, { |unit, factor = 1| 14 | (UChain.duration ? 1) * factor 15 | }) 16 | .category_( 'uchain_info' ) 17 | .valueIsMapped_( false ) 18 | .mappedArgs_( [] ) 19 | .setSpec( \factor, [ 0, 10, 1.calcCurve(0,10) ].asSpec ) 20 | .setSpec( \value, DisplaySpec( SMPTESpec(), _.asSMPTEString(1000) ), private: true ) 21 | .canUseUMapFunc_({ |unit, key, umapdef| 22 | var spec; 23 | spec = unit.getSpec( key ); 24 | [ SMPTESpec, UAdaptSpec ].any({ |item| spec.isKindOf( item ) }); 25 | }) -------------------------------------------------------------------------------- /UnitDefs/bandPass.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \bandPass 3 | 4 | A band-pass filter 5 | 6 | freq: center frequency. 7 | bw: the bandwidth in octaves between -3 dB frequencies. 8 | 9 | -- 10 | this is an Udef definition file 11 | part of the Unit lib default Udefs set 12 | */ 13 | 14 | Udef( \bandPass, { |freq = 440, bw = 1, makeUp = 0.0| 15 | var in; 16 | in = UIn.ar(0,1); 17 | in = BBandPass.ar( in, freq.clip(20,20000), bw ); 18 | in = in * DC.kr(1).blend( bw.explin(0.01,10,30,0,\none).dbamp, makeUp ); 19 | UOut.ar( 0, in ); 20 | }) 21 | .category_( \private ) 22 | .setSpec( \freq, \freq.asSpec ) 23 | .setSpec( \bw, [ 0.001, 10, \exp, 0, 1 ].asSpec ) 24 | .uchainInitFunc_({ |unit| 25 | var args; 26 | if( unit.def.category == \private ) { 27 | args = [ \bw, unit.get( \bw ), \makeUp, unit.get( \makeUp ) ]; 28 | unit.defName = \filter; 29 | unit.set( \type, \bandPass ); 30 | unit.set( *args ); 31 | }; 32 | }); -------------------------------------------------------------------------------- /UnitDefs/fullEQ.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \fullEQ 3 | 4 | This is a filter with a lowshelf filter, 3 parametric filters and a hihgshelf filter. 5 | 6 | Clicking the [edit] button in UChainGUI opens the EQ Edit window. You can set the filter by dragging in the window, setting the values in combination with the popup menu or choosing from the presets. The eq algorithm (EQdef) is the same as that of the global Unit lib EQ (UGlobalEQ), and it shares presets with it. 7 | 8 | eq: an UEQ object, holding all settings for the eq. 9 | numChannels: number of channels (*). 10 | 11 | (*) only the following numbers of channels are allowed: 12 | 1,2,3,4,5,6,7,8,10,12,16,24,32 13 | 14 | -- 15 | this is an Udef definition file 16 | part of the Unit lib default Udefs set 17 | */ 18 | 19 | MultiChannelUdef( \fullEQ, { 20 | var in; 21 | in = UIn.ar( 0, Udef.numChannels ); 22 | UOut.ar(0, UEQ.ar( in, \eq, \default ) ); 23 | }) 24 | .category_( 'eq' ); -------------------------------------------------------------------------------- /UMapDefs/sample_and_hold.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \sample_and_hold 3 | 4 | This UMap implements sample-and-hold process. Every time a trigger is received the output value becomes the input value of that moment. 5 | 6 | value: the value or UMap to sample 7 | trigger: the trigger 8 | time: a linear lag time to move to the new value 9 | 10 | the value arg range is mapped to that of the parameter to which the UMap is connected. 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the Unit lib default UMapDefs set 15 | */ 16 | 17 | UMapDef( \sample_and_hold, { 18 | var value, trigger, output; 19 | value = \value.kr(0.0); 20 | trigger = \trigger.tr; 21 | output = Select.kr( Peak.kr( trigger ), [ DC.kr( value ), Latch.kr( value, trigger ) ] ); 22 | output = output.varlag( \time.kr(0.0) ); 23 | UMapOut.kr( output ); 24 | }) 25 | .mappedArgs_([ \value ]) 26 | .setSpec( \trigger, TriggerSpec() ) 27 | .category_( 'trigger_to_value' ) -------------------------------------------------------------------------------- /UMapDefs/upattern_sustain.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \upattern_sustain 3 | 4 | Creates an UMap that passes the current sustain time of the current UPattern, if available. It can only be applied to SMPTESpec arguments (i.e. time arguments). 5 | 6 | factor: a multiplication factor for the returned duration (0.1-10) 7 | 8 | -- 9 | this is an UMapDef definition file 10 | part of the Unit lib default UMapDefs set 11 | */ 12 | 13 | FuncUMapDef( \upattern_sustain, { |unit, factor = 1.0| 14 | (UPattern.currentSustain ? 1) * factor; 15 | }) 16 | .category_( 'uchain_info' ) 17 | .valueIsMapped_( false ) 18 | .mappedArgs_( [] ) 19 | .setSpec( \factor, [ 0, 10, 1.calcCurve(0,10) ].asSpec ) 20 | .setSpec( \value, DisplaySpec( SMPTESpec(), _.asSMPTEString(1000) ), private: true ) 21 | .canUseUMapFunc_({ |unit, key, umapdef| 22 | var spec; 23 | spec = unit.getSpec( key ); 24 | [ SMPTESpec, UAdaptSpec ].any({ |item| spec.isKindOf( item ) }); 25 | }) -------------------------------------------------------------------------------- /UnitDefs/limiter.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \limiter 3 | 4 | A lookahead transparent limiter. 5 | 6 | limit: in dB. 7 | lookAhead: lookahead time in seconds. The signal will be delayed by this amount of time, to give the limiter the chance to eliminate peaks from it. Lower lookahead times will result in faster response, but also more side-effects. lookAhead is an 'init' parameter (recognized by the "(i)" in the UChain editor), which means changed values only become effective when the event is started the next time. 8 | 9 | -- 10 | this is an Udef definition file 11 | part of the Unit lib default Udefs set 12 | */ 13 | 14 | Udef( \limiter, { |limit = 0, lookAhead = 0.01| 15 | var in; 16 | in = UIn.ar(0,1); 17 | in = Limiter.ar( in, limit.dbamp, lookAhead ); 18 | UOut.ar( 0, in ); 19 | }) 20 | .category_( \dynamics ) 21 | .setSpec( \limit, [ -60, 0, \lin, 1, 0].asSpec ) 22 | .setSpec( \lookAhead, [ 0.001, 0.1, \exp, 0, 0.01].asSpec, \init ); -------------------------------------------------------------------------------- /UMapDefs/toggle_ff.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \toggle_ff 3 | 4 | This UMap implements a toggle flip-flop mechanism. Each time a trigger is received the UMap switches to the other value. 5 | 6 | trigger: the trigger 7 | lag: a linear lag time between value1 and value2 in seconds 8 | value1: the first value (or UMap) 9 | value2: the second value (or UMap) 10 | 11 | value1 and value2 arg ranges are mapped to that of the parameter to which the UMap is connected. 12 | 13 | -- 14 | this is an UMapDef definition file 15 | part of the Unit lib default UMapDefs set 16 | */ 17 | 18 | UMapDef( \toggle_ff, { 19 | var index, output; 20 | index = ToggleFF.kr( \trigger.tr ); 21 | index = Slew.kr(index, 1 / \lag.kr(0.0), 1 / \lag.kr ); 22 | output = LinSelectX.kr( index, [ \value1.kr(0.0), \value2.kr(1.0) ] ); 23 | UMapOut.kr( output ); 24 | }) 25 | .mappedArgs_([ \value1, \value2 ]) 26 | .setSpec( \trigger, TriggerSpec() ) 27 | .category_( 'trigger_to_value' ) -------------------------------------------------------------------------------- /UMapDefs/upattern_timeToNext.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \upattern_timeToNext 3 | 4 | Creates an UMap that passes the current timeToNext of the current UPattern, if available. It can only be applied to SMPTESpec arguments (i.e. time arguments). 5 | 6 | factor: a multiplication factor for the returned time (0.1-10) 7 | 8 | -- 9 | this is an UMapDef definition file 10 | part of the Unit lib default UMapDefs set 11 | */ 12 | 13 | FuncUMapDef( \upattern_timeToNext, { |unit, factor = 1.0| 14 | (UPattern.currentTimeToNext ? 1) * factor; 15 | }) 16 | .category_( 'uchain_info' ) 17 | .valueIsMapped_( false ) 18 | .mappedArgs_( [] ) 19 | .setSpec( \factor, [ 0, 10, 1.calcCurve(0,10) ].asSpec ) 20 | .setSpec( \value, DisplaySpec( SMPTESpec(), _.asSMPTEString(1000) ), private: true ) 21 | .canUseUMapFunc_({ |unit, key, umapdef| 22 | var spec; 23 | spec = unit.getSpec( key ); 24 | [ SMPTESpec, UAdaptSpec ].any({ |item| spec.isKindOf( item ) }); 25 | }) -------------------------------------------------------------------------------- /Examples/USession example.scd: -------------------------------------------------------------------------------- 1 | ( 2 | f = { 12.collect({ |i| 3 | var evt; 4 | evt = UChain(i/2,i+1,rrand(3.0,10.0),false,\sine, \output).fadeOut_(1).fadeIn_(1); 5 | evt.units[0].set(\freq,rrand(200.0,600.0) ); 6 | evt; 7 | }) }; 8 | z = UScore(*(12.collect({ |i| 9 | var evt; 10 | evt = BufSndFile("@resources/sounds/a11wlk01-44_1.aiff", 11 | rate: (i-6).midiratio, loop: [true,false].wrapAt(i) ).makeUChain 12 | .releaseSelf_(true).startTime_(i/2).track_(i).fadeOut_(1).fadeIn_(1); 13 | 14 | if( evt.duration == inf ) { 15 | evt.duration = 8; // looped events stopped by UScore 16 | }; 17 | evt; 18 | })++f.()++[ 19 | UScore(*f.()++[ 20 | UScore(*f.()) 21 | ] 22 | )])); 23 | z.cleanOverlaps; 24 | x = USession(z,UChain(\sine,\output),UChain(\sine,\output),UChain(\sine,\output),UChain(\sine,\output) 25 | ,UChainGroup(UChain([\sine,[\freq,200]],\output),UChain([\sine,[\freq,400]],\output))); 26 | y = USessionGUI(x); 27 | ) -------------------------------------------------------------------------------- /UMapDefs/start_delay.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \start_delay 3 | 4 | This is the standard UMap for UPattern. The UMap adds a delay (i.e. a silend period) to the start of an UPattern. After the delay the UPattern will start playing. 5 | 6 | delay: delay (in seconds) 7 | pattern: the sustain / timeToNext for the rest of the UPatttern (can be any UMap from the 'upattern' category) 8 | 9 | -- 10 | this is an UMapDef definition file 11 | part of the Unit lib default UMapDefs set 12 | */ 13 | 14 | FuncUMapDef( \start_delay, { |unit, delay = 0, pattern = #[1,1]| 15 | var pos = UPattern.pos; 16 | if( pos < delay ) { 17 | [ 0, delay - pos ] 18 | } { 19 | pattern; 20 | } 21 | }) 22 | .category_( 'upattern' ) 23 | .valueIsMapped_( false ) 24 | .setSpec( \delay, SMPTESpec(0,3600) ) 25 | .setSpec( \pattern, UPatternSpec() ) 26 | .dontStoreValue_( true ) 27 | .canUseUMapFunc_({ |unit, key, umapdef| 28 | unit.getSpec( key ).isKindOf( UPatternSpec ); 29 | }) -------------------------------------------------------------------------------- /UnitDefs/noiseGate.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \noiseGate 3 | 4 | A noise gate. 5 | 6 | thresh: threshold in dB 7 | att: attack time 8 | hold: hold time 9 | rel: release time 10 | hysteresis: hysteresis applied to threshold (0-1). A hysteresis value 1 (maximum) will make the gate never close agian after opening. 11 | 12 | -- 13 | this is an Udef definition file 14 | part of the Unit lib default Udefs set 15 | */ 16 | 17 | Udef( \noiseGate, { |thresh = -10, att = 0.01, hold = 0.0, rel = 0.5, hysteresis = 0.0| 18 | var in, sig, test; 19 | in = UIn.ar(0,1); 20 | thresh = thresh.dbamp; 21 | sig = Schmidt.ar( Amplitude.ar( in ), thresh * (1 - hysteresis), thresh ); 22 | sig = Slew.ar( sig, inf, 1/hold ) > 0; 23 | sig = LagUD.ar( sig, att, rel ); 24 | UOut.ar( 0, in * sig ); 25 | }) 26 | .category_( \dynamics ) 27 | .setSpec( \att, [0,1,4,0,0.01].asSpec ) 28 | .setSpec( \rel, [0,1,4,0,0.5].asSpec ) 29 | .setSpec( \thresh, [ -90, 0, \lin, 1, -10].asSpec ); -------------------------------------------------------------------------------- /UnitDefs/tremolo.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \tremolo 3 | Applies a tremolo to the amplitude of the input sound. 4 | speed: number of tremolo's per second. 5 | amount: sets the minimum and maximum of the tremolo effect. 6 | smooth: smoothen the modulator signal; 0 means square wave, 1 means sine wave, and everything in between. 7 | 8 | -- 9 | this is an Udef definition file 10 | part of the Unit lib default Udefs set 11 | */ 12 | 13 | Udef( \tremolo, { |speed = 1, phase = 0, amount = #[0.0,1.0], smooth = 1| 14 | var modsig, sig; 15 | smooth = smooth.max(1.0e-12); 16 | modsig = ((LFTri.ar( speed, phase * 2 ) / smooth) * 0.5pi).clip(-0.5pi,0.5pi); 17 | modsig = SinOsc.ar( 0, modsig ); 18 | sig = modsig.range(*amount) * UIn.ar( 0 ); 19 | UOut.ar( 0, sig ) 20 | } ) 21 | .category_( \effect ) 22 | .setSpec( \speed, [0, 100, 99.squared.log, 0, 1].asSpec ) 23 | .setSpec( \phase, [-2, 2, \lin, 0, 0, "pi"].asSpec, \init ) 24 | .setSpec( \smooth, [0,1,\lin, 0, 1] ); -------------------------------------------------------------------------------- /UMapDefs/trig_random.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \trig_random 3 | 4 | This UMap implements triggered random value generator. Every time a trigger is received the output value a random value within the set 'range' of the UMap. 5 | 6 | trigger: the trigger 7 | range: the range of the value 8 | time: a linear lag time to move to the new value 9 | 10 | the 'range' arg range is mapped to that of the parameter to which the UMap is connected. 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the Unit lib default UMapDefs set 15 | */ 16 | 17 | UMapDef( \trig_random, { 18 | var lo, hi, trigger, time, output; 19 | var sig; 20 | trigger = \trigger.tr; 21 | #lo, hi = \range.kr([0.0,1.0]); 22 | time = \time.kr(0.0); 23 | URandSeed.ir(); 24 | output = TRand.kr( lo, hi, trigger ); 25 | output = output.varlag( time ); 26 | UMapOut.kr( output ); 27 | }) 28 | .mappedArgs_([ \range ]) 29 | .setSpec( \trigger, TriggerSpec() ) 30 | .category_( 'trigger_to_value' ) -------------------------------------------------------------------------------- /UnitDefs/babblingbrook_jmc.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \babblingbrook_jmc 3 | 4 | The famous James Mc.Cartney babbling brook. based on code posted to sc-users 2007-04-07 by james mccartney 5 | 6 | amp: amplitude (0-1) 7 | seed: random seed (positive whole number). The same seed will always result in exactly the same signal on any computer. 8 | 9 | -- 10 | this is an Udef definition file 11 | part of the Unit lib default Udefs set 12 | */ 13 | 14 | MultiChannelUdef( \babblingbrook_jmc, { |amp = 0.1| 15 | var son; 16 | 17 | URandSeed.ir(); 18 | son = ({RHPF.ar(OnePole.ar(BrownNoise.ar, 0.99), LPF.ar(BrownNoise.ar, 14) 19 | * 400 + 500, 0.03, 0.003)}! Udef.numChannels ) 20 | + ({RHPF.ar(OnePole.ar(BrownNoise.ar, 0.99), LPF.ar(BrownNoise.ar, 20) 21 | * 800 + 1000, 0.03, 0.005)}! Udef.numChannels ) * 4; 22 | 23 | UMixOut.ar( 0, son * (amp * 100), 0, true ) 24 | }, [ 25 | [ \amp, 0.1, \amp.asSpec ] 26 | ], channels: [1,2,3,4,5,6,7,8] ).category_( \synthesis ) -------------------------------------------------------------------------------- /UMapDefs/set_reset_ff.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \set_reset_ff 3 | 4 | This UMap implements a flip-flop switch mechanism. 5 | 6 | trigger: the set trigger 7 | reset: the reset trigger 8 | lag: a linear lag time between value1 and value2 in seconds 9 | value1: the first value (or UMap) 10 | value2: the second value (or UMap) 11 | 12 | value1 and value2 arg ranges are mapped to that of the parameter to which the UMap is connected. 13 | 14 | -- 15 | this is an UMapDef definition file 16 | part of the Unit lib default UMapDefs set 17 | */ 18 | 19 | UMapDef( \set_reset_ff, { 20 | var index, output; 21 | index = SetResetFF.kr( \trigger.tr, \reset.tr ); 22 | index = Slew.kr(index, 1 / \lag.kr(0.0), 1 / \lag.kr ); 23 | output = SelectX.kr( index, [ \value1.kr(0.0), \value2.kr(1.0) ] ); 24 | UMapOut.kr( output ); 25 | }) 26 | .mappedArgs_([ \value1, \value2 ]) 27 | .setSpec( \trigger, TriggerSpec() ) 28 | .setSpec( \reset, TriggerSpec() ) 29 | .category_( 'trigger_to_value' ) -------------------------------------------------------------------------------- /Examples/mass edit example.scd: -------------------------------------------------------------------------------- 1 | // MassEditU: 2 | 3 | // create 10 similar units 4 | y = 10.collect({ U( \sine, [ \freq, 220 rrand: 880, \amp, 0.1 rrand: 0.5 ] ) }); 5 | 6 | // show them all in a window 7 | w = Window("mass-edit", Rect(571, 101, 264, 381)).front; 8 | w.addFlowLayout; 9 | y.do(_.gui(w)); 10 | 11 | // create a mass editor 12 | z = MassEditU( y ); 13 | z.gui; 14 | 15 | 16 | // MassEditUChain 17 | 18 | // create 10 similar uchains 19 | ( 20 | y = 10.collect({ 21 | UChain( 22 | [ 23 | [ \sine, [ \freq, 220 rrand: 880, \amp, 0.1 rrand: 0.5 ] ], 24 | [ \whitenoise, [ \amp, 0.1 rrand: 0.5 ] ] 25 | ].choose, 26 | \output 27 | ) 28 | .dur_( 2 rrand: 10 ) 29 | .setGain( -10 rrand: 10 ); 30 | }); 31 | 32 | 33 | ) 34 | 35 | // show them all in a window 36 | w = Window("mass-edit", Rect(571, 101, 360, 381), scroll: true).front; 37 | w.addFlowLayout; 38 | y.do(_.gui(w)); 39 | 40 | // create a mass editor 41 | z = MassEditUChain( y ); 42 | z.gui; 43 | -------------------------------------------------------------------------------- /UMapDefs/lag_lpf.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \lag_lpf 3 | 4 | An UMap that slows down value changes over time. It is implemented as a two-pole low-pass filter. Please note that changing the 'time' variable during playback may cause the filter to become temporarily unstable. 5 | 6 | value: the value upon which the lag is applied (this can be another UMap as well) 7 | time: the time it takes to move to within 0.01% towards a new value 8 | 9 | The value arg range is mapped to that of the parameter to which the UMap is connected. 10 | 11 | -- 12 | this is an UMapDef definition file 13 | part of the Unit lib default UMapDefs set 14 | */ 15 | 16 | UMapDef( \lag_lpf, { |value = 0.0, time = 0.0| 17 | Udef.buildUdef.dontStoreSynthDef = true; 18 | UMapOut.kr( LPFLag.kr( value, time).clip(0,1) ); 19 | }) 20 | .uchainInitFunc_({ |unit, chain| 21 | unit.def_( \lag ); 22 | unit.type = \lpf; 23 | }) 24 | .setSpec( \time, [0,10,\lin].asSpec ) 25 | .mappedArgs_([ \value ]) 26 | .category_( 'private' ) -------------------------------------------------------------------------------- /UMapDefs/lfo_saw.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \lfo_saw 3 | 4 | Creates an UMap with a low frequency saw/triangle wave oscillator. 5 | 6 | freq: the frequency of the pulse wave 7 | phase: the initial phase (0-1) of the pulse wave 8 | width: the width of the sawtooth; 9 | 0 creates a saw wave: |\|\ 10 | 0.5 creates a traingular wave: /\/\ 11 | 1 creates an reversed saw wave: /|/| 12 | range: the output range 13 | 14 | The 'range' arg range is mapped to that of the parameter to which the UMap is connected. 15 | 16 | -- 17 | this is an UMapDef definition file 18 | part of the Unit lib default UMapDefs set 19 | */ 20 | 21 | UMapDef( \lfo_saw, { |freq = 2, phase = 0, width = 0.0, range = #[0.0,1.0]| 22 | var sig; 23 | sig = VarSaw.kr(freq, phase + (\u_startPos.kr(0) * freq), width).range(*range); 24 | UMapOut.kr(sig); 25 | }) 26 | .setSpec( \phase, [0,1,\lin,0,0], \init ) 27 | .setSpec( \freq, FreqSpec(0.001,300, default: 2) ) 28 | .mappedArgs_( [ \range ] ) 29 | .category_( 'lfo' ) 30 | -------------------------------------------------------------------------------- /Examples/Spec guis test.scd: -------------------------------------------------------------------------------- 1 | 2 | // Show all types of spec 3 | ( 4 | x = Udef(\test,{ |bus = 0, freq = 500,thing2=1, thing3 =1,thing4,thing5,thing6| 5 | Out.ar(bus,WhiteNoise.ar*0.001*\point.kr(0,0)) }, 6 | [[\bus,0,IntegerSpec()], 7 | [\point, Point(1,2),PointSpec(Rect(0,0,20,20))], // is not constraining... 8 | [\thing2,1,BoolSpec()], 9 | [\thing3,1,ListSpec([1,2,3,4],2)], 10 | //[\thing4,1,RangeSpec()] this is broken 11 | ]); 12 | y = U(\test); 13 | y.gui; 14 | ) 15 | 16 | RangeSpec() 17 | 18 | //EQ 19 | 20 | ( 21 | var numChannels = 2; 22 | x = MetaU(\param_beq,[\numChannels,numChannels],[\eq_controls,EQSpec().default]); 23 | y = Udef(\noise,{ UOut.ar(0, WhiteNoise.ar.dup(numChannels) *0.1) }); 24 | r = MetaU(\copy,[\numChannels,numChannels]); 25 | z = UChain(\noise,x,r); 26 | z.prepareAndStart(s); 27 | x.unit.gui(nil,Rect(0,0,700,700)) 28 | ) 29 | 30 | x.set(\eq_controls,EQArg([ [ 100, 0, 1 ], [ 250, 0, 1 ], [ 1000, 0, 1 ], [ 3500, 0, 1 ], [ 10000, -24, 1 ] ])) 31 | -------------------------------------------------------------------------------- /UnitDefs/lfNoise.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \lfNoise 3 | 4 | A sample-and-hold noise generator. Generates random values at frequency rate. 5 | 6 | freq: frequency (2-20000Hz) 7 | amp: amplitude (0-1) of the noise 8 | type: the type of noise: 9 | 0: step or sample-and-hold noise; hard jumps at each value change 10 | 1: linear interpolated noise 11 | 2: cubic interpolated noise 12 | 3: clip noise 13 | 14 | -- 15 | this is an Udef definition file 16 | part of the Unit lib default Udefs set 17 | */ 18 | 19 | Udef( \lfNoise, { |freq = 440, amp = 0.1, type = 0| 20 | var sig; 21 | URandSeed.ir(); 22 | sig = [ 23 | LFDNoise0.ar( freq, amp ), 24 | LFDNoise1.ar( freq, amp ), 25 | LFDNoise3.ar( freq, amp ), 26 | LFDClipNoise.ar( freq, amp ), 27 | ]; 28 | sig = SelectX.ar( type, sig ); 29 | UMixOut.ar( 0, sig, 0, true ) 30 | } ).category_( \noise ) 31 | .setSpec( \type, ListSpec( [0,1,2,3], 0, ['step', 'linear', 'cubic', 'clip'] ) ) 32 | .setSpec( \freq, FreqSpec(2, 20000, default: 440) ) -------------------------------------------------------------------------------- /UnitDefs/pitchShift.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \pitchShift 3 | 4 | A time domain granular pitch shifter. Grains have a triangular amplitude envelope and an overlap of 4:1. 5 | 6 | semitones: the number of semitones to shift the pitch with. 7 | pitchDisp: the maximum random deviation of the pitch. 8 | timeDisp: a random offset from 0 to the number of seconds set with timeDisp that is added to the delay of the grain. 9 | 10 | -- 11 | this is an Udef definition file 12 | part of the Unit lib default Udefs set 13 | */ 14 | 15 | Udef( \pitchShift, { |semitones = 0, pitchDisp = 0.0, timeDisp = 0.0| 16 | var sig, windowSize; 17 | windowSize = \windowSize.ir(0.2); 18 | URandSeed.ir(); 19 | sig = UIn.ar( 0, 1 ); 20 | sig = PitchShift.ar( sig, windowSize, semitones.midiratio, pitchDisp * 4, timeDisp * 0.2 ); 21 | UOut.ar(0, sig ); 22 | }) 23 | .category_( \effect ) 24 | .setSpec( \semitones, [ -24, 24, \lin, 0.01, 0 ].asSpec ) 25 | .setSpec( \windowSize, [0.01,0.5,\exp, 0, 0.2 ].asSpec, \init ) -------------------------------------------------------------------------------- /UMapDefs/db_amp.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \db_amp 3 | 4 | Creates an UMap for converting db values to amplitude 5 | 6 | db: the db value 7 | mute: if true amp becomes zero 8 | 9 | -- 10 | this is an UMapDef definition file 11 | part of the Unit lib default UMapDefs set 12 | */ 13 | 14 | HybridUMapDef( \db_amp, { |db = 64, mute = 0| 15 | UMapDef.useMappedArgs = false; // use raw values instead of mapped (0-1) 16 | UMapOut.kr( db.dbamp * (1-mute) ); 17 | }, { |unit, db = 64, mute = 0| 18 | db.dbamp * (1-mute.binaryValue) 19 | } 20 | ) 21 | .mappedArgs_([ \db ]) 22 | .setSpec( \db, UAdaptSpec({ |spec| 23 | ControlSpec( spec.minval.max(-96.dbamp).ampdb, spec.maxval.max(-96.dbamp).ampdb, \lin, 0, 0 ); 24 | }) ) 25 | .setSpec( \mute, BoolSpec(false) ) 26 | .canUseUMapFunc_({ |unit, key, umapdef| 27 | var spec; 28 | spec = unit.getSpec( key ); 29 | spec.isKindOf( ControlSpec ) && { spec.default.size < 2 && { (spec.minval == 0) && { spec.maxval < inf } } }; 30 | }) 31 | .category_( 'convert' ); -------------------------------------------------------------------------------- /UMapDefs/uchain_startTime.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \uchain_startTime 3 | 4 | Creates an UMap that passes on the startTime of the current UChain. When used inside an UPattern this returns the elapsed time since the pattern has started. It has no parameters, and can only be applied to SMPTESpec arguments (i.e. time arguments). 5 | 6 | -- 7 | this is an UMapDef definition file 8 | part of the Unit lib default UMapDefs set 9 | */ 10 | 11 | FuncUMapDef( \uchain_startTime, { |unit| 12 | var chain; 13 | chain = UChain.nowPreparingChain ?? { UPattern.nowCallingPattern }; 14 | if( chain.notNil ) { 15 | chain.startTime; 16 | } { 17 | 1; 18 | }; 19 | }) 20 | .category_( 'uchain_info' ) 21 | .valueIsMapped_( false ) 22 | .mappedArgs_( [] ) 23 | .setSpec( \value, DisplaySpec( SMPTESpec(), _.asSMPTEString(1000) ), private: true ) 24 | .canUseUMapFunc_({ |unit, key, umapdef| 25 | var spec; 26 | spec = unit.getSpec( key ); 27 | [ SMPTESpec, UAdaptSpec ].any({ |item| spec.isKindOf( item ) }); 28 | }) -------------------------------------------------------------------------------- /Classes/Extensions/extBuffer-uSendCollection.sc: -------------------------------------------------------------------------------- 1 | + Buffer { 2 | 3 | *uSendCollection { |server, collection, numChannels = 1, wait = 0.02, action| 4 | var buffer = this.alloc(server, ceil(collection.size / numChannels), numChannels); 5 | var pos, collstream, collsize, bundsize; 6 | if( UEvent.nrtMode != true ) { 7 | OSCFunc({ |msg, time, addr| 8 | { buffer.sendCollection( collection, 0, wait, action ); }.fork; 9 | }, '/done', server.addr, argTemplate: [ '/b_alloc', buffer.bufnum ]).oneShot; 10 | } { 11 | collstream = CollStream.new; 12 | collstream.collection = collection; 13 | collsize = collection.size; 14 | pos = collstream.pos; 15 | while { pos < collsize } { 16 | // 1626 max size for setn under udp 17 | bundsize = min(1626, collsize - pos); 18 | server.listSendMsg(['/b_setn', buffer.bufnum, pos, bundsize] 19 | ++ Array.fill(bundsize, { collstream.next })); 20 | pos = collstream.pos; 21 | }; 22 | }; 23 | ^buffer; 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /UMapDefs/semitones_rate.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \semitones_rate 3 | 4 | Creates an UMap for converting a fractional (playback) rate to semitones of transposition. 5 | 6 | semitones: amount of semitones transposition 7 | 8 | -- 9 | this is an UMapDef definition file 10 | part of the Unit lib default UMapDefs set 11 | */ 12 | 13 | HybridUMapDef( \semitones_rate, { |semitones = 0| 14 | UMapDef.useMappedArgs = false; // use raw values instead of mapped (0-1) 15 | UMapOut.kr( semitones.midiratio ); 16 | }, { |unit, semitones = 0| 17 | semitones.midiratio; 18 | }) 19 | .mappedArgs_([ \semitones ]) 20 | .setSpec( \semitones, UAdaptSpec({ |spec| 21 | ControlSpec( spec.minval.ratiomidi, spec.maxval.ratiomidi, \lin, 22 | 0, spec.default.ratiomidi ); 23 | }) ) 24 | .canUseUMapFunc_({ |unit, key, umapdef| 25 | var spec; 26 | spec = unit.getSpec( key ); 27 | spec.isKindOf( ControlSpec ) && { spec.default.size < 2 && { spec.minval > 0 && { spec.maxval < inf } } }; 28 | }) 29 | .category_( 'convert' ) -------------------------------------------------------------------------------- /Classes/Extensions/extNilObject.sc: -------------------------------------------------------------------------------- 1 | /* 2 | Unit Library 3 | The Game Of Life Foundation. http://gameoflife.nl 4 | Copyright 2006-2011 Miguel Negrao, Wouter Snoei. 5 | 6 | GameOfLife Unit Library: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | GameOfLife Unit Library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with GameOfLife Unit Library. If not, see . 18 | */ 19 | 20 | + Object { 21 | !! { arg obj; ^obj.value(this) } 22 | } 23 | 24 | + Nil { 25 | !! { } 26 | } -------------------------------------------------------------------------------- /UMapDefs/median.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \median 3 | 4 | An UMap that applies a median filter, effectively removing spikes from incoming values by calculating the median value of a number of samples (length). 5 | 6 | value: the value upon which the median is applied (this can be another UMap as well) 7 | length: length of the median window 8 | amount: mix between original signal and filtered signal (0-1) 9 | 10 | The value arg range is mapped to that of the parameter to which the UMap is connected. 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the Unit lib default UMapDefs set 15 | */ 16 | 17 | UMapDef( \median, { |value = 0.0, length = 3, amount = 1.0| 18 | var median, delaytime; 19 | median = Median.kr( length, value ) * amount; 20 | delaytime = ControlDur.ir * ((length/2)-1).ceil; 21 | value = DelayN.kr( value, delaytime, delaytime ) * (1-amount); 22 | UMapOut.kr( median + value ); 23 | }) 24 | .setSpec( \length, [1,31,\lin,1,3].asSpec, \init ) 25 | .mappedArgs_([ \value ]) 26 | .category_( 'filter' ) -------------------------------------------------------------------------------- /UMapDefs/value_to_range.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \value_to_range 3 | 4 | Creates an UMap intended for use on modulatable range parameters. The UMap derrives a value range by taking the peak and the lowest value from the input value over time. 5 | 6 | value: the input value (or UMap) 7 | decay: (0-1) a decay parameter for the (low)peak detection. 0 means no decay, 1 means infinite decay 8 | 9 | The 'value' arg range is mapped to that of the parameter to which the UMap is connected. 10 | 11 | -- 12 | this is an UMapDef definition file 13 | part of the Unit lib default UMapDefs set 14 | */ 15 | 16 | UMapDef( \value_to_range, { |value = 0.5, decay = 0.999| 17 | var range; 18 | range = [ 19 | 1 - PeakFollower.kr( 1 - value, decay ), 20 | PeakFollower.kr( value, decay ) 21 | ]; 22 | UMapOut.kr(range); 23 | }) 24 | .mappedArgs_( [ \value ] ) 25 | .canUseUMapFunc_({ |unit, key, umapdef| 26 | unit.getSpec( key ).isKindOf( RangeSpec ); 27 | }) 28 | .setSpec( \decay, [0,1,-8].asSpec ) 29 | .category_( 'range' ); 30 | -------------------------------------------------------------------------------- /UnitDefs/delay.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \delay 3 | 4 | time: the length of the delay. 5 | timeScale: the number of seconds by which 'time' is multiplied. This value can not be changed during playback. 6 | dry: level of the dry signal. 7 | amp: level of the delayed signal. 8 | lag: smoothing time applied to change of delay time, use to prevent clicks during change of delay time. 9 | 10 | -- 11 | this is an Udef definition file 12 | part of the Unit lib default Udefs set 13 | */ 14 | 15 | 16 | Udef( \delay, { |time = 0.1, timeScale = 1, dry = 1, amp = 0.2, lag = 0| 17 | var in, delayed; 18 | in = UIn.ar( 0, 1 ); 19 | delayed = DelayC.ar( in, timeScale * 2, time.lag3( lag ) * timeScale, amp ); 20 | UOut.ar( 0, delayed + ( in * dry ) ) 21 | } ) 22 | .category_( \effect ) 23 | .setSpec( \time, [ 0, 2, \lin, 0, 0.1 ] ) 24 | .setSpec( \timeScale, ListSpec([0.1,1,10],1,["0.1s", "1s", "10s"]), \init ) 25 | .setSpec( \dry, [0,1,\lin,0], \normal ) 26 | .setSpec( \lag, [0,1,\lin].asSpec ) 27 | .setSpecMode( \amp, \normal ); 28 | -------------------------------------------------------------------------------- /UnitDefs/tiltEQ.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \tiltEQ 3 | 4 | Combined High Shelf and Low Shelf filter. Default settings mimic the Tonelux TILT eq response. 5 | 6 | tilt: amount of tilt (in dBs). Positive numbers increase high frequencies. 7 | center: center frequency (default 650) 8 | rs: the reciprocal of S. Shell boost/cut slope for both shelving filters (default 2) 9 | 10 | -- 11 | this is an Udef definition file 12 | part of the Unit lib default Udefs set 13 | */ 14 | 15 | MultiChannelUdef( \tiltEQ, { |tilt = 0, center = 650, rs = 2, ampComp = 0| 16 | var in; 17 | in = UIn.ar( 0, Udef.numChannels ); 18 | center = center.clip(20,20000); 19 | in = BHiShelf.ar( in, center, rs, tilt ); 20 | in = BLowShelf.ar( in, center, rs, tilt.neg ); 21 | UOut.ar( 0, in * (tilt.abs * ampComp).dbamp ); 22 | }) 23 | .category_( \eq ) 24 | .setSpec( \tilt, [-24,24,\lin,0,0].asSpec ) 25 | .setSpec( \ampComp, [-1,1,\lin,0,0].asSpec ) 26 | .setSpec( \center, \freq.asSpec.copy.default_(650) ) 27 | .setSpec( \rs, [ 0.6, 10, \exp, 0, 1 ].asSpec ) 28 | -------------------------------------------------------------------------------- /Classes/SyncCenter/+ OSCBundle.sc: -------------------------------------------------------------------------------- 1 | /* 2 | Unit Library 3 | The Game Of Life Foundation. http://gameoflife.nl 4 | Copyright 2006-2011 Miguel Negrao, Wouter Snoei. 5 | 6 | GameOfLife Unit Library: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | GameOfLife Unit Library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with GameOfLife Unit Library. If not, see . 18 | */ 19 | 20 | + OSCBundle { 21 | 22 | syncedSend{ |server, delta| 23 | server.listSendSyncedBundle(delta,messages) 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /UMapDefs/integer.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \integer 3 | 4 | Creates an UMap for rounding values to whole numbers (Integer), on a linear scale. 5 | 6 | input: the value 7 | 8 | The 'input' arg ranges are mapped to that of the parameter to which the UMap is connected. 9 | 10 | -- 11 | this is an UMapDef definition file 12 | part of the Unit lib default UMapDefs set 13 | */ 14 | 15 | HybridUMapDef( \integer, { |input = 0.5| 16 | UMapDef.useMappedArgs = false; 17 | UMapOut.kr(input); 18 | }, { |unit, input = 0.5| 19 | input.clip( *[unit.spec.minval, unit.spec.maxval] ); 20 | }, \convert 21 | ) 22 | .valueIsMapped_( false ) 23 | .setSpec( \input, UAdaptSpec( { |spec| 24 | IntegerSpec( spec.default, spec.minval, spec.maxval ); 25 | } ) ) 26 | .canUseUMapFunc_({ |unit, key, umapdef| 27 | var spec; 28 | UMapDef.defaultCanUseUMapFunc.value( unit, key, umapdef ) && { 29 | spec = unit.getSpec( key ); 30 | spec.respondsTo( \minval ) && { spec.respondsTo( \maxval ) }; 31 | }; 32 | }) 33 | .mappedArgs_( [ \input ] ); 34 | 35 | 36 | -------------------------------------------------------------------------------- /UMapDefs/p_stutter.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \p_stutter 3 | 4 | Creates an pattern UMap for repeating values. The output values of a connected (pattern) UMap is repeated n times until the next value is called. 5 | 6 | input: value or UMap to repeat 7 | n: number of repetitions 8 | 9 | The 'input' arg ranges is mapped to that of the parameter to which the UMap is connected 10 | 11 | -- 12 | this is an UMapDef definition file 13 | part of the Unit lib default UMapDefs set 14 | */ 15 | 16 | UPatDef( \p_stutter, { |unit, input = 0, n = 1| 17 | Pdup( n, input ).asStream; 18 | }) 19 | .setSpec( \input, UAdaptSpec() ) 20 | .setSpec( \n, IntegerSpec(1, 1,((2**31) - 1).asInteger) ) 21 | .canUseUMapFunc_({ |unit, key, umapdef| 22 | unit.isKindOf( UPattern ).not && { 23 | [ Point, SimpleNumber, Array, Symbol, Boolean ].any({ |class| 24 | unit.getDefault( key ).isKindOf( class ) 25 | }) && { UAdaptSpec().canAdapt( unit.getSpec( key ) ) } 26 | }; 27 | }) 28 | .useMappedArgs_( false ) 29 | .mappedArgs_([ \input ]).category_( 'pattern_filter' ); -------------------------------------------------------------------------------- /UnitDefs/blipTest.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \blipTest 3 | 4 | A test signal generator, including a "blip" oscillator and pink noise generator, modulated with a pulse lfo. This generator is equal to the "blip" audioType in WFSCollider version 1. 5 | 6 | rate: frequency (Hz) of pulse lfo 7 | freq: frequency (Hz) of blip oscillator 8 | noiseLevel: amplitude (0-1) of pink noise generator 9 | blipLevel: amplitude (0-1) of blip oscillator 10 | 11 | 12 | -- 13 | this is an Udef definition file 14 | part of the Unit lib default Udefs set 15 | */ 16 | 17 | Udef(\blipTest,{ |rate = 1, freq = 100, noiseLevel = 0.125, blipLevel = 1| 18 | var out, env; 19 | URandSeed.ir( 12345 ); // always the same noise 20 | out = ( Blip.ar( freq, 100, blipLevel * 0.125) + 21 | PinkNoise.ar( noiseLevel )) * 22 | LFPulse.kr(10 * rate); 23 | UMixOut.ar(0, out, 0, true ) 24 | }).category_( \synthesis ) 25 | .setSpec( \noiseLevel, \amp.asSpec ) 26 | .setSpec( \blipLevel, \amp.asSpec ) 27 | .setSpecMode( \noiseLevel, \normal ) 28 | .setSpecMode( \blipLevel, \normal ) 29 | -------------------------------------------------------------------------------- /UMapDefs/slope.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \slope 3 | 4 | An UMap that differentiates its input, returning the amount of change per control cycle. 5 | 6 | value: the value upon which the lag is applied (this can be another UMap as well) 7 | abs: if true the UMap returns the absolute slope, if false it returns negative and positive slope 8 | range: the range to which the output values are mapped 9 | 10 | The 'value' and 'range' arg ranges are mapped to that of the parameter to which the UMap is connected 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the Unit lib default UMapDefs set 15 | */ 16 | 17 | UMapDef( \slope, { |value = 0.0, abs = 0, boost = 0, range = #[0.0,1.0]| 18 | var slope; 19 | slope = HPZ1.kr( value.linlin(0,1,-1,1) * DC.kr(1).blend( 1/ControlDur.ir, boost ) ); 20 | slope = if( abs, slope.abs.linlin(0,1,-1,1), slope ); 21 | UMapOut.kr( slope.linlin( -1, 1, *range ) ); 22 | }) 23 | .mappedArgs_([ \value, \range ]) 24 | .setSpec( \abs, BoolSpec(false) ) 25 | .setSpec( \boost, [0,1,\lin].asSpec ) 26 | .category_( 'filter' ) -------------------------------------------------------------------------------- /UMapDefs/single_chord.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \single_chord 3 | 4 | This is the standard UMap for UPattern. The UMap turns the pattern into a single chord player. I.e. it plays a number of copies of the chain at the same time, with the same duration as the whole UPattern (can be inf) 5 | 6 | n: number of voices (1-100, default 2) 7 | strum: the voices of the chord will be started one-by-one over the strum time. A zero strum time (default) means all voices start immediately. 8 | 9 | -- 10 | this is an UMapDef definition file 11 | part of the Unit lib default UMapDefs set 12 | */ 13 | 14 | FuncUMapDef( \single_chord, { |unit, n = 2, strum = 0| 15 | var count = UPattern.count; 16 | if( count < (n - 1) ) { 17 | [ inf, strum / n ] 18 | } { 19 | [ inf, inf ] 20 | } 21 | }) 22 | .category_( 'upattern' ) 23 | .valueIsMapped_( false ) 24 | .setSpec( \strum, SMPTESpec(0,3600) ) 25 | .setSpec( \n, IntegerSpec(2,1,10000) ) 26 | .dontStoreValue_( true ) 27 | .canUseUMapFunc_({ |unit, key, umapdef| 28 | unit.getSpec( key ).isKindOf( UPatternSpec ); 29 | }) -------------------------------------------------------------------------------- /UMapDefs/scale_time.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \scale_time 3 | 4 | Creates an UMap that scales a time to a certain factor. This UMap can also be used on 'init' mode parameters. It can only be used for time (SMPTESpec) parameters. 5 | 6 | time: time to scale (in seconds) 7 | factor: amount of scaling (lower values give smaller times) 8 | add: amount of time to add after scaling 9 | 10 | -- 11 | this is an UMapDef definition file 12 | part of the Unit lib default UMapDefs set 13 | */ 14 | 15 | HybridUMapDef( \scale_time, { |time = 1, factor = 1, add = 0| 16 | UMapDef.useMappedArgs = false; 17 | UMapOut.kr( (time * factor) + add, false ); 18 | }, { |unit, time = 1, factor = 1, add = 0| 19 | (time * factor) + add 20 | }) 21 | .category_( 'convert' ) 22 | .valueIsMapped_( false ) 23 | .setSpec( \time, SMPTESpec() ) 24 | .setSpec( \factor, [0.1,10,\exp,0,1].asSpec ) 25 | .setSpec( \add, SMPTESpec() ) 26 | .canUseUMapFunc_({ |unit, key, umapdef| 27 | unit.getSpec( key ).isKindOf( SMPTESpec ) or: { 28 | unit.getSpec( key ).isKindOf( UAdaptSpec ) 29 | } 30 | }) -------------------------------------------------------------------------------- /UMapDefs/p_select.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \p_select 3 | 4 | Creates an UMap that can select a value from an Array of values in a UPattern. 5 | 6 | index: the index (0-n-1) 7 | vals: the Array of values 8 | n: the total number of values 9 | 10 | The 'vals' arg ranges are mapped to that of the parameter to which the UMap is connected. 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the Unit lib default UMapDefs set 15 | */ 16 | 17 | var defs; 18 | 19 | defs = [2,3,4,5,6,7,8,9,10,11,12,14,16,18,20,24,28,32,48,64,96,128 ].collect({ |n| 20 | UPatDef( n, { |unit, index = 0, vals| 21 | { 22 | inf.do({ 23 | vals.next.wrapAt( index.next ).yield; 24 | }); 25 | }.r 26 | }, addToAll: false ) 27 | .category_( \pattern ) 28 | .setSpec( \index, IntegerSpec(0,0,n-1) ) 29 | .setSpec( \vals, ArrayControlSpec(0,1,\lin,default: 0.5!n ).size_(n) ) 30 | .mappedArgs_([ \vals ]); 31 | }); 32 | 33 | MultiUMapDef( \p_select, defs, \pattern_selection, \n, false ) 34 | .mappedArgs_([ \vals ]) 35 | .defaultDefName_( 8 ) 36 | .allowedModes_([ \init, \sync, \normal ]) -------------------------------------------------------------------------------- /UnitDefs/median.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \median 3 | 4 | A median filter, effectively removing spikes from incoming values by calculating the median value of a number of samples (length). 5 | 6 | length: length of the median window 7 | amount: mix between original signal and filtered signal (0-1) 8 | residue: (boolean) if true the unit will output the difference between the original input signal and the output signal. 9 | 10 | -- 11 | this is an Udef definition file 12 | part of the Unit lib default Udefs set 13 | */ 14 | 15 | Udef( \median, { |length = 3, amount = 1.0, residue = 0| 16 | var in; 17 | var median, delaytime, delayed; 18 | in = UIn.ar(0,1); 19 | median = Median.ar( length, in ); 20 | delaytime = SampleDur.ir * ((length/2)-1).ceil; 21 | delayed = DelayN.ar( in, delaytime, delaytime ); 22 | in = (amount * median) + ((1-amount) * delayed); 23 | in = LinXFade2.ar( in, delayed - in, (residue * 2) - 1 ); 24 | UOut.ar( 0, in ); 25 | }) 26 | .category_( \filter ) 27 | .setSpec( \length, [1,31,\lin,1,3].asSpec, \init ) 28 | .setSpec( \residue, BoolSpec(false) ); -------------------------------------------------------------------------------- /UMapDefs/time_freq.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \time_freq 3 | 4 | Creates an UMap for converting the duration of a period in a frequency to a time value. 5 | 6 | time: time for one period 7 | factor: multiplication factor (0.1-10) for the resulting frequency 8 | 9 | -- 10 | this is an UMapDef definition file 11 | part of the Unit lib default UMapDefs set 12 | */ 13 | 14 | HybridUMapDef( \time_freq, { |time = 0.002, factor = 1| 15 | UMapDef.useMappedArgs = false; // use raw values instead of mapped (0-1) 16 | UMapOut.kr( factor / time.max(1.0e-12) ); 17 | }, { |unit, time = 0.002, factor = 1| 18 | factor / time.max(1.0e-12); 19 | }) 20 | .setSpec( \time, UAdaptSpec({ |spec| 21 | SMPTESpec( 1/spec.maxval, 1/(spec.minval.max(1.0e-12)) ); 22 | }) ) 23 | .setSpec( \factor, [ 0.1, 10, \exp ].asSpec ) 24 | .canUseUMapFunc_({ |unit, key, umapdef| 25 | var spec; 26 | spec = unit.getSpec( key ); 27 | spec.isKindOf( ControlSpec ) && { spec.default.size < 2 && { spec.minval > 0 && { spec.maxval < inf } } }; 28 | }) 29 | .mappedArgs_( [ \time ] ) 30 | .category_( 'convert' ) -------------------------------------------------------------------------------- /UMapDefs/direction_change.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \direction_change 3 | 4 | This UMap can switch between two values, depending on an incoming value. If the value is changing upwards (getting higher) the result is 'up', if the value is changing downwards it becomes 'down'. If the value doesn't change, the current state is kept. All parameters can be UMaps. 5 | 6 | value: the value to test (0-1) 7 | upValue: the value (or UMap) to output when the value changes upwards 8 | downValue: the value (or UMap) to output when the value changes downwards 9 | 10 | upValue and downValue arg ranges are mapped to that of the parameter to which the UMap is connected. 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the Unit lib default UMapDefs set 15 | */ 16 | 17 | UMapDef( \direction_change, { |value = 0.0, upValue = 1.0, downValue = 0.0| 18 | var index, output; 19 | index = Schmidt.kr( HPZ1.kr( value ), 0, 0 ); 20 | output = Select.kr( index, [ downValue, upValue ] ); 21 | UMapOut.kr( output ); 22 | }) 23 | .mappedArgs_([ \upValue, \downValue ]) 24 | .category_( 'detection' ) -------------------------------------------------------------------------------- /Classes/Extensions/plusContiguousBlockAllocator-uReserve.sc: -------------------------------------------------------------------------------- 1 | + ContiguousBlockAllocator { 2 | 3 | uReserve { |address, size = 1, warn = true| 4 | var block = array[address - addrOffset] ?? { this.prFindNext(address) }; 5 | var new; 6 | if(block.notNil and: 7 | { block.used and: 8 | { address + size > block.start } 9 | }) { 10 | if(warn) { 11 | "The block at (%, %) is already in use and cannot be reserved." 12 | .format(address, size).warn; 13 | }; 14 | } { 15 | if(block.notNil and: { block.start == address }) { 16 | new = this.prReserve(address, size, block); 17 | ^new 18 | } { 19 | block = this.prFindPrevious(address); 20 | if(block.notNil and: 21 | { block.used and: 22 | { block.start + block.size > address } 23 | }) { 24 | if(warn) { 25 | "The block at (%, %) is already in use and cannot be reserved." 26 | .format(address, size).warn; 27 | }; 28 | } { 29 | new = this.prReserve(address, size, nil, block); 30 | ^new 31 | }; 32 | }; 33 | }; 34 | ^nil 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /UMapDefs/density_overlap.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \density_overlap 3 | 4 | This UMap is intended for use on the 'pattern' value of an UPattern. It creates new events based on density and overlap settings. 5 | 6 | density: number of events per second 7 | variation: amount of random variation on start times 8 | overlap: amount of overlap in duration per event, as a factor of the average time between two events. 9 | 10 | -- 11 | this is an UMapDef definition file 12 | part of the Unit lib default UMapDefs set 13 | */ 14 | 15 | FuncUMapDef( \density_overlap, { |unit, density = 10, variation = 0.0, overlap = 4| 16 | variation = (variation * 6).midiratio; 17 | [ overlap/density, 1.0.rand.linexp(0,1,1/variation/density,variation/density) ] 18 | }) 19 | .category_( 'upattern' ) 20 | .valueIsMapped_( false ) 21 | .mappedArgs_( [] ) 22 | .setSpec( \density, [0.1,100,\exp,0,10].asSpec ) 23 | .setSpec( \overlap, [0,16,((4/16).reciprocal-1).squared.log,0,1].asSpec ) 24 | .dontStoreValue_( true ) 25 | .canUseUMapFunc_({ |unit, key, umapdef| 26 | unit.getSpec( key ).isKindOf( UPatternSpec ); 27 | }) -------------------------------------------------------------------------------- /UMapDefs/peak.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \peak 3 | 4 | Creates an UMap for following the highest or lowest peak from the incoming value (or UMap) 5 | 6 | value: the input value (or UMap) 7 | decay: (0-1) a decay parameter for the (low)peak detection. 0 means no decay, 1 means infinite decay 8 | direction: (-1 - 1) if 1 (default) the UMap will follow output the peak / maximum value, if -1 the UMap will follow the bottom / minimum value. Values in between will interpolate between these two. 9 | 10 | The 'value' arg range is mapped to that of the parameter to which the UMap is connected. 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the Unit lib default UMapDefs set 15 | */ 16 | 17 | UMapDef( \peak, { |value = 0.5, decay = 0.999, direction = 1.0| 18 | var peak; 19 | peak = LinXFade2.kr( 20 | 1 - PeakFollower.kr( 1 - value, decay ), 21 | PeakFollower.kr( value, decay ), 22 | direction 23 | ); 24 | UMapOut.kr(peak); 25 | }) 26 | .mappedArgs_( [ \value ] ) 27 | .setSpec( \decay, [0,1,-8].asSpec ) 28 | .setSpec( \direction, [-1,1].asSpec ) 29 | .category_( 'filter' ); 30 | -------------------------------------------------------------------------------- /HelpSource/Classes/ULib.schelp: -------------------------------------------------------------------------------- 1 | TITLE:: ULib 2 | summary:: Unit Library startup and other convenience methods 3 | categories:: UnitLib 4 | related:: Classes/UChain, Classes/Udef, Classes/UScore 5 | 6 | DESCRIPTION:: 7 | 8 | For starting up the library: 9 | 10 | code:: 11 | ULib.startup 12 | :: 13 | 14 | In order to not to load the all the default synthdefs on every language recompile, the synthefs should be then loaded once with : 15 | 16 | code:: 17 | 18 | ULib.writeDefaultDefs 19 | 20 | :: 21 | 22 | and the then use false in the startup method so that they are not loaded at every startup: 23 | 24 | code:: 25 | ULib.startup(false) 26 | :: 27 | 28 | CLASSMETHODS:: 29 | 30 | METHOD:: waitForServersToBoot 31 | block a routine until all servers have booted. 32 | 33 | 34 | 35 | METHOD:: startup 36 | (describe method here) 37 | 38 | ARGUMENT:: sendDefsOnInit 39 | A boolean. If true will send all the default synthdefs to the server. 40 | 41 | METHOD:: serversWindow 42 | Open the server window. 43 | 44 | 45 | METHOD:: writeDefaultSynthDefs 46 | Write all the default synthdefs to disk. -------------------------------------------------------------------------------- /UMapDefs/random_time.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \random_time 3 | 4 | Creates an UMap that generates a new random time value each time it is started. This UMap can also be used on 'init' mode parameters. It can only be used for time (SMPTESpec) parameters. 5 | 6 | min: minimum time 7 | max: maximum time 8 | value: the output value (can only be changed by the UMap itself) 9 | 10 | The 'value' and 'range' arg ranges are mapped to that of the parameter to which the UMap is connected 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the Unit lib default UMapDefs set 15 | */ 16 | 17 | FuncUMapDef( \random_time, { |unit, min = 0, max = 1| 18 | min rrand: max; // result sets \value arg 19 | }) 20 | .category_( 'random' ) 21 | .valueIsMapped_( false ) 22 | .mappedArgs_( [\min, \max] ) 23 | .setSpec( \min, UAdaptSpec() ) 24 | .setSpec( \max, UAdaptSpec() ) 25 | .setSpec( \value, DisplaySpec( SMPTESpec(), _.asSMPTEString(1000) ) ) 26 | .canUseUMapFunc_({ |unit, key, umapdef| 27 | unit.getSpec( key ).isKindOf( SMPTESpec ) or: { 28 | unit.getSpec( key ).isKindOf( UAdaptSpec ) 29 | } 30 | }) -------------------------------------------------------------------------------- /Classes/Extensions/extObject-isXlike.sc: -------------------------------------------------------------------------------- 1 | /* 2 | Unit Library 3 | The Game Of Life Foundation. http://gameoflife.nl 4 | Copyright 2006-2011 Miguel Negrao, Wouter Snoei. 5 | 6 | GameOfLife Unit Library: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | GameOfLife Unit Library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with GameOfLife Unit Library. If not, see . 18 | */ 19 | 20 | + Object { 21 | 22 | isUChainLike { 23 | ^[UChain,UChainGroup].includes(this.class) 24 | } 25 | 26 | isUScoreLike { 27 | ^[UScore,UScoreList].includes(this.class) 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /Examples/UScore example.scd: -------------------------------------------------------------------------------- 1 | ( 2 | z = UScore( 3 | *12.collect({ |i| 4 | var evt; 5 | evt = BufSndFile("@resources/sounds/a11wlk01-44_1.aiff", 6 | rate: (i-6).midiratio, loop: [true,false].wrapAt(i) ).makeUChain 7 | .releaseSelf_(true).startTime_(i/2).track_(i).fadeOut_(1).fadeIn_(1); 8 | 9 | if( evt.duration == inf ) { 10 | evt.duration = 8; // looped events stopped by UScore 11 | }; 12 | evt; 13 | }) 14 | ); 15 | x = UScoreEditor(z); 16 | y = UScoreEditorGUI(x); 17 | ) 18 | 19 | ( 20 | z = UScore( 21 | *12.collect({ |i| 22 | var evt; 23 | evt = UChain(i/2,i,rrand(3.0,10.0),false,\sine, \output).fadeOut_(1).fadeIn_(1); 24 | evt.units[0].set(\freq,rrand(200.0,600.0) ); 25 | evt; 26 | }) 27 | ); 28 | x = UScoreEditor(z); 29 | y = UScoreEditorGUI(x); 30 | ) 31 | 32 | 33 | z.prepare( s, 0, { "done".postln } ); 34 | z.start( s, 0, true ); 35 | 36 | z.pause; // looped events keep playing 37 | z.resume; 38 | 39 | z.stop; 40 | 41 | z.start( s, 0, false ); // takes extra wait time for preparing events (depends on content) 42 | 43 | z.pos; // returns current position (keeps increasing if not stopped -------------------------------------------------------------------------------- /UMapDefs/p_brown.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \p_brown 3 | 4 | Creates an pattern UMap for brownian noise. New values are generated each time the chain is started, or in a UPattern for each of the generated events. 5 | 6 | lo: minimum value of the noise 7 | hi: maximum value of the noise 8 | step: step size (0-1) as multiplier of the range between lo and hi 9 | seed: random seed for the noise 10 | 11 | The 'lo' and 'hi' arg ranges are mapped to that of the parameter to which the UMap is connected 12 | 13 | -- 14 | this is an UMapDef definition file 15 | part of the Unit lib default UMapDefs set 16 | */ 17 | 18 | UPatDef( \p_brown, { |unit, lo = 0.0, hi = 1.0, step = 0.125, seed| 19 | { 20 | var stream, curr, llo, hhi; 21 | thisThread.randSeed = seed.next.asControlInput; 22 | curr = lo.next rrand: hi.next; 23 | curr.yield; 24 | loop { 25 | llo = lo.next; 26 | hhi = hi.next; 27 | curr = (curr + (step.next.xrand2 * (hhi - llo))).fold( llo, hhi ); 28 | curr.yield; 29 | }; 30 | }.r; 31 | }).mappedArgs_([\lo, \hi ]) 32 | .setSpec( \seed, URandSeed ) 33 | .setDefault( \seed, URandSeed() ) 34 | .category_( 'pattern_random' ); -------------------------------------------------------------------------------- /UnitDefs/balance.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \balance 3 | 4 | A panning balancer for multiple channels (minimum: 2). 5 | 6 | pan: pan position 7 | width: width of panning (0: 2 outputs, 1: all outputs) 8 | amount: amount of panning applied (0-1) 9 | level: output level 10 | numChannels: number of channels (2,3,4,5,6,7,8,10,12,16,24,32) 11 | 12 | -- 13 | this is an Udef definition file 14 | part of the Unit lib default Udefs set 15 | */ 16 | 17 | MultiChannelUdef( \balance, { |pan = 0, width = 0.0, amount = 1.0, level = 1.0 | 18 | var in, pansig; 19 | in = UIn.ar(0, Udef.numChannels ); 20 | if( Udef.numChannels == 2 ) { 21 | pan = pan * 0.5; 22 | }; 23 | pansig = PanAz.kr( 24 | Udef.numChannels, DC.kr(1), pan, 1, 25 | width.linlin(0,1,2,Udef.numChannels), 0.5 26 | ); 27 | pansig = DC.kr(1).blend( pansig, amount ); 28 | in = in * pansig * level; 29 | UOut.ar( 0, in ); 30 | }, channels: [2,3,4,5,6,7,8,10,12,16,24,32]) 31 | .category_( \utility ) 32 | .setSpec( \level, \amp.asSpec, \normal ) 33 | .setSpec( \pan, [-1,1,\lin,0,0], \normal ) 34 | 35 | 36 | /* 37 | { PanAz.ar( 2, DC.ar(1), Line.ar(-0.5,0.5,0.1), 1, 2, 0 ) }.plot(0.1) 38 | */ -------------------------------------------------------------------------------- /UnitDefs/rmsCompressor.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \rmsCompressor 3 | 4 | An rms-compressor. The mean value is taken over a range of 40 samples. 5 | 6 | thresh: in dB. 7 | ratio: ratio of the reduced level to the original level. 8 | knee: the size of the knee in dB over and under the threshold. 0 is equal to no knee. 9 | att: attack. The time it takes to follow an attack. 10 | rel: release. The time it takes to follow a decay. 11 | makeUp: make-up gain. 12 | 13 | -- 14 | this is an Udef definition file 15 | part of the Unit lib default Udefs set 16 | */ 17 | 18 | Udef( \rmsCompressor, { |thresh = (-20), ratio = 1, knee = 6, att = 0, rel= 0.5, makeUp = 0| 19 | var in; 20 | in = UIn.ar(0,1); 21 | in = SoftKneeCompressor.ar( in, in, thresh, ratio, knee, att, rel, makeUp, 40 ); 22 | UOut.ar( 0, in ); 23 | }) 24 | .category_( \dynamics ) 25 | .setSpec( \thresh, [ -96, 0, \lin, 1, -20 ].asSpec ) 26 | .setSpec( \ratio, [ 0, 1, \lin, 0, 1 ].asSpec ) 27 | .setSpec( \knee, [ 0, 24, \lin, 1, 6 ].asSpec ) 28 | .setSpec( \att, [ 0, 1, \lin, 0 ].asSpec ) 29 | .setSpec( \rel, [ 0.01, 1, \exp, 0 ].asSpec ) 30 | .setSpec( \makeUp, [ 0, 1, \lin, 0 ].asSpec ); -------------------------------------------------------------------------------- /UMapDefs/lfo_step_noise.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \lfo_step_noise 3 | 4 | Creates an UMap for generating step noise. Random values are chosen on time intervals. 5 | 6 | time: the time between the steps in seconds, minimum and maximum 7 | type: the type of transitions; step or line: 8 | 0: step or sample-and-hold noise; hard jumps at each value change 9 | 1: linear interpolation 10 | seed: random seed (positive whole number). The same seed will always result in exactly the signal on any computer. 11 | range: the output range 12 | 13 | The 'range' arg is mapped to that of the parameter to which the UMap is connected. 14 | 15 | -- 16 | this is an UMapDef definition file 17 | part of the Unit lib default UMapDefs set 18 | */ 19 | 20 | UMapDef( \lfo_step_noise, { |time = #[0.1,1], type = 0, range = #[0.0,1.0]| 21 | var sig; 22 | URandSeed.ir(); 23 | sig = DemandEnvGen.kr( Dwhite( *range ), Dwhite( 0,1 ).linexp(0,1, *time), type ); 24 | UMapOut.kr(sig); 25 | }) 26 | .setSpec( \type, ListSpec([0,1], 0, [\step, \linear]) ) 27 | .setSpec( \time, RangeSpec(0.001,100, warp: \exp, default: [0.1,1]) ) 28 | .mappedArgs_( [ \range ] ) 29 | .category_( 'lfo' ) 30 | -------------------------------------------------------------------------------- /UnitDefs/peakCompressor.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \peakCompressor 3 | 4 | A compressor that uses the peak values in the amplitude as reference. 5 | 6 | thresh: in dB. 7 | ratio: ratio of the reduced level to the original level. 8 | knee: the size of the knee in dB over and under the threshold. 0 is equal to no knee. 9 | att: attack. The time it takes to follow an attack. 10 | rel: release. The time it takes to follow a decay. 11 | makeUp: make-up gain. 12 | 13 | -- 14 | this is an Udef definition file 15 | part of the Unit lib default Udefs set 16 | */ 17 | 18 | Udef( \peakCompressor, { |thresh = (-20), ratio = 1, knee = 6, att = 0, rel = 0.5, 19 | makeUp = 0| 20 | var in; 21 | in = UIn.ar(0,1); 22 | in = SoftKneeCompressor.ar( in, in, thresh, ratio, knee, att, rel, makeUp, 0 ); 23 | UOut.ar( 0, in ); 24 | }) 25 | .category_( \dynamics ) 26 | .setSpec( \thresh, [ -96, 0, \lin, 1, -20 ].asSpec ) 27 | .setSpec( \ratio, [ 0, 1, \lin, 0, 1 ].asSpec ) 28 | .setSpec( \knee, [ 0, 24, \lin, 1, 6 ].asSpec ) 29 | .setSpec( \att, [ 0, 1, \lin, 0 ].asSpec ) 30 | .setSpec( \rel, [ 0.01, 1, \exp, 0 ].asSpec ) 31 | .setSpec( \makeUp, [ 0, 1, \lin, 0 ].asSpec ); -------------------------------------------------------------------------------- /Classes/Arg/UMapOut.sc: -------------------------------------------------------------------------------- 1 | UMapOut { 2 | 3 | *kr { |channelsArray, map = true, clip = true| 4 | var spec; 5 | ReplaceOut.kr( 6 | UMap.busOffset + \u_mapbus.ir(0), 7 | if( map ) { 8 | Udef.addBuildSpec( 9 | ArgSpec(\u_spec, [0,1,\lin].asSpec, ControlSpecSpec(), true, \init ) 10 | ); 11 | Udef.addBuildSpec( 12 | ArgSpec(\u_useSpec, true, BoolSpec(true), true, \init ) 13 | ); 14 | spec = \u_spec.kr([0,1,1,-2,0]); 15 | if( UMapDef.useMappedArgs ) { 16 | Select.kr( \u_useSpec.ir(1), [ 17 | if( clip ) { channelsArray.clip( 0, 1 ) } { channelsArray }, 18 | spec.asSpecMapKr( channelsArray ) 19 | ]); 20 | } { 21 | Select.kr( \u_useSpec.ir(1), [ 22 | spec.asSpecUnmapKr( channelsArray ), 23 | if( clip ) { 24 | channelsArray.clip( spec[0], spec[1] ) 25 | } { channelsArray } 26 | ]); 27 | }; 28 | } { channelsArray }; 29 | ); 30 | Udef.buildUdef.numChannels = channelsArray.asCollection.size; 31 | Udef.buildUdef.outputIsMapped = map; 32 | Udef.addBuildSpec( 33 | ArgSpec(\u_mapbus, 0, PositiveIntegerSpec(), true, \init ) 34 | ); 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /Classes/GUI/Misc/IntegerNumberBox.sc: -------------------------------------------------------------------------------- 1 | /* 2 | Unit Library 3 | The Game Of Life Foundation. http://gameoflife.nl 4 | Copyright 2006-2011 Miguel Negrao, Wouter Snoei. 5 | 6 | GameOfLife Unit Library: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | GameOfLife Unit Library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with GameOfLife Unit Library. If not, see . 18 | */ 19 | 20 | IntegerNumberBox : SmoothNumberBox { 21 | 22 | *new { arg ...args; 23 | ^super.new( *args ).initIntegerNumberBox 24 | } 25 | 26 | initIntegerNumberBox{ 27 | allowedChars = ""; 28 | step = 1; 29 | clipLo = 0; 30 | } 31 | 32 | 33 | } -------------------------------------------------------------------------------- /UMapDefs/shared_buffer_in.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \shared_buffer_in 3 | 4 | ** this UMapDef should be used in conjunction with a 'shared_buffer' unit ** 5 | 6 | The shared_buffer_in UMapDef can receive a buffer pointer from a 'shared_buffer' unit earlier in the chain. This way a single buffer can be played by multiple buffer-playing units (i.e. bufSoundFile, grainSoundFile etc.). 7 | 8 | id: the id (0-99) by which the point can be retreived from 'shared_buffer' 9 | rate: the playback rate 10 | loop: loop mode on/off for playback 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the WFSCollider Class Library default UMapDefs set 15 | */ 16 | 17 | UMapDef( \shared_buffer_in, { 18 | var buffer; 19 | buffer = USharedBufferIn.kr( \id ); 20 | UMapOut.kr([buffer,\rate.kr(1),\loop.kr(0)], false); 21 | }) 22 | .setSpec( \id, SharedBufferIDSpec( 0 ) ) 23 | .setSpec( \rate, [0,2,\lin,0,1].asSpec ) 24 | .setSpec( \loop, BoolSpec(true) ) 25 | .category_( 'shared_io' ) 26 | .canUseUMapFunc_({ |unit, key, umapdef| 27 | unit.getSpec( key ).isMemberOf( BufSndFileSpec ) or: { 28 | unit.getSpec( key ).isMemberOf( MonoBufSndFileSpec ) 29 | }; 30 | }); -------------------------------------------------------------------------------- /UnitDefs/ringMod.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \ringMod 3 | 4 | A ringmodulator that modulates the soundfile with a sine oscillator, a pink noise generator and/or a second sound file. 5 | 6 | sine: level of the sine oscillator. 7 | freq: frequency of the sine oscillator. 8 | noise: level of the pink noise generator. 9 | input: level of the input on the 1st audio bus. 10 | mix: balance between the original and ringmodulated sound. 11 | 12 | -- 13 | this is an Udef definition file 14 | part of the Unit lib default Udefs set 15 | */ 16 | 17 | Udef( \ringMod, { |sine = 1, freq = 440, noise = 0, input = 0, mix = 1.0| 18 | var sig, modsig; 19 | RandSeed.ir(1,12345); // for the noise 20 | sig = UIn.ar(0,1); 21 | modsig = ( 22 | SinOsc.ar(freq, 0, sine ) + 23 | PinkNoise.ar( noise ) + 24 | ( UIn.ar(1,1) * input ) 25 | ) * sig; 26 | 27 | UOut.ar( 0, (sig * (1-mix)) + (modsig * mix) ); 28 | 29 | }) 30 | .category_( \effect ) 31 | .setSpec( \sine, \amp.asSpec ) 32 | .setSpec( \freq, FreqSpec(2,20000) ) 33 | .setSpec( \noise, \amp.asSpec ) 34 | .setSpec( \input, \amp.asSpec ) 35 | .setSpecMode( \sine, \normal, \noise, \normal, \input, \normal, \mix, \normal ); 36 | -------------------------------------------------------------------------------- /UnitDefs/moogVCF.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \moogVCF 3 | 4 | A Robert Moog style low-pass filter, modulated with an LFO 5 | 6 | freq: cutoff frequencies between which the modulation takes place. 7 | modSpeed: speed of modulation (cycles per second). 8 | modShape: shape of LFO; 0: square wave, 1: sine wave. 9 | res: resonance of the filter (0-1) 10 | 11 | -- 12 | this is an Udef definition file 13 | part of the Unit lib default Udefs set 14 | */ 15 | var class; 16 | class = 'MoogVCF'.asClass; // only create if sc3-plugins are installed 17 | 18 | if( class.notNil ) { 19 | Udef('moogVCF', { |freq #[ 20, 20000 ], modSpeed = 1, modShape = 1, res = 0.5| 20 | var in; 21 | in = UIn.ar(0,1); 22 | freq = freq.clip(20,20000); 23 | in = class.ar( in, SinOsc.ar( modSpeed ).pow( modShape ).exprange( *freq ), res ); 24 | UOut.ar( 0, in ); 25 | }, [ 26 | ArgSpec('freq', [ 20.0, 20000.0 ], 27 | RangeSpec(20, 20000, 0, inf, 'exp', 0, [20.0,20000.0 ], " Hz") 28 | ), 29 | ArgSpec( 'modSpeed', 1, [0.1, 20, 'exp', 0, 1].asSpec ), 30 | ArgSpec( 'modShape', 1, [0, 1, 'lin', 0, 1].asSpec ), 31 | ArgSpec('res', 0.5, [0, 1, 'linear', 0, 0.1].asSpec ) 32 | ], 'filter') 33 | }; -------------------------------------------------------------------------------- /UMapDefs/lag_linear.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \lag_line 3 | 4 | An UMap that slows down value changes over time. It does this by creating a line between the old and new value 5 | 6 | value: the value upon which the lag is applied (this can be another UMap as well) 7 | time: the time it takes to move to the new value 8 | curve: a curve value for the line. 0 means linear, a negative curve makes the value move faster in the beginning, a positive curve makes it move faster at the end. 9 | 10 | The value arg range is mapped to that of the parameter to which the UMap is connected. 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the Unit lib default UMapDefs set 15 | */ 16 | 17 | UMapDef( \lag_line, { |value = 0.0, time = 0.0, curve = 0.0| 18 | Udef.buildUdef.dontStoreSynthDef = true; 19 | UMapOut.kr(value.varlag(time, curve)); 20 | }) 21 | .uchainInitFunc_({ |unit, chain| 22 | var curve; 23 | curve = unit.curve; 24 | unit.def_( \lag ); 25 | unit.type = \linear; 26 | if( curve.notNil ) { unit.curve = curve }; 27 | }) 28 | .setSpec( \time, [0,10,\lin].asSpec ) 29 | .setSpec( \curve, [-40,40,\lin].asSpec ) 30 | .mappedArgs_([ \value ]) 31 | .category_( 'private' ) -------------------------------------------------------------------------------- /UMapDefs/envelope_rel.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \envelope_rel 3 | 4 | An envelope generator of which the duration is automatically scaled to that of the event. 5 | 6 | env: an Env or EnvM object, containing time and level values. 7 | timeScale: if timeScale is 1, the duration of the envelope will become exactly that of the event, lower and higher timeScales result in a shorter and longer envelope durations. 8 | loop: loopmode (0: off, 1: loop, 2: alternate) 9 | delay: delay time before starting the env (not affected by timeScale) 10 | trigger: a trigger that restarts the env 11 | 12 | The env arg range is mapped to that of the parameter to which the UMap is connected. 13 | 14 | -- 15 | this is an UMapDef definition file 16 | part of the Unit lib default UMapDefs set 17 | */ 18 | 19 | UMapDef( \envelope_rel, { 20 | var sig; 21 | sig = UEnvGenRel.kr( \env, nil, \timeScale, \loop, \delay, \trigger ); 22 | UMapOut.kr(sig); 23 | }).mappedArgs_([ \env ]) 24 | .uchainInitFunc_({ |umap, unit| 25 | var filter, invert, active, curve; 26 | if( umap.def.category == \private ) { 27 | umap.defName = \envelope; 28 | umap.set( \timeMode, \relative ) 29 | } 30 | }) 31 | .category_( 'private' ) -------------------------------------------------------------------------------- /UMapDefs/p_crossfade.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \p_crossfade 3 | 4 | Creates an pattern UMap for linear crossfading between two values. 5 | 6 | a: the first value 7 | b: the second value 8 | crossfade: (0-1) the crossfading position (a to b) 9 | 10 | The 'a' and 'b' arg ranges are mapped to that of the parameter to which the UMap is connected 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the Unit lib default UMapDefs set 15 | */ 16 | 17 | UPatDef( \p_crossfade, { |unit, a = 0.0, b = 1.0, crossfade = 0.5| 18 | { 19 | inf.do { |i| 20 | var cf; 21 | cf = crossfade.next; 22 | switch( cf, 23 | 0, { a.next.yield; }, 24 | 1, { b.next.yield; }, 25 | { a.next.blend( b.next, cf ).yield } 26 | ); 27 | }; 28 | }.r; 29 | }).mappedArgs_([\a, \b]) 30 | .useMappedArgs_( false ) 31 | .setSpec( \a, UAdaptSpec() ) 32 | .setSpec( \b, UAdaptSpec() ) 33 | .canUseUMapFunc_({ |unit, key, umapdef| 34 | unit.isKindOf( UPattern ).not && { 35 | [ Point, SimpleNumber, Array ].any({ |class| 36 | unit.getDefault( key ).isKindOf( class ) 37 | }) && { UAdaptSpec().canAdapt( unit.getSpec( key ) ) } 38 | }; 39 | }) 40 | .category_( 'pattern_selection' ); 41 | -------------------------------------------------------------------------------- /UMapDefs/greater_than.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \greater_than 3 | 4 | A comparator. This UMap can switch between two values, depending on two incoming values; a and b. If a > b the UMap outputs trueValue, otherwise it outputs falseValue. All values can be UMaps. 5 | 6 | a: the first value 7 | b: the second value 8 | trueValue: the value (or UMap) to output when a > b 9 | falseValue: the value (or UMap) to output when a <= b 10 | 11 | trueValue and falseValue arg ranges are mapped to that of the parameter to which the UMap is connected. 12 | 13 | -- 14 | this is an UMapDef definition file 15 | part of the Unit lib default UMapDefs set 16 | */ 17 | 18 | HybridUMapDef( \greater_than, { |a = 0.0, b = 0.5, trueValue = 1.0, falseValue = 0.0| 19 | var index, output; 20 | UMapDef.useMappedArgs_( false ); 21 | index = a > b; 22 | output = Select.kr( index, [ falseValue, trueValue ] ); 23 | UMapOut.kr( output ); 24 | }, { |unit, a = 0.0, b = 0.5, trueValue = 1.0, falseValue = 0.0| 25 | if( a > b ) { trueValue } { falseValue }; 26 | }) 27 | .setSpec( \trueValue, UAdaptSpec() ) 28 | .setSpec( \falseValue, UAdaptSpec() ) 29 | .mappedArgs_([ \trueValue, \falseValue ]) 30 | .category_( 'detection' ) -------------------------------------------------------------------------------- /UMapDefs/add.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \add 3 | 4 | Creates an UMap adding (+) two values together. 5 | 6 | input: the value to add to 7 | add: the amount to add 8 | factor: multiplier for add (negative value results in subtraction0 9 | 10 | The 'input' and 'add' arg ranges are mapped to that of the parameter to which the UMap is connected. 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the Unit lib default UMapDefs set 15 | */ 16 | 17 | 18 | HybridUMapDef( \add, { |input = 0.0, add = 0.0, factor = 1| 19 | var sig; 20 | UMapDef.useMappedArgs = false; // use raw values instead of mapped (0-1) 21 | sig = input + (add * factor); 22 | UMapOut.kr(sig); 23 | }, { |unit, input = 0.0, add = 0.0, factor = 1| 24 | (input + (add * factor)).clip( *[unit.spec.minval, unit.spec.maxval] ); 25 | } 26 | ) 27 | .mappedArgs_([ \input, \add ]) 28 | .prepareArgsFunc_({ |args| 29 | var index; 30 | index = args.indexOf( \value ); 31 | if( index.notNil && { index.even }) { 32 | args[index] = \input; 33 | }; 34 | args; 35 | }) 36 | .setSpec( \factor, [-1,1,\lin,0,0].asSpec ) 37 | .setSpec( \input, UAdaptSpec() ) 38 | .setSpec( \add, UAdaptSpec() ) 39 | .category_( 'math' ) -------------------------------------------------------------------------------- /UMapDefs/center_range.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \center_range 3 | 4 | Creates an UMap intended for use on modulatable range parameters. It converts the range into two linear controls: center and range, which on their turn can be used to assign other UMaps to. 5 | 6 | center: the center of the range 7 | range: the width of the range (0-1) 8 | 9 | The 'center' arg range is mapped to that of the parameter to which the UMap is connected. 10 | 11 | -- 12 | this is an UMapDef definition file 13 | part of the Unit lib default UMapDefs set 14 | */ 15 | 16 | HybridUMapDef( \center_range, { |center = 0.5, range = 1.0| 17 | var lo, hi, halfRange; 18 | halfRange = range/2; 19 | center = center.linlin( 0, 1, halfRange, 1-halfRange ); 20 | lo = center - halfRange; 21 | hi = center + halfRange; 22 | UMapOut.kr([lo,hi]); 23 | }, { |unit, center = 0.5, range = 1.0| 24 | var halfRange; 25 | halfRange = range/2; 26 | center = center.linlin( 0, 1, halfRange, 1-halfRange ); 27 | [ center - halfRange, center + halfRange ] 28 | 29 | }) 30 | .mappedArgs_( [ \center ] ) 31 | .canUseUMapFunc_({ |unit, key, umapdef| 32 | unit.getSpec( key ).isKindOf( RangeSpec ); 33 | }) 34 | .category_( 'range' ); 35 | -------------------------------------------------------------------------------- /UMapDefs/phasor.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \phasor 3 | 4 | Creates an UMap with a looping linear ramp, that can be reset via a trigger. 5 | 6 | speed: the speed of the ramp 7 | up: if true (default) the ramp moves upwards, if false the ramp moves downwards 8 | startPos: the start value of the ramp 9 | range: the output range 10 | trigger: if set, the ramp will jump to 'startPos' 11 | 12 | The 'range' arg range is mapped to that of the parameter to which the UMap is connected. 13 | 14 | -- 15 | this is an UMapDef definition file 16 | part of the Unit lib default UMapDefs set 17 | */ 18 | 19 | UMapDef( \phasor, { |speed = 0.1, up = 1, startPos = 0, range = #[0.0,1.0]| 20 | var sig; 21 | var trigger; 22 | trigger = \trigger.utr + Impulse.kr(0); 23 | sig = Phasor.kr(trigger, speed * up.linlin(0,1,-1,1) / ControlRate.ir, 24 | range[0], range[1], (startPos + ( 25 | DC.kr( \u_startPos.ir * speed * (range[1] - range[0]) ) 26 | )).wrap( *range ) 27 | ); 28 | UMapOut.kr(sig); 29 | }) 30 | .setSpec( \up, BoolSpec(true) ) 31 | .setSpec( \startPos, [0,1,\lin,0,0] ) 32 | .setSpec( \speed, [0.001, 100, \exp, 0, 0.1 ] ) 33 | .mappedArgs_( [ \range, \startPos ] ) 34 | .category_( 'modulation' ) 35 | -------------------------------------------------------------------------------- /UnitDefs/decodeB2.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \decodeB2 3 | 4 | Decodes a two dimensional ambisonic B-format signal (FuMa first order) to a set of speaker locations in a regular polygon. The outputs will be in clockwise order. The position of the first speaker location is either center or left of center. 5 | 6 | orientation: Should be zero if the front is a vertex of the polygon. The first speaker location will be directly in front. Should be 0.5 if the front bisects a side of the polygon. Then the first speaker will be the one left of center. 7 | numChannels: number of input channels (*). 8 | 9 | (*) only the following numbers of channels are allowed: 10 | 2,3,4,5,6,7,8,10,12,16,24,32 11 | 12 | -- 13 | this is an Udef definition file 14 | part of the Unit lib default Udefs set 15 | */ 16 | 17 | MultiChannelUdef( \decodeB2, { 18 | var w,x,y, orientation, rotate, mode; 19 | orientation = \orientation.ukr( 0, 0, 0.5, \lin ); 20 | rotate = \rotate.ukr( 0, AngleSpec() ) / pi; 21 | #w,x,y = UIn.ar( 0, 3, true ); 22 | #x,y = Rotate2.ar( x, y, rotate ); 23 | UOut.ar( 0, DecodeB2.ar( Udef.numChannels, w, x, y, orientation ) ); 24 | }, channels: [2,3,4,5,6,7,8,10,12,16,24,32]) 25 | .category_( \utility ) -------------------------------------------------------------------------------- /UMapDefs/lfo_noise.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \lfo_noise 3 | 4 | Creates an UMap with a low frequency noise oscillator. 5 | 6 | freq: the frequency of the noise generator 7 | type: the type of noise: 8 | 0: step or sample-and-hold noise; hard jumps at each value change 9 | 1: linear interpolated noise 10 | 2: cubic interpolated noise 11 | seed: random seed (positive whole number). The same seed will always result in exactly the signal on any computer. 12 | range: the output range 13 | 14 | The 'range' arg is mapped to that of the parameter to which the UMap is connected. 15 | 16 | -- 17 | this is an UMapDef definition file 18 | part of the Unit lib default UMapDefs set 19 | */ 20 | 21 | UMapDef( \lfo_noise, { |freq = 2, type = 2, range = #[0.0,1.0]| 22 | var sig; 23 | URandSeed.ir(); 24 | sig = [ 25 | LFDNoise0.kr( freq ), 26 | LFDNoise1.kr( freq ), 27 | LFDNoise3.kr( freq ), 28 | LFDClipNoise.kr( freq ), 29 | ]; 30 | sig = Select.kr( type, sig ).linlin(-1,1,*range); 31 | UMapOut.kr(sig); 32 | }) 33 | .setSpec( \type, ListSpec([0,1,2,3], 0, [\step, \linear, \cubic, \clip]) ) 34 | .setSpec( \freq, FreqSpec(0.001,300, default: 2) ) 35 | .mappedArgs_( [ \range ] ) 36 | .category_( 'lfo' ) 37 | -------------------------------------------------------------------------------- /UMapDefs/trigger.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \trigger 3 | 4 | This UMap implements a simple trigger signal with a certain duration. For convenience also a linear rise/decay filter, so that users can use this UMap for simple envelope creation 5 | 6 | trigger: the trigger 7 | time: trigger duration (if 0, it will be a single frame) 8 | rise: a linear lag time before the value reaches it's maximum 9 | decay: a linear lag time before the value reaches it's minimum after the trigger time has ended 10 | range: the value range (when triggered, the value moves from the lower to the upper limit of the range) 11 | 12 | The 'range' arg range is mapped to that of the parameter to which the UMap is connected. 13 | 14 | -- 15 | this is an UMapDef definition file 16 | part of the Unit lib default UMapDefs set 17 | */ 18 | 19 | UMapDef( \trigger, { 20 | var index, output; 21 | index = Trig.kr( \trigger.tr, \time.kr(0.0) ); 22 | index = Slew.kr(index, 1 / \rise.kr(0.0), 1 / \decay.kr(0.0) ); 23 | output = LinSelectX.kr( index, \range.kr([0.0,1.0]) ); 24 | UMapOut.kr( output ); 25 | }) 26 | .mappedArgs_([ \range ]) 27 | .setSpec( \time, SMPTESpec(0,3600) ) 28 | .setSpec( \trigger, TriggerSpec() ) 29 | .category_( 'trigger' ) -------------------------------------------------------------------------------- /UMapDefs/line.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \line 3 | 4 | An line / ramp generator. 5 | 6 | a: start value 7 | b: end value 8 | curve: a curve value for the line. A 0 (zero) curve creates a linear line, a positive curve value makes the line tend towards the start value, and v.v. 9 | duration: duration of the line in seconds (can be modulated) 10 | loop: loopmode (0: off, 1: loop, 2: alternate) 11 | delay: delay time before the line starts 12 | trigger: a trigger that restarts the line 13 | 14 | The 'range' arg range is mapped to that of the parameter to which the UMap is connected. 15 | 16 | -- 17 | this is an UMapDef definition file 18 | part of the Unit lib default UMapDefs set 19 | */ 20 | 21 | UMapDef( \line, { |a = 0.0, b = 1.0, curve = 0, duration = 10| 22 | var sig; 23 | duration = duration.max( ControlDur.ir + SampleDur.ir ); 24 | sig = ULine.kr( 0, 1, duration, \loop, \delay, \trigger ); 25 | sig = Select.kr( curve.inRange(-0.001,0.001), [ 26 | sig.lincurve(0, 1, a, b, curve ), 27 | sig.linlin(0, 1, a, b ) 28 | ]); 29 | UMapOut.kr(sig); 30 | }) 31 | .setSpec( \curve, [-16,16,\lin,0,0].asSpec ) 32 | .setSpec( \duration, SMPTESpec() ) 33 | .category_( 'automation' ) 34 | .mappedArgs_( [ \a, \b ] ); -------------------------------------------------------------------------------- /Classes/GUI/plusMenu-uFront.sc: -------------------------------------------------------------------------------- 1 | + Menu { 2 | uFront { 3 | |point, action| 4 | var tempAction; 5 | point = point ?? { QtGUI.cursorPosition; }; 6 | action = action ?? { tempAction = MenuAction(); }; 7 | this.invokeMethod(\popup, [point, action]); 8 | tempAction !? _.destroy; 9 | } 10 | 11 | deepDestroy { 12 | this.actions.do({ |act| 13 | if( act.menu.notNil ) { 14 | act.menu.deepDestroy; 15 | }; 16 | act.destroy; 17 | }); 18 | this.destroy; 19 | } 20 | } 21 | 22 | + AbstractMenuAction { 23 | 24 | deepDestroy { 25 | this.menu !? _.deepDestroy; 26 | this.destroy; 27 | } 28 | 29 | } 30 | 31 | + MainMenu { 32 | 33 | *registerNoUpdate { 34 | |action, menu, group=\none| 35 | var menuList, existingIndex; 36 | 37 | menu = menu.asSymbol; 38 | group = group.asSymbol; 39 | 40 | menuList = this.prGetMenuGroup(menu, group); 41 | existingIndex = menuList.detectIndex({ |existing| existing.string == action.string }); 42 | if (existingIndex.notNil) { 43 | "Menu item '%' replaced an existing menu".format(action.string).warn; 44 | menuList[existingIndex] = action; 45 | } { 46 | menuList.add(action); 47 | }; 48 | 49 | //this.prUpdate(); 50 | } 51 | } -------------------------------------------------------------------------------- /UMapDefs/delay.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \delay 3 | 4 | This UMapDef creates an UMap for delaying value changes. The delay time itself can also be modulated. 5 | 6 | value: the value (or UMap) to be delayed 7 | time: the length of the delay. 8 | timeScale: the number of seconds by which 'time' is multiplied. This value can not be changed during playback. 9 | lag: smoothing time applied to change of delay time, use to prevent sudden jumps during change of delay time. 10 | 11 | The 'value' arg range is mapped to that of the parameter to which the UMap is connected. 12 | 13 | -- 14 | this is an Udef definition file 15 | part of the Unit lib default Udefs set 16 | */ 17 | 18 | 19 | UMapDef( \delay, { |value = 0.0, time = 0.1, timeScale = 1, lag = 0| 20 | var delayed; 21 | time = time.lag3( lag ) * timeScale; 22 | delayed = DelayC.kr( value, timeScale * 2, time ); 23 | delayed = Select.kr( Line.kr(0,1,time) >= 1, [Latch.kr( value, Impulse.kr(0) ), delayed] ); 24 | UMapOut.kr( delayed ) 25 | } ) 26 | .category_( \filter ) 27 | .setSpec( \time, [ 0, 2, \lin, 0, 0.1 ] ) 28 | .setSpec( \timeScale, ListSpec([0.1,1,10],1,["0.1s", "1s", "10s"]), \init ) 29 | .setSpec( \lag, [0,1,\lin].asSpec ) 30 | .mappedArgs_([ \value ]); -------------------------------------------------------------------------------- /UMapDefs/linear.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \linear 3 | 4 | gives an arg that doesn't have a linear ArgSpec a linear warp in the same range. For example; \freq args usually have non-linear warps (\exp in this case), as well as \amp args. 5 | 6 | input: the value to be mapped (0-1) 7 | 8 | The 'input' arg range is mapped to that of the parameter to which the UMap is connected. 9 | 10 | -- 11 | this is an UMapDef definition file 12 | part of the Unit lib default UMapDefs set 13 | */ 14 | 15 | HybridUMapDef( \linear, { |input = 0.5| 16 | UMapDef.useMappedArgs = false; 17 | UMapOut.kr(input); 18 | }, { |unit, input = 0.5| 19 | input 20 | }) 21 | .mappedArgs_( [ \input ] ) 22 | .setSpec( \input, UAdaptSpec({ |sp| sp.copy.warp_( \lin ) }) ) 23 | .prepareArgsFunc_({ |args| 24 | var index; 25 | index = args.indexOf( \value ); 26 | if( index.notNil && { index.even }) { 27 | args[index] = \input; 28 | }; 29 | args; 30 | }) 31 | .canUseUMapFunc_({ |unit, key, umapdef| 32 | var spec; 33 | UMapDef.defaultCanUseUMapFunc.value( unit, key, umapdef ) && { 34 | spec = unit.getSpec( key ); 35 | spec.respondsTo( \warp_ ) && { spec.warp.isKindOf( LinearWarp ).not }; 36 | }; 37 | }) 38 | .category_( 'convert' ) 39 | 40 | 41 | -------------------------------------------------------------------------------- /Examples/UChain example.scd: -------------------------------------------------------------------------------- 1 | ( 2 | // create some Udefs 3 | 4 | Udef( \mix2, { |balance = 0.5| 5 | var l1, l2; 6 | l1 = UIn.ar( 0 ) * (1-balance); 7 | l2 = UIn.ar( 1 ) * balance; 8 | UOut.ar( 0, l1 + l2 ) 9 | } ).loadSynthDef; 10 | 11 | Udef( \vibrato, { |rate = 1, amount = #[0.0,1.0]| 12 | UOut.ar( 0, SinOsc.kr( rate ).range(*amount) * UIn.ar( 0 ) ) 13 | } ).loadSynthDef; 14 | 15 | ) 16 | 17 | // \sine and \output are already in the Udef bank 18 | 19 | x = UChain( \sine, [ \sine, [ \freq, 550, \u_o_ar_0_bus, 1 ]], \mix2, \vibrato, \output ); 20 | 21 | y = UChain( [ \sine, [ \freq, 660 ] ], \output ); 22 | 23 | s.notify; // make sure the server is notified!! 24 | 25 | x.prepareAndStart; 26 | x.release; 27 | 28 | x.fadeOut = 0.5; 29 | x.fadeIn = 0.5; 30 | 31 | x.setDur( 5 ); 32 | x.setDur( inf ); // infinite duration (default) 33 | 34 | x[1].setAudioOut( 0, 1 ); // 2nd sine output to bus 1, so it goes to second mix input 35 | 36 | x.gui; // gui without styling 37 | y.gui; 38 | 39 | ( // gui with styling 40 | w = Window( "x", Rect( 300,25,200,300 ) ).front; 41 | RoundView.useWithSkin( ( 42 | labelWidth: 40, 43 | font: Font( Font.defaultSansFace, 10 ), 44 | hiliteColor: Color.gray(0.33) 45 | ), { x.gui(w); }; 46 | ); 47 | ) -------------------------------------------------------------------------------- /Classes/Core/MassEditUPattern.sc: -------------------------------------------------------------------------------- 1 | MassEditUPattern : MassEditU { 2 | 3 | init { |inUnits, active = true| 4 | var firstDef, defs; 5 | var dkey, dval; 6 | units = inUnits.asCollection; 7 | if( units.every({ |item| item.isKindOf( UPattern ) }) ) { 8 | def = units[0]; 9 | argSpecs = def.argSpecs( inUnits[0] ); 10 | 11 | argSpecs = argSpecs.collect({ |argSpec| 12 | var values, massEditSpec, value; 13 | values = units.collect({ |unit| 14 | unit.get( argSpec.name ); 15 | }); 16 | 17 | if( values.any(_.isUMap) ) { 18 | massEditSpec = MassEditUMapSpec( MassEditUMap( values ) ); 19 | } { 20 | if( argSpec.name != \fadeTimes ) { 21 | massEditSpec = argSpec.spec.massEditSpec( values ); 22 | }; 23 | }; 24 | if( massEditSpec.notNil ) { 25 | ArgSpec( argSpec.name, massEditSpec.default, massEditSpec, 26 | argSpec.private, argSpec.mode ); 27 | } { 28 | nil; 29 | }; 30 | }).select(_.notNil); 31 | 32 | args = argSpecs.collect({ |item| [ item.name, item.default ] }).flatten(1); 33 | if( active == true ) { this.changed( \init ); }; 34 | } { 35 | "MassEditUPattern:init - not all units are of the same Udef".warn; 36 | }; 37 | } 38 | 39 | defName { ^\UPattern } 40 | } -------------------------------------------------------------------------------- /UMapDefs/p_sine.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \p_sine 3 | 4 | Creates an pattern UMap for sine wave. New values are generated each time the chain is started, or in a UPattern for each of the generated events. 5 | 6 | freq: the frequency of the sine wave 7 | phase: (-pi - pi) the start phase of the sine wave (can be modulated) 8 | min: lowest output value 9 | max: highest output value 10 | 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the Unit lib default UMapDefs set 15 | */ 16 | 17 | UPatDef( \p_sine, { |unit, 18 | freq = 0.1, 19 | phase = 0, 20 | min = 0.0, 21 | max = 1.0, 22 | timeBase = \seconds| 23 | { 24 | var i = 0; 25 | var timer = UPattern.deltaTimer; 26 | if( timeBase.next === \seconds ) { 27 | i = freq.next * UPattern.startPos; 28 | }; 29 | loop { 30 | (((i % 1) * 2pi) + phase.next).sin.linlin(-1,1,min.next,max.next).yield; 31 | switch( timeBase.next, 32 | \events, { i = i + freq.next; }, 33 | \seconds, { i = i + (freq.next * timer.value); }, 34 | ); 35 | }; 36 | }.r 37 | }).category_( 'pattern_timebased' ) 38 | .mappedArgs_( [ \min, \max ] ) 39 | .setSpec( \phase, AngleSpec() ) 40 | .setSpec( \freq, FreqSpec(0.001,300, default: 2) ) 41 | .setSpec( \timeBase, ListSpec( [ 'events', 'seconds' ] ) ); -------------------------------------------------------------------------------- /UMapDefs/schmidt.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \schmidt 3 | 4 | This UMap can switch between two values, depending on an incoming value. If the value passes the upper range boundary, the output will become 'true'. If there-after the value passes the lower range value, the output will become 'false'. The range between the upper and lower value is known as "hysteresis". If the lower and upper value of the range are the same, the UMap will behave as a simple treshold comparator. All parameters can be UMaps. 5 | 6 | value: the value to test (0-1) 7 | range: the Schmidt range (explanation above) 8 | trueValue: the value (or UMap) to output when the result is true 9 | falseValue: the value (or UMap) to output when the result is false 10 | 11 | trueValue and falseValue arg ranges are mapped to that of the parameter to which the UMap is connected. 12 | 13 | -- 14 | this is an UMapDef definition file 15 | part of the Unit lib default UMapDefs set 16 | */ 17 | 18 | UMapDef( \schmidt, { |value = 0.0, range = #[0.25,0.75], trueValue = 1.0, falseValue = 0.0| 19 | var index, output; 20 | index = Schmidt.kr( value, *range ); 21 | output = Select.kr( index, [ falseValue, trueValue ] ); 22 | UMapOut.kr( output ); 23 | }) 24 | .mappedArgs_([ \trueValue, \falseValue ]) 25 | .category_( 'detection' ) -------------------------------------------------------------------------------- /UMapDefs/pulse_divider.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \pulse_divider 3 | 4 | This UMap implements a pulse divider. The incoming trigger pulses are counted and every 'division' times one is passed through. 5 | 6 | trigger: the trigger 7 | division: number of pulses to divide 8 | offset: start offset for pulse division (0 means first trigger always gets through) 9 | time: the time to hold the trigger. If a new trigger occurs within this time it is ignored. 10 | range: the output range; a passed through trigger makes the output jump from the range minimum to maximum. 11 | 12 | The 'range' arg range is mapped to that of the parameter to which the UMap is connected. 13 | 14 | -- 15 | this is an UMapDef definition file 16 | part of the Unit lib default UMapDefs set 17 | */ 18 | 19 | UMapDef( \pulse_divider, { 20 | var index, output; 21 | index = \trigger.tr; 22 | index = PulseDivider.kr( index, \division.kr(2), \offset.ir(0) ); 23 | index = Trig.kr( index, \time.kr(0.0) ); 24 | output = LinSelectX.kr( index, \range.kr([0.0,1.0]) ); 25 | UMapOut.kr( output ); 26 | }) 27 | .mappedArgs_([ \range ]) 28 | .setSpec( \division, IntegerSpec(2,1,inf) ) 29 | .setSpec( \offset, IntegerSpec(0,0,inf), \init ) 30 | .setDefault( \offset, 0 ) 31 | .setSpec( \trigger, TriggerSpec() ) 32 | .category_( 'trigger' ) -------------------------------------------------------------------------------- /Classes/Misc/IndexL2D.sc: -------------------------------------------------------------------------------- 1 | IndexL2D { 2 | 3 | /* 4 | accepts a buffer of any number of channels/frames and lets you treat it as a 2-dimensional table 5 | */ 6 | 7 | *ar { arg bufnum, frame = 0, channel = 0, autoScale = false; 8 | var numChannels; 9 | numChannels = BufChannels.kr(bufnum); 10 | if( autoScale.booleanValue == true ) { 11 | frame = frame.linlin(0, 1, 0, BufFrames.kr( bufnum ) - 1, \minmax ); 12 | channel = channel.linlin(0, 1, 0, numChannels - 1, \minmax ); 13 | }; 14 | ^LinXFade2.ar( 15 | IndexL.ar( bufnum, (frame.round(2) * numChannels) + channel ), 16 | IndexL.ar( bufnum, ((frame.trunc(2) + 1) * numChannels) + channel ), 17 | (frame * 2 - 1).fold2(1) 18 | ); 19 | } 20 | 21 | *kr { arg bufnum, frame = 0, channel = 0, autoScale = false; 22 | var numChannels; 23 | numChannels = BufChannels.kr(bufnum); 24 | if( autoScale.booleanValue == true ) { 25 | frame = frame.linlin(0, 1, 0, BufFrames.kr( bufnum ) - 1, \minmax ); 26 | channel = channel.linlin(0, 1, 0, numChannels - 1, \minmax ); 27 | }; 28 | ^LinXFade2.kr( 29 | IndexL.kr( bufnum, (frame.round(2) * BufChannels.ir(bufnum)) + channel ), 30 | IndexL.kr( bufnum, ((frame.trunc(2) + 1) * BufChannels.ir(bufnum)) + channel ), 31 | (frame * 2 - 1).fold2(1) 32 | ); 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /UMapDefs/ringz.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \ringz 3 | 4 | Creates an UMap that routes an input value through a ringing filter with attack and decay and adds the result to the original value. This causes oscillations to happen at value changes. 5 | 6 | value: the value upon which the lag is applied (this can be another UMap as well) 7 | freq: the frequency of the filter. Rapid changes of this value may cause the filter to be temporarily unstable 8 | attackTime: the attack time of the 9 | decayTime: the decay time of the ringing filter 10 | amp: amplitude of the ringing filter 11 | 12 | The value arg range is mapped to that of the parameter to which the UMap is connected. 13 | 14 | -- 15 | this is an UMapDef definition file 16 | part of the Unit lib default UMapDefs set 17 | */ 18 | 19 | UMapDef( \ringz, { |value = 0.5, freq = 2, attackTime = 0.001, decayTime = 1, amp = 0.1| 20 | var sig, scaledValue; 21 | scaledValue = (value - DC.kr( value )); 22 | sig = Formlet.kr( scaledValue, freq, attackTime, decayTime ) * amp; 23 | sig = (sig + value).clip(0,1); 24 | UMapOut.kr( sig ); 25 | }) 26 | .setSpec( \freq, FreqSpec(0.01,300, default: 2) ) 27 | .setSpec( \attackTime, [0.001,10,\exp, 0, 1].asSpec ) 28 | .setSpec( \decayTime, [0.001,10,\exp, 0, 1].asSpec ) 29 | .mappedArgs_([ \value ]) 30 | .category_( 'filter' ) -------------------------------------------------------------------------------- /Classes/Extensions/extEZGui-makeParentView.sc: -------------------------------------------------------------------------------- 1 | /* 2 | Unit Library 3 | The Game Of Life Foundation. http://gameoflife.nl 4 | Copyright 2006-2011 Miguel Negrao, Wouter Snoei. 5 | 6 | GameOfLife Unit Library: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | GameOfLife Unit Library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with GameOfLife Unit Library. If not, see . 18 | */ 19 | 20 | + EZGui { 21 | *makeParentView { |parent, bounds| 22 | var new, view, margin, gap; 23 | // extracts the window making capacities of EZGui, disregards the rest 24 | new = this.new; 25 | #view, bounds = new.prMakeMarginGap(parent).prMakeView(parent, bounds ? (350@20) ); 26 | margin = new.slotAt( \margin ); 27 | gap = new.slotAt( \gap ); 28 | ^[ view, bounds, margin, gap ] 29 | } 30 | } -------------------------------------------------------------------------------- /UMapDefs/poll.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \poll 3 | 4 | An UMap that posts incoming values in the 'post' window. The value itself is passed through unchanged. 5 | 6 | value: the value to be posted 7 | trigger: a trigger causes the value to be posted 8 | onChange: when true, the value will be posted whenever it changes (can result in many posts) 9 | speed: number of times per second to post the value automatically (default 0 - no automatic posting). 10 | 11 | The value arg range is mapped to that of the parameter to which the UMap is connected. 12 | 13 | -- 14 | this is an UMapDef definition file 15 | part of the Unit lib default UMapDefs set 16 | */ 17 | 18 | UMapDef( \poll, { |value = 0.0| 19 | var speed, trigger, change, onChange, mappedVal; 20 | trigger = \trigger.tr( 1 ); 21 | onChange = \onChange.kr( 0 ); 22 | speed = \speed.kr( 0 ); 23 | change = HPZ1.kr( value ).abs > 0; 24 | change = (HPZ1.kr( change ).abs > 0) + (TDuty.kr( 0.1, change ) * change); 25 | change = change * onChange; 26 | Poll.kr( Impulse.kr( speed ) + trigger + change, 27 | \u_spec.asSpecMapKr( value ), 28 | "poll" ); 29 | UMapOut.kr(value); 30 | }) 31 | .setSpec( \onChange, BoolSpec( false ) ) 32 | .setSpec( \speed, [0,20,\lin,0,0].asSpec ) 33 | .setSpec( \trigger, TriggerSpec( ) ) 34 | .mappedArgs_([ \value ]) 35 | .category_( 'utility' ) -------------------------------------------------------------------------------- /UMapDefs/in_range.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \in_range 3 | 4 | This UMap can switch between two values, depending on an incoming value. If the value is in between the lower and higher value of the range, the result is 'true', otherwise it is 'false'. All parameters can be UMaps. 5 | 6 | input: the value to test (0-1) 7 | range: the range (explanation above) 8 | trueValue: the value (or UMap) to output when the result is true 9 | falseValue: the value (or UMap) to output when the result is false 10 | 11 | trueValue and falseValue arg ranges are mapped to that of the parameter to which the UMap is connected. 12 | 13 | -- 14 | this is an UMapDef definition file 15 | part of the Unit lib default UMapDefs set 16 | */ 17 | 18 | HybridUMapDef( \in_range, { |input = 0.0, range = #[0.25,0.75], trueValue = 1.0, falseValue = 0.0| 19 | var index, output; 20 | UMapDef.useMappedArgs_( false ); 21 | index = InRange.kr( input, *range ); 22 | output = Select.kr( index, [ falseValue, trueValue ] ); 23 | UMapOut.kr( output ); 24 | }, { |unit, input = 0.0, range = #[0.25,0.75], trueValue = 1.0, falseValue = 0.0| 25 | if( input.inclusivelyBetween(*range ) ) { trueValue } { falseValue }; 26 | }) 27 | .setSpec( \trueValue, UAdaptSpec() ) 28 | .setSpec( \falseValue, UAdaptSpec() ) 29 | .mappedArgs_([ \trueValue, \falseValue ]) 30 | .category_( 'detection' ) -------------------------------------------------------------------------------- /Examples/UEnvGen examples.scd: -------------------------------------------------------------------------------- 1 | ( 2 | Udef(\test, { 3 | var env = UEnvGen.ar( Env([0.3,0.4,0.2,0.3], [2.0,2.0,2.0], \lin), \freq); 4 | var out = SinOsc.ar( env ) * 0.2; 5 | UOut.ar(0, out ) 6 | }); 7 | Udef(\test2, { 8 | var env = ULine.ar(200,400, 10, \freq); 9 | var out = SinOsc.ar( env ) * 0.2; 10 | UOut.ar(0, out ) 11 | }) 12 | .setSpec(\freq, RangeSpec(20,20000)); 13 | Udef(\test1Rel, { 14 | var env = UEnvGenRel.ar( Env([0.3,0.4,0.2,0.3], [2.0,2.0,2.0], \lin), \freq); 15 | var out = SinOsc.ar( env ) * 0.2; 16 | UOut.ar(0, out ) 17 | }); 18 | Udef(\test2Rel, { 19 | var env = UXLineRel.ar(200, 400); 20 | var out = SinOsc.ar( env ) * 0.2; 21 | UOut.ar(0, out ) 22 | }) 23 | .setSpec(\freq, RangeSpec(20,20000) ) 24 | ) 25 | 26 | ( 27 | UScore( 28 | UChain(0,0,6, \test, \stereoOutput), 29 | UChain(3,1,10, \test2, \stereoOutput) 30 | ).gui 31 | ) 32 | 33 | 34 | ( 35 | //change dur, run again 36 | var dur = 4; 37 | UScore( 38 | UChain(0,0,dur, \test1Rel, \stereoOutput), 39 | UChain(0,1,dur, \test2Rel, \stereoOutput) 40 | ).gui 41 | ) 42 | 43 | ( 44 | Udef(\test3Rel, { 45 | var env = UEnvGenRel.ar(\uenv, \freq); 46 | var out = SinOsc.ar( env ) * 0.2; 47 | UOut.ar(0, out ) 48 | }).setDefault( \uenv, Env([0.5,0.75,0.3,0.8],[0.1,0.5,0.4]) ); 49 | ) 50 | 51 | ( 52 | UScore( 53 | UChain(0,0,1, \test3Rel, \stereoOutput) 54 | ).gui 55 | ) -------------------------------------------------------------------------------- /UnitDefs/output.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \output 3 | 4 | Sends sounds from the previous units in the UChain to hardware output busses. 5 | WFSCollider users: This sends only to the outputs of the master server. To send to individual speakers on the WFS system, use wfsIndex instead. To send output "the official way" only to the outputs of the master audio interface, use the wfsMasterOut Udef instead (and set "toServers" to false if you really want the analog outputs of the master interface) 6 | 7 | bus: the channels are sent out starting with this bus. 8 | numChannels: number of channels (*). 9 | 10 | (*) only the following numbers of channels are allowed: 11 | 1,2,3,4,5,6,7,8,10,12,16,24,32 12 | 13 | -- 14 | this is an Udef definition file 15 | part of the Unit lib default Udefs set 16 | */ 17 | 18 | var def = MultiChannelUdef( \output, { |bus, useGlobalGain = 1| 19 | Out.ar( bus, UGlobalEQ.ar( UIn.ar( 0, Udef.numChannels, endPoint: true ) ) * UEnv.kr( 20 | extraSilence: 0.2, 21 | useGlobalGain: useGlobalGain 22 | ) ); 23 | }) 24 | .category_( \output ) 25 | .setSpec( \useGlobalGain, BoolSpec(true) ) 26 | .shouldPlayOnFunc_({ |unit, target| 27 | target.asTarget.server.isLocal; // safety measure: no output on wfs servers 28 | }); 29 | 30 | def.udefs.do({ |def| 31 | def.setSpec( \bus, HardwareBusSpec(\output, def.name ) ); 32 | }); 33 | 34 | def -------------------------------------------------------------------------------- /UnitDefs/shared_buffer.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \shared_buffer 3 | 4 | ** this Udef should be used in conjunction with 'shared_buffer_in' UMaps ** 5 | 6 | The 'shared_buffer' Udef creates a unit that is able to share a (soundfile) buffer or UMap with other units further in the chain. The 'shared_buffer' unit needs to before the units that use it in the order of the chain. To retreive the value in an other unit use the 'shared_buffer_in' UMapDef, and make sure the 'id' setting is the same on both. The buffer will always be mono (for multichannel audiofiles only the first channel will be loaded). 7 | 8 | soundFile: a soundfile object of which the buffer will be shared. Note: the 'rate' and 'loop' settings of the soundfile are ignored, and can be set separately in the corresponding shared_buffer_in UMaps. 9 | id: the id (0-99) by which the buffer can be retreived by a 'shared_buffer_in' UMap. In the GUI this will show up as a colored box, which can be dragged and dropped onto the receiving unit. 10 | 11 | -- 12 | this is an Udef definition file 13 | part of the Unit lib default UDefs set 14 | */ 15 | 16 | Udef( \shared_buffer, { |soundFile = #[0,1,0]| 17 | UEnv.kr( extraSilence: 0.2, useGlobalGain: 0 ); 18 | USharedBufferOut.kr( \id, soundFile[0] ); 19 | }) 20 | .setSpec( \soundFile, MonoBufSndFileSpec() ) 21 | .setDefault( \soundFile, nil ) 22 | .category_( 'shared_io' ); -------------------------------------------------------------------------------- /UMapDefs/envelope.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \envelope 3 | 4 | An envelope generator. 5 | 6 | env: an Env or EnvM object, containing time and level values. 7 | timeScale: a scale for the time/duration of the Env (can be modulated) 8 | loop: loopmode (0: off, 1: loop, 2: alternate) 9 | delay: delay time before starting the env (not affected by timeScale) 10 | trigger: a trigger that restarts the env 11 | timeMode: \absolute or \relative: 12 | \absolute will use the duration specified in the Env object (a sum of the level values) 13 | \relative will scale the duration of the Env to that of the UChain 14 | 15 | The env arg range is mapped to that of the parameter to which the UMap is connected. 16 | 17 | -- 18 | this is an UMapDef definition file 19 | part of the Unit lib default UMapDefs set 20 | */ 21 | 22 | var defs; 23 | 24 | defs = [ 25 | UMapDef( \absolute, { 26 | var sig; 27 | sig = UEnvGen.kr( \env, nil, \timeScale, \loop, \delay, \trigger ); 28 | UMapOut.kr(sig); 29 | }, addToAll: false, extraPrefix: "envelope" ).mappedArgs_([ \env ]), 30 | UMapDef( \relative, { 31 | var sig; 32 | sig = UEnvGenRel.kr( \env, nil, \timeScale, \loop, \delay, \trigger ); 33 | UMapOut.kr(sig); 34 | }, addToAll: false, extraPrefix: "envelope" ).mappedArgs_([ \env ]) 35 | ]; 36 | 37 | MultiUMapDef( \envelope, defs, \automation, \timeMode, false, true ) 38 | .mappedArgs_([ \env ]) -------------------------------------------------------------------------------- /Classes/Misc/Angle.sc: -------------------------------------------------------------------------------- 1 | /* 2 | Unit Library 3 | The Game Of Life Foundation. http://gameoflife.nl 4 | Copyright 2006-2011 Miguel Negrao, Wouter Snoei. 5 | 6 | GameOfLife Unit Library: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | GameOfLife Unit Library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with GameOfLife Unit Library. If not, see . 18 | */ 19 | 20 | // a simple class mainly to display an angle in a compileString 21 | 22 | Angle { 23 | 24 | var <>value; 25 | 26 | *new { |value| 27 | ^super.newCopyArgs( value ? 0); 28 | } 29 | 30 | printOn { |stream| 31 | stream << case { 32 | value == 0 33 | } { 34 | value 35 | } { 36 | value == pi 37 | } { 38 | "pi" 39 | } { 40 | (value / pi).asString ++ "pi" 41 | }; 42 | } 43 | storeOn { |stream| 44 | this.printOn( stream ); 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /Classes/GUI/Core/UdefsGUI.sc: -------------------------------------------------------------------------------- 1 | UdefsGUI { 2 | 3 | classvar <>current; 4 | 5 | var _: an arg with the correct spec for the correct parameter 18 | ... etc 19 | 20 | ArraySpec: 21 | value: the value at index 22 | 23 | all arg ranges are mapped to that of the parameter to which the UMap is connected. 24 | This UMapDef replaces the former 'lo_hi' and 'x_y' UMapDefs, which are now automatically re-routed to 'expand'. 25 | 26 | -- 27 | this is an UMapDef definition file 28 | part of the Unit lib default UMapDefs set 29 | */ 30 | 31 | ExpandUMapDef( \expand, { |unit| 32 | var specs; 33 | specs = unit.spec.expandArgSpecs; 34 | if( unit.unitArgMode.notNil ) { 35 | specs.do({ |spec| spec.mode = unit.unitArgMode }) 36 | }; 37 | specs; 38 | }, \convert ) 39 | .canUseUMapFunc_({ |unit, key, umapdef| 40 | unit.getSpec( key ).respondsTo( \expandArgSpecs ); 41 | }); -------------------------------------------------------------------------------- /UnitDefs/magFreeze.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \magFreeze 3 | 4 | An FFT-based (spectral) Udef that is able to freeze the magnitude of an incoming audio signal. The freeze parameter (named 'hold') can be modulated. There is also the option to convolve the signal with noise, effectively randomizing the phase information. 5 | 6 | fftSize: (512, 1024, 2048 or 4096) the window size of the FFT. Smaller windows result in faster response but more side effects 7 | hold: (0-1/false-true) freeze magnitudes when true/1 8 | amp: amplitude of output signal 9 | noise: the amount of convolved noise signal 10 | seed: random seed of the noise 11 | 12 | -- 13 | this is an Udef definition file 14 | part of the Unit lib default Udefs set 15 | */ 16 | 17 | Udef( \magFreeze, { |fftSize = 4096, hold = 0, amp = 0.1, noise = 0.0| 18 | var sig, fft1, fft2, conv, normal, delay; 19 | URandSeed.ir(); 20 | sig = UIn.ar( 0, Udef.numChannels ); 21 | fft1 = FFT( LocalBuf(fftSize).clear, sig ); 22 | fft2 = FFT( LocalBuf(fftSize).clear, WhiteNoise.ar(0.05) ); 23 | fft1 = PV_MagFreeze( fft1, hold.round(1)); 24 | fft2 = PV_MagMul( fft2, fft1 ); 25 | conv = IFFT.ar( fft2 ) * 1; 26 | normal = IFFT.ar( fft1 ) * 1; 27 | sig = XFade2.ar( normal, conv, noise.linlin(0,1,-1,1) ); 28 | UOut.ar( 0, sig * amp ); 29 | }) 30 | .setSpec( \hold, BoolSpec(false) ) 31 | .setSpec( \fftSize, ListSpec([512,1024,2048,4096]), \init) 32 | .category_( \effect ); -------------------------------------------------------------------------------- /UnitDefs/mda_piano.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \mda_piano 3 | 4 | A piano synthesiser (originally a VST plugin by Paul Kellett, ported to SC by Dan Stowell). Plays a single piano note at any desired frequency. The Udef provides a 2-channel output. 5 | 6 | freq: pitch of the piano note. 7 | vel: velocity 8 | decay: decay time (0-1) 9 | hard: hardness of attack (0-1) 10 | muffle: amount of muffling (0-1) 11 | stereo: amount of stereo width (0-1) 12 | sustain: if on, the piano sustain pedal is emulated 13 | amp: amplitude (0-1) 14 | trigger: retriggers the note at the current freq. 15 | 16 | -- 17 | this is an Udef definition file 18 | part of the Unit lib default Udefs set 19 | */ 20 | var class; 21 | 22 | class = 'MdaPiano'.asClass; 23 | 24 | if( class.notNil ) { 25 | Udef(\mda_piano,{ |freq = 440, vel = 0.8, decay = 0.8, hard = 0.8, muffle = 0.8, stereo = 0.2, sustain = 0, amp = 0.1| 26 | var sig, detune, midi, trigger; 27 | trigger = \trigger.tr(0); 28 | midi = freq.clip(20,20000).cpsmidi; 29 | detune = ((midi - midi.round(1))) + 0.5; 30 | freq = midi.round(1).midicps; 31 | sig = class.ar( freq, 1 - trigger, vel * 127, decay, 0.8, hard, 0.8, muffle, 0.8, 0.8, stereo, detune, 0.1, 0.1, sustain ) * amp; 32 | UMixOut.ar(0, sig, 0, true ); 33 | }).category_( \synthesis ) 34 | .setSpec( \trigger, TriggerSpec() ) 35 | .setSpec( \gate, BoolSpec(true) ) 36 | .setSpec( \sustain, BoolSpec(false) ); 37 | }; -------------------------------------------------------------------------------- /UMapDefs/p_wchoose.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \p_wchoose 3 | 4 | Creates an pattern UMap that chooses between multiple values, with an optional exclusion history. To use UMaps as values, apply an 'expand' UMap to the 'vals' parameter. 5 | 6 | 7 | vals: values to choose from 8 | histSize: size of history buffer; the amount of steps before a value can repeat itself. 9 | seed: random seed. 10 | n: total number of values. 11 | 12 | The 'vals' arg ranges are mapped to that of the parameter to which the UMap is connected 13 | 14 | -- 15 | this is an UMapDef definition file 16 | part of the Unit lib default UMapDefs set 17 | */ 18 | 19 | var defs; 20 | 21 | defs = [ 4, 8,12,16,24,32,48,64,128 ].collect({ |n| 22 | UPatDef( n, { |unit, vals, weights, seed| 23 | { 24 | thisThread.randSeed = seed.next.asControlInput; 25 | loop { 26 | vals.at( (..n-1).wchoose( weights.next.normalizeSum ) ).yield; 27 | }; 28 | }.r 29 | }, addToAll: false ) 30 | .category_( \pattern ) 31 | .setSpec( \seed, URandSeed ) 32 | .setDefault( \seed, URandSeed() ) 33 | .setSpec( \vals, ArrayControlSpec(0,1,\lin,default: 0.5!n ).size_(n) ) 34 | .setSpec( \weights, ArrayControlSpec(0,1,\lin,default: 0.5!n ).size_(n) ) 35 | .mappedArgs_([ \vals ]); 36 | }); 37 | 38 | MultiUMapDef( \p_wchoose, defs, \pattern_random, \n, false ) 39 | .mappedArgs_([ \vals ]) 40 | .defaultDefName_( 8 ) 41 | .allowedModes_([ \init, \sync, \normal ]) -------------------------------------------------------------------------------- /UMapDefs/polar.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \polar 3 | 4 | Creates an UMap intended for use on modulatable point parameters. It converts the point into a polar, with linear controls for rho and theta, which on their turn can be used to assign other UMaps to. 5 | 6 | rho: the rho value (distance from 0@0) 7 | theta: the theta value (angle from 0@0 ) 8 | 9 | The 'rho' arg range is mapped to that of the parameter to which the UMap is connected. 10 | 11 | -- 12 | this is an UMapDef definition file 13 | part of the Unit lib default UMapDefs set 14 | */ 15 | 16 | UMapDef( \polar, { |rho = 0.5, theta = 0| 17 | var polar, x,y; 18 | polar = Polar( rho.linlin(0.5,1,0,1,\none), theta ); 19 | x = polar.real.linlin(0,1,0.5,1,\none); 20 | y = polar.imag.linlin(0,1,0.5,1,\none); 21 | UMapOut.kr([x,y]); 22 | }) 23 | .setSpec( \theta, AngleSpec() ) 24 | .uchainInitFunc_({ |unit, chain| 25 | var rho; 26 | rho = unit.rho; 27 | unit.def = \map_polar.asUdef( UMapDef ); 28 | if( unit.rho.isKindOf( UMap ).not ) { 29 | if( rho.inclusivelyBetween(-10,10) ) { 30 | unit.rho = rho.linlin(-10,10,-1,1); 31 | } { 32 | unit.rho = rho.linlin(-200,200,-1,1); 33 | unit.radius = 200@200; 34 | }; 35 | } { 36 | unit.radius = 200@200; 37 | }; 38 | }) 39 | .mappedArgs_( [ \rho ] ) 40 | .category_( 'private' ) 41 | .canUseUMapFunc_({ |unit, key, umapdef| 42 | unit.getSpec( key ).isKindOf( PointSpec ); 43 | }); 44 | -------------------------------------------------------------------------------- /UnitDefs/outputWithSubwoofer.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \outputWithSubwoofer 3 | 4 | Sends sounds from the previous units in the UChain to hardware output busses. 5 | Send also the another output for subwoofer mix. 6 | 7 | Note to WFSCollider users: This sends only to the outputs of the master server. To send to individual speakers on the WFS system, use wfsIndex instead. To send output "the official way" only to the outputs of the master audio interface, use the wfsMasterOut Udef instead (and set "toServers" to false if you really want the analog outputs of the master interface) 8 | 9 | bus: the channels are sent out starting with this bus. 10 | numChannels: number of channels (*). 11 | 12 | (*) only the following numbers of channels are allowed: 13 | 1,2,3,4,5,6,7,8,10,12,16,24,32 14 | 15 | -- 16 | this is an Udef definition file 17 | part of the Unit lib default Udefs set 18 | */ 19 | 20 | MultiChannelUdef( \outputWithSubwoofer, { |bus, subwooferBus=2| 21 | var sig = UGlobalEQ.ar( UIn.ar( 0, Udef.numChannels ) ) * UEnv.kr; 22 | Out.ar( subwooferBus, if(sig.size>0){sig.sum}{sig} * UGlobalSubwooferGain.kr ); 23 | Out.ar( bus, sig ); 24 | }) 25 | .category_( \private ) 26 | .setSpec( \bus, PositiveIntegerSpec( 0, 0, 192 ) ) 27 | .setSpec( \subwooferBus, PositiveIntegerSpec( 0, 0, 192 ) ) 28 | .shouldPlayOnFunc_({ |unit, target| 29 | target.asTarget.server.isLocal; // safety measure: no output on wfs servers 30 | }) -------------------------------------------------------------------------------- /UMapDefs/p_select_8.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \p_select_8 3 | 4 | Creates an pattern UMap that can select a value out of 8. 5 | 6 | index: index of the value (0-7) 7 | value0..value7: values (can be pattern or function UMaps) 8 | 9 | The 'value0'..'value7' arg ranges are mapped to that of the parameter to which the UMap is connected 10 | 11 | -- 12 | this is an UMapDef definition file 13 | part of the Unit lib default UMapDefs set 14 | */ 15 | 16 | var def, values; 17 | 18 | values = 8.collect({ |i| ("value"++i).asSymbol }); 19 | 20 | def = UPatDef( \p_select_8, { |unit, 21 | index = 0, 22 | value0 = 0.5, value1 = 0.5, value2 = 0.5, value3 = 0.5, 23 | value4 = 0.5, value5 = 0.5, value6 = 0.5, value7 = 0.5 24 | | 25 | { 26 | inf.do { |i| 27 | [ 28 | value0, value1, value2, value3, 29 | value4, value5, value6, value7 30 | ].at( index.next.asInteger ).next.yield; 31 | }; 32 | }.r; 33 | }).mappedArgs_( values ) 34 | .useMappedArgs_( false ) 35 | .canUseUMapFunc_({ |unit, key, umapdef| 36 | unit.isKindOf( UPattern ).not && { 37 | [ Point, SimpleNumber, Array, Symbol ].any({ |class| 38 | unit.getDefault( key ).isKindOf( class ) 39 | }) && { UAdaptSpec().canAdapt( unit.getSpec( key ) ) } 40 | }; 41 | }) 42 | .setSpec( \index, IntegerSpec(0,0,7) ) 43 | .category_( 'pattern_selection' ); 44 | 45 | values.do({ |val| def.setSpec( val, UAdaptSpec() ) }); 46 | 47 | def; 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /UMapDefs/rho_theta.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \rho_theta 3 | 4 | Creates an UMap intended for use on modulatable point parameters. It converts the point into a polar, with linear controls for rho and theta, which on their turn can be used to assign other UMaps to. 5 | 6 | rho: the rho value (distance from 0@0) 7 | theta: the theta value (angle from 0@0 ) 8 | 9 | The 'rho' arg range is mapped to that of the parameter to which the UMap is connected. 10 | 11 | -- 12 | this is an UMapDef definition file 13 | part of the Unit lib default UMapDefs set 14 | */ 15 | 16 | UMapDef( \rho_theta, { |rho = 0.5, theta = 0| 17 | var polar, x,y; 18 | polar = Polar( rho.linlin(0.5,1,0,1,\none), theta ); 19 | x = polar.real.linlin(0,1,0.5,1,\none); 20 | y = polar.imag.linlin(0,1,0.5,1,\none); 21 | UMapOut.kr([x,y]); 22 | }) 23 | .setSpec( \theta, AngleSpec() ) 24 | .uchainInitFunc_({ |unit, chain| 25 | var rho; 26 | rho = unit.rho; 27 | unit.def = \map_polar.asUdef( UMapDef ); 28 | if( unit.rho.isKindOf( UMap ).not ) { 29 | if( rho.inclusivelyBetween(-10,10) ) { 30 | unit.rho = rho.linlin(-10,10,-1,1); 31 | } { 32 | unit.rho = rho.linlin(-200,200,-1,1); 33 | unit.radius = 200@200; 34 | }; 35 | } { 36 | unit.radius = 200@200; 37 | }; 38 | }) 39 | .mappedArgs_( [ \rho ] ) 40 | .category_( 'private' ) 41 | .canUseUMapFunc_({ |unit, key, umapdef| 42 | unit.getSpec( key ).isKindOf( PointSpec ); 43 | }); 44 | -------------------------------------------------------------------------------- /UnitDefs/divide.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \divide 3 | 4 | Creates an UMap for division (/) of two values. 5 | 6 | input: the value 7 | divide: the divider 8 | negative: divide by negative value 9 | factor: exponent of 10 to multiply the divider by 10 | 11 | The input arg range is mapped to that of the parameter to which the UMap is connected. 12 | 13 | -- 14 | this is an UMapDef definition file 15 | part of the Unit lib default UMapDefs set 16 | */ 17 | 18 | 19 | HybridUMapDef( \divide, { |input = 0.0, divide = 1.0, negative = 0, factor = 0| 20 | var sig; 21 | UMapDef.useMappedArgs = false; // use raw values instead of mapped (0-1) 22 | sig = input / (divide * negative.linlin(0,1,1,-1) * (10**factor)); 23 | UMapOut.kr(sig); 24 | }, { |unit, input = 0.0, divide = 1.0, negative = 0, factor = 0| 25 | (input / (divide * negative.binaryValue.linlin(0,1,1,-1) * (10**factor))) 26 | .clip( *[unit.spec.minval, unit.spec.maxval] ); 27 | }) 28 | .mappedArgs_([ \input ]) 29 | .prepareArgsFunc_({ |args| 30 | var index; 31 | index = args.indexOf( \value ); 32 | if( index.notNil && { index.even }) { 33 | args[index] = \input; 34 | }; 35 | args; 36 | }) 37 | .setSpec( \divide, [0.1,10,\exp,0,1].asSpec ) 38 | .setSpec( \negative, BoolSpec(false) ) 39 | .setSpec( \factor, ListSpec( [-2,-1,0,1,2,3,4,5], 2, 40 | [-2,-1,0,1,2,3,4,5].collect({ |x| (10**x).asString }) 41 | ) ) 42 | .setSpec( \input, UAdaptSpec() ) 43 | .category_( 'math' ) -------------------------------------------------------------------------------- /UnitDefs/auxIn.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \auxIn 3 | 4 | Read sound from one of the 32 internal 'aux' buses, or, in 'external' mode, from an audio input of your audio interface. 5 | 6 | In 'internal' mode, the signal can be sent from another UChain using 'auxOut'. For this to work on every system, set the receiving UChain's addAction to \addToTail or \addAfter, and enable 'global'. As an alternative to 'global', it is also possible to use an ugroup; In that case, make sure that the sending ('auxOut') unit is in the same ugroup as the receiving one ('auxIn'). 7 | 8 | In 'external' mode the auxIn receives audio from an external input. This is similar to the soundIn Udef. 9 | 10 | bus: the aux bus to read from (0-31) 11 | type: \internal or \external 12 | 13 | -- 14 | this is an Udef definition file 15 | part of the Unit lib default Udefs set 16 | */ 17 | 18 | ( 19 | var defs, def; 20 | 21 | defs = [ 22 | Udef( \internal, { |bus = 0| 23 | var input; 24 | input = UAuxIn.ar( bus ); 25 | UOut.ar( 0, input ); 26 | }, addToAll: false, extraPrefix: \aux_ ) 27 | .setSpec( \bus, UAuxIn.specs[ \bus ] ), 28 | 29 | Udef( \external, { |bus = 0| 30 | var input; 31 | input = SoundIn.ar( bus ); 32 | input * if( bus > (NumInputBuses.ir - 1), 0, 1 ); 33 | UOut.ar( 0, input ); 34 | }, addToAll: false, extraPrefix: \auxIn_ ) 35 | .setSpec( \bus, HardwareBusSpec( \input, 1 ) ) 36 | ]; 37 | 38 | def = MultiUdef( \auxIn, defs, \input, \type, false ); 39 | 40 | def; 41 | ) -------------------------------------------------------------------------------- /UMapDefs/p_time_humanize.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \p_time_humanize 3 | 4 | Creates an pattern UMap intended to use on the 'timeToNext' value of UPatterns. It can add a random factor to start times of events. The UMap will internally track the original time, so that it doesn't drift away. 5 | 6 | time: value or UMap to quantize 7 | amount: amount of deviation from the original start time (0-1 in seconds) 8 | 9 | The 'time' arg ranges is mapped to that of the parameter to which the UMap is connected 10 | 11 | -- 12 | this is an UMapDef definition file 13 | part of the Unit lib default UMapDefs set 14 | */ 15 | 16 | UPatDef( \p_time_humanize, { |unit, time = 1, amount = 0| 17 | { 18 | var logical = 0, actual = 0, qtime = 0; 19 | var ttime, aamt, random; 20 | loop { 21 | ttime = time.next; 22 | logical = logical + ttime; 23 | aamt = amount.next; 24 | random = aamt.rand; 25 | qtime = (logical + (random - ((aamt/2).min(ttime) ))) - actual; 26 | if( qtime <= 0 ) { qtime = random / 2 }; 27 | actual = actual + qtime; 28 | qtime.yield; 29 | }; 30 | }.r; 31 | }) 32 | .setSpec( \time, UAdaptSpec() ) 33 | .setSpec( \amount, [0.0,1,9.squared.log,0,0].asSpec ) 34 | .canUseUMapFunc_({ |unit, key, umapdef| 35 | key == \timeToNext or: { 36 | unit.getSpec( key ).isKindOf( SMPTESpec ) or: { 37 | unit.getSpec( key ).isKindOf( UAdaptSpec ) 38 | } 39 | } 40 | }) 41 | .useMappedArgs_( false ) 42 | .mappedArgs_([ \time ]).category_( 'pattern_time' ); 43 | -------------------------------------------------------------------------------- /UMapDefs/multiply.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \multiply 3 | 4 | Creates an UMap for multiplication (*) of two values. 5 | 6 | input: the value to multiply 7 | multiply: the multiplier 8 | negative: multiply with negative value 9 | factor: exponent of 10 to multiply the multiplier by 10 | 11 | The input arg range is mapped to that of the parameter to which the UMap is connected. 12 | 13 | -- 14 | this is an UMapDef definition file 15 | part of the Unit lib default UMapDefs set 16 | */ 17 | 18 | 19 | HybridUMapDef( \multiply, { |input = 0.0, multiply = 1.0, negative = 0, factor = 0| 20 | var sig; 21 | UMapDef.useMappedArgs = false; // use raw values instead of mapped (0-1) 22 | sig = input * (multiply * negative.linlin(0,1,1,-1) * (10**factor)); 23 | UMapOut.kr(sig); 24 | }, { |unit, input = 0.0, multiply = 1.0, negative = 0, factor = 0| 25 | (input * (multiply * negative.binaryValue.linlin(0,1,1,-1) * (10**factor))) 26 | .clip( *[unit.spec.minval, unit.spec.maxval] ); 27 | }) 28 | .mappedArgs_([ \input ]) 29 | .setSpec( \multiply, [0,2,\lin,0,1].asSpec ) 30 | .prepareArgsFunc_({ |args| 31 | var index; 32 | index = args.indexOf( \value ); 33 | if( index.notNil && { index.even }) { 34 | args[index] = \input; 35 | }; 36 | args; 37 | }) 38 | .setSpec( \negative, BoolSpec(false) ) 39 | .setSpec( \factor, ListSpec( [-2,-1,0,1,2,3,4,5], 2, 40 | [-2,-1,0,1,2,3,4,5].collect({ |x| (10**x).asString }) 41 | ) ) 42 | .setSpec( \input, UAdaptSpec() ) 43 | .category_( 'math' ) -------------------------------------------------------------------------------- /UMapDefs/p_index_soundFile.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \p_index_soundFile 3 | 4 | Creates an UMap that can sequence a number of buffers in a UPattern. For proper use it is best to set the soundFiles 5 | to 'global' so that they don't need to load during pattern playback. The UMap should not be used for an UChain that 6 | is not an UPattern, this will cause issues with the buffers loading especially when not set to 'global' 7 | 8 | soundFiles: (Array of BufSndFiles) this can be a collection of BufSndFiles of any size (max 256 is recommended) 9 | index: (Integer) the index of the soundFile to be played. This can be an UMap too, for example p_int_step can either 10 | loop through the files or randdomize. 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the WFSCollider Class Library default UMapDefs set 15 | */ 16 | 17 | UPatDef( \p_index_soundFile, { | 18 | unit, 19 | soundFiles, 20 | index = 0| 21 | { loop { soundFiles.next.wrapAt( index.next.asInteger ).yield; } }.r 22 | }) 23 | .category_( 'pattern' ) 24 | .canUseUMapFunc_({ |unit, key, umapdef| 25 | unit.getSpec( key ).isKindOf( BufSndFileSpec ); 26 | }) 27 | .numChannels_( 3 ) 28 | .setSpec( \value, AnythingSpec(), private: true ) 29 | .setSpec( \index, IntegerSpec(0,0,256) ) 30 | .setSpec( \soundFiles, MultiSndFileSpec( 31 | { "@resources/sounds/a11wlk01-44_1.aiff".asBufSndFile } ! 8, 32 | false, 33 | ) ) 34 | .setDefault( \soundFiles, 35 | { "@resources/sounds/a11wlk01-44_1.aiff".asBufSndFile } ! 8, 36 | ); 37 | -------------------------------------------------------------------------------- /Classes/GUI/Misc/ClearDragSink.sc: -------------------------------------------------------------------------------- 1 | CleanDragSink { 2 | classvar <>all; 3 | 4 | var color, <>time = 2, <>task; 5 | var <>canReceiveDragHandler, <>receiveDragHandler; 6 | var <>onClose; 7 | 8 | *initClass { 9 | all = Set(); 10 | } 11 | 12 | *new { |parent, bounds| 13 | ^super.newCopyArgs.init( parent, bounds ); 14 | } 15 | 16 | init { |parent, bounds| 17 | view = UserView( parent, bounds ); 18 | color = Color.blue; 19 | 20 | all.add( this ); 21 | view.onClose = { onClose.value; this.task.stop; all.remove( this ) }; 22 | 23 | view.canReceiveDragHandler = { |vw ...args| 24 | if( this.canReceiveDragHandler.value( this, *args ) == true ) { 25 | this.startTask; 26 | true; 27 | } { 28 | false; 29 | }; 30 | }; 31 | 32 | view.receiveDragHandler = { |vw ...args| 33 | this.stopTask; 34 | this.receiveDragHandler.value( this, *args ); 35 | }; 36 | } 37 | 38 | startTask { 39 | this.task.stop; 40 | view.background = this.color.copy.alpha_( 0.33 ); 41 | this.task = Routine({ 42 | var n; 43 | n = (this.time / 0.2).asInteger; 44 | n.do({ |i| 45 | view.background = this.color.copy.alpha_( i.linlin(0,n-1,0.33,0) ); 46 | 0.2.wait; 47 | }); 48 | }).play( AppClock ); 49 | } 50 | 51 | stopTask { 52 | this.task.stop; this.task = nil; 53 | view.background = Color.clear; 54 | } 55 | 56 | doesNotUnderstand { |what ...args| 57 | var res; 58 | res = view.perform( what, *args ); 59 | if( res != view ) { ^res }; 60 | } 61 | } -------------------------------------------------------------------------------- /Classes/GUI/Misc/UDragBin.sc: -------------------------------------------------------------------------------- 1 | UDragBin { 2 | 3 | classvar <>current; 4 | 5 | var <>view; 6 | var <>canReceiveDragHandler; 7 | var <>task; 8 | var <>color; 9 | 10 | *new { |parent, bounds| 11 | ^super.new.view_( UserView( parent, bounds ) ).init; 12 | } 13 | 14 | init { 15 | color = Color.blue; 16 | view.canFocus_( false ); 17 | view.canReceiveDragHandler_({ |vw, x,y| 18 | var last; 19 | if( x.notNil ) { 20 | last = current; 21 | current = vw; 22 | last !? _.refresh; 23 | vw.refresh; 24 | }; 25 | canReceiveDragHandler.value( vw, x, y ); 26 | }); 27 | view.drawFunc = { |vw| 28 | if( View.currentDrag.notNil && { 29 | canReceiveDragHandler.value == true; 30 | }) { 31 | Pen.width = 2; 32 | if( current === vw ) { 33 | Pen.color = color.copy.alpha_(1); 34 | } { 35 | Pen.color = color.copy.alpha_(0.25); 36 | }; 37 | Pen.roundedRect( vw.bounds.moveTo(0,0).insetBy(1,1), 3 ); 38 | Pen.stroke; 39 | if( task.isPlaying.not ) { 40 | task = Routine({ 41 | while { vw.isClosed.not && { canReceiveDragHandler.value == true 42 | } 43 | } { 44 | 0.25.wait; 45 | }; 46 | if( vw.isClosed.not ) { 47 | vw.refresh; 48 | }; 49 | }).play( AppClock ); 50 | }; 51 | }; 52 | }; 53 | } 54 | 55 | doesNotUnderstand { arg ... args; 56 | var result = view.perform( *args ); 57 | ^if( result === view, { this }, { result }); // be sure to replace view with base 58 | } 59 | } -------------------------------------------------------------------------------- /UMapDefs/p_choose.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \p_choose 3 | 4 | Creates an pattern UMap that chooses between multiple values, with an optional exclusion history. To use UMaps as values, apply an 'expand' UMap to the 'vals' parameter. 5 | 6 | 7 | vals: values to choose from 8 | histSize: size of history buffer; the amount of steps before a value can repeat itself. 9 | seed: random seed. 10 | n: total number of values. 11 | 12 | The 'vals' arg ranges are mapped to that of the parameter to which the UMap is connected 13 | 14 | -- 15 | this is an UMapDef definition file 16 | part of the Unit lib default UMapDefs set 17 | */ 18 | 19 | var defs; 20 | 21 | defs = [ 3,4,5,6,7,8,10,12,16,24,32,48,64,128 ].collect({ |n| 22 | UPatDef( n, { |unit, vals, histSize = 0, seed| 23 | { 24 | var index, size, arr, nn; 25 | thisThread.randSeed = seed.next.asControlInput; 26 | arr = (..n-1).scramble; 27 | loop { 28 | index = arr.removeAt( histSize.next.asInteger rrand: (n-1).asInteger ); 29 | arr = arr.addFirst( index ); 30 | vals.at( index ).yield; 31 | }; 32 | }.r 33 | }, addToAll: false ) 34 | .category_( \pattern ) 35 | .setSpec( \histSize, IntegerSpec(0,0,n-1) ) 36 | .setSpec( \seed, URandSeed ) 37 | .setDefault( \seed, URandSeed() ) 38 | .setSpec( \vals, ArrayControlSpec(0,1,\lin,default: 0.5!n ).size_(n) ) 39 | .mappedArgs_([ \vals ]); 40 | }); 41 | 42 | MultiUMapDef( \p_choose, defs, \pattern_random, \n, false ) 43 | .mappedArgs_([ \vals ]) 44 | .defaultDefName_( 8 ) 45 | .allowedModes_([ \init, \sync, \normal ]) -------------------------------------------------------------------------------- /UnitDefs/cymbalic_mcld.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \cymbalic_mcld 3 | 4 | A cymbal sound by Dan Stowell. Based on the example at http://www.mcld.co.uk/cymbalsynthesis/ published 2008 by Dan Stowell 5 | 6 | decay: decay time (s) of the cymbal 7 | ratio: scale factor for the frequencies (0.25-4) 8 | amp: amplitude (0-1) 9 | seed: random seed (positive whole number). The same seed will always result in exactly the same signal on any computer. 10 | 11 | -- 12 | this is an Udef definition file 13 | part of the Unit lib default Udefs set 14 | */ 15 | 16 | Udef(\cymbalic_mcld,{ |decay = 10, ratio = 1, amp = 0.1| 17 | var lodriver, locutoffenv, hidriver, hicutoffenv, freqs, res, thwack; 18 | var trig; 19 | trig = \trigger.tr(1); 20 | 21 | URandSeed.ir( ); // always the same sound 22 | 23 | locutoffenv = EnvGen.ar(Env.perc(0.5, decay), trig ) * 20000 + 10; 24 | lodriver = LPF.ar(WhiteNoise.ar(0.1), locutoffenv); 25 | 26 | hicutoffenv = 10001 - (EnvGen.ar(Env.perc(1, 3), trig) * 10000); 27 | hidriver = HPF.ar(WhiteNoise.ar(0.1), hicutoffenv); 28 | hidriver = hidriver * EnvGen.ar(Env.perc(1, 2, 0.25), trig); 29 | 30 | thwack = EnvGen.ar(Env.perc(0.001,0.001,1), trig); 31 | 32 | freqs = ExpRand( 300.dup(100), 20000 ) * ratio; 33 | 34 | res = Ringz.ar(lodriver + hidriver + thwack, freqs).mean; 35 | 36 | UMixOut.ar(0, ((res * 1) + (lodriver * 2) + thwack) * amp * 0.5, 0, true ); 37 | 38 | }).category_( \synthesis ) 39 | .setSpec( \trigger, TriggerSpec() ) 40 | .setSpec( \decay, [2.5,100,\exp, 0, 10].asSpec, \init ) 41 | .setSpec( \ratio, [0.25, 4, \exp, 0, 1].asSpec ) -------------------------------------------------------------------------------- /UMapDefs/round.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \round 3 | 4 | Creates an UMap for rounding off (quantizing) values. The output value will be the nearest multiple of the 'round' value. 5 | 6 | input: the value to be rounded 7 | round: the value to round to 8 | 9 | The 'input' and 'round' arg ranges are mapped to that of the parameter to which the UMap is connected. 10 | 11 | -- 12 | this is an UMapDef definition file 13 | part of the Unit lib default UMapDefs set 14 | */ 15 | 16 | HybridUMapDef( \round, { |input = 0.5, round = 0| 17 | UMapDef.useMappedArgs = false; 18 | input = input.round( round ); 19 | UMapOut.kr(input); 20 | }, { |unit, input = 0.5, round = 0| 21 | input.round( round ).clip( *[unit.spec.minval, unit.spec.maxval] ); 22 | }, \math 23 | ) 24 | .prepareArgsFunc_({ |args| 25 | var index; 26 | index = args.indexOf( \value ); 27 | if( index.notNil && { index.even }) { 28 | args[index] = \input; 29 | }; 30 | args; 31 | }) 32 | .valueIsMapped_( false ) 33 | .setSpec( \round, UAdaptSpec( { |spec| 34 | var center; 35 | spec = spec.copy; 36 | if( spec.isKindOf( FreqSpec ) ) { 37 | spec = ControlSpec.newFrom( spec ); 38 | }; 39 | if( spec.respondsTo( \warp ) ) { 40 | if( spec.warp.asSpecifier == \exp ) { 41 | center = spec.map( 0.5 ); 42 | center = center / spec.maxval; 43 | spec.warp = (center.reciprocal-1).squared.log; 44 | }; 45 | spec.warp = spec.warp.asSpecifier; 46 | }; 47 | spec.minval = 0; 48 | spec; 49 | } ) ) 50 | .setSpec( \input, UAdaptSpec() ) 51 | .mappedArgs_( [ \input, \round ] ); 52 | 53 | 54 | -------------------------------------------------------------------------------- /UMapDefs/shared_out.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \shared_out 3 | 4 | ** this UMapDef should be used in conjunction with 'shared_in' ** 5 | 6 | The shared_out UMapDef creates an UMap that is able to share a value with other UMaps used further in the chain. This is useful when multiple units or unit parameters need to use the same value, or derrive things from it. The shared_out would always need to be first in the order of the chain; it sends the value to a bus. To retreive the value in an other unit or parameter use the 'shared_in' UMapDef, and make sure the 'id' setting is the same on both. The 'shared_in' UMapDef will automatically map the value to the range of the parameter it is connected to, which means it is possible to use for example the 'freq' value of one unit to influence the 'amp' value of another (or the same) unit. This will only work _within_ a single chain. 7 | 8 | value: the value to be shared (can be an UMap) 9 | id: the id (0-99) by which the point can be retreived by 'shared_in' 10 | range: the range of the value to be shared. 11 | 12 | The value arg range is mapped to that of the parameter to which the UMap is connected. 13 | 14 | -- 15 | this is an UMapDef definition file 16 | part of the Unit lib default UMapDefs set 17 | */ 18 | 19 | UMapDef( \shared_out, { |value = 0.0, range = #[0,1]| 20 | var sig; 21 | sig = value; 22 | range[1] = range[1].max(range[0] + 1.0e-8); 23 | sig = sig.linlin(*range ++ [0,1,\none]); 24 | USharedValueOut.kr( \id, sig ); 25 | UMapOut.kr(value); 26 | }) 27 | .mappedArgs_([ \value, \range ]) 28 | .category_( 'shared_io' ); 29 | -------------------------------------------------------------------------------- /UnitDefs/sample_delay.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \sample_delay 3 | 4 | a clean and precise sample delay. 5 | 6 | samples/ms/meters: the length of the delay. 7 | lag: smoothing time applied to change of delay time, use to prevent clicks during change of delay time. 8 | numChannels: number of channels 9 | type: 'samples' / 'ms' / 'meters'; time mode, samples, milliseconds or meters 10 | 11 | -- 12 | this is an Udef definition file 13 | part of the Unit lib default Udefs set 14 | */ 15 | 16 | 17 | var defs, func; 18 | 19 | func = { |val, denom, step| 20 | var in, delayed; 21 | in = UIn.ar( 0, Udef.numChannels ); 22 | delayed = if( val < step, in, DelayN.ar( in, 1, val / denom ) ); 23 | UOut.ar( 0, delayed ) 24 | }; 25 | 26 | defs = [ 27 | MultiChannelUdef( \samples, { |samples = 0, lag = 0| 28 | func.value( samples.lag3( lag ), SampleRate.ir, 0.1 ); 29 | }, extraPrefix: \sample_delay, addToAll: false ) 30 | .setSpec( \lag, [0,1,\lin].asSpec ) 31 | .setSpec( \samples, [ 0, 48000, \lin, 1, 0 ] ), 32 | 33 | MultiChannelUdef( \ms, { |ms = 0, lag = 0| 34 | func.value( ms.lag3( lag ), 1000, 0.1 ); 35 | }, extraPrefix: \sample_delay, addToAll: false ) 36 | .setSpec( \lag, [0,1,\lin].asSpec ) 37 | .setSpec( \ms, [ 0, 1000, \lin, 0.1, 0 ] ), 38 | 39 | MultiChannelUdef( \meters, { |meters = 0, lag = 0| 40 | func.value( meters.lag3( lag ), 344, 0.1 ); 41 | }, extraPrefix: \sample_delay, addToAll: false ) 42 | .setSpec( \lag, [0,1,\lin].asSpec ) 43 | .setSpec( \meters, [ 0, 344, \lin, 0.1, 0 ] ), 44 | ]; 45 | 46 | MultiUdef( 'sample_delay', defs, \utility, \type, false, true ); -------------------------------------------------------------------------------- /UMapDefs/note_freq.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \note_freq 3 | 4 | Creates an UMap for converting chromatic midi-note values to a frequency, in semitones where 69 == 440Hz. 5 | 6 | note: a midi note value (can be in between semitones as well) 7 | round: rounding factor (0 - 12) 8 | base: frequency of note 69 (A) 9 | detune: detune amount in cents (-50 - 50) 10 | transpose: transposition in semitones 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the Unit lib default UMapDefs set 15 | */ 16 | 17 | HybridUMapDef( \note_freq, { |note = 64, round = 1, base = 440, detune = 0, transpose = 0| 18 | UMapDef.useMappedArgs = false; // use raw values instead of mapped (0-1) 19 | UMapOut.kr( 20 | base * 2.pow((note.round(round) + (detune/100)) + transpose - 69 / 12) ); 21 | }, { |unit, note = 64, round = 1, base = 440, detune = 0, transpose = 0| 22 | base * 2.pow((note.round(round) + (detune/100)) + transpose - 69 / 12); 23 | }) 24 | .mappedArgs_([ \note ]) 25 | .setSpec( \note, UAdaptSpec({ |spec| 26 | ControlSpec( spec.minval.cpsmidi, spec.maxval.cpsmidi, \lin, 0, spec.default.cpsmidi ); 27 | }) ) 28 | .setSpec( \round, [0,12,\lin,0,1] ) 29 | .setSpec( \base, [68.midicps, 70.midicps,\lin,0,440] ) 30 | .setSpec( \detune, [-50,50,\lin,0,0, " cents"].asSpec ) 31 | .setSpec( \transpose, [-36,36,\lin,1,0, " semitones"].asSpec ) 32 | .canUseUMapFunc_({ |unit, key, umapdef| 33 | var spec; 34 | spec = unit.getSpec( key ); 35 | spec.isKindOf( ControlSpec ) && { spec.default.size < 2 && { spec.minval > 0 && { spec.maxval < inf } } }; 36 | }) 37 | .category_( 'convert' ) -------------------------------------------------------------------------------- /UMapDefs/select_8.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \select_8 3 | 4 | Creates an UMap that can select one from 8 values (or UMaps). If you need to select from > 8 values, use \select_16 instead. 5 | 6 | index: the index of the value (0-7) 7 | smooth: smoothening parameter (0: hard steps, 1: linear interpolation) 8 | value0 - value7: the values of the steps (can be UMaps) 9 | 10 | The 'value[0-7]' arg ranges are mapped to that of the parameter to which the UMap is connected. 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the Unit lib default UMapDefs set 15 | */ 16 | 17 | UMapDef( \select_8, { 18 | var values, smooth; 19 | var phase, step, resetPos, sig; 20 | Udef.buildUdef.dontStoreSynthDef = true; 21 | phase = \index.kr(0); 22 | smooth = \smooth.kr(0.0); 23 | values = 8.collect({ |i| 24 | ("value"++i).asSymbol.ukr(0.5); 25 | }); 26 | phase = (phase.floor * (1-smooth)) + (phase * smooth); 27 | sig = LinSelectX.kr( phase, values ); 28 | UMapOut.kr( sig ); 29 | }).category_( \private ) 30 | .uchainInitFunc_({ |unit, chain| 31 | var values, smooth; 32 | values = 8.collect({ |i| unit.get( ("value"++i).asSymbol ) }); 33 | smooth = unit.smooth; 34 | unit.def = \select; 35 | unit.interpolate = smooth.booleanValue; 36 | unit.n = values.size; 37 | if( values.any( _.isKindOf( UMap ) ) ) { 38 | unit.vals = [ \expand, 39 | 8.collect({ |i| [ ("value"++i).asSymbol, values[i] ] }).flatten(1); 40 | ]; 41 | } { 42 | unit.vals = values; 43 | }; 44 | unit 45 | }) 46 | .setSpec( \index, [0,7].asSpec ) 47 | .mappedArgs_( 8.collect({ |i| ("value"++i).asSymbol }) ); -------------------------------------------------------------------------------- /UMapDefs/tempo_time.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \tempo_time 3 | 4 | Creates an UMap that converts tempo to time. This UMap can also be used on 'init' mode parameters. It can only be used for time (SMPTESpec) parameters. The UMap also features a quantize option, designed to use in combination with 'timeToNext' on UPatterns. This option is useful for synchronizing multiple patterns that start asynchronously. 5 | 6 | factor: number or fraction of beats (0.125-8) 7 | tempo: beats per minute 8 | quantize: (for use on 'timeToNext') quantize the time to the nearest beat or division. If quantize is set to 0 (default) nothing is changed. 9 | 10 | -- 11 | this is an UMapDef definition file 12 | part of the Unit lib default UMapDefs set 13 | */ 14 | 15 | HybridUMapDef( \tempo_time, { |factor = 1, tempo = 60| 16 | UMapDef.useMappedArgs = false; 17 | UMapOut.kr( factor / tempo * 60, false ); 18 | }, { |unit, factor = 1, tempo = 60, quantize = 0.0| 19 | var time, currentTime, out; 20 | time = factor / tempo * 60; 21 | if( quantize > 0 ) { 22 | currentTime = thisThread.seconds; 23 | (currentTime.round( (quantize / tempo * 60).min(time) ) - currentTime + time) 24 | } { 25 | time; 26 | }; 27 | }) 28 | .category_( 'convert' ) 29 | .valueIsMapped_( false ) 30 | .setSpec( \factor, [0.0625,16,\exp].asSpec ) 31 | .setSpec( \tempo, [10,300,\exp,0,60].asSpec ) 32 | .prepareArgsFunc_( { |args| 33 | args.replace( \division, \factor ); 34 | } ) 35 | .canUseUMapFunc_({ |unit, key, umapdef| 36 | unit.getSpec( key ).isKindOf( SMPTESpec ) or: { 37 | unit.getSpec( key ).isKindOf( UAdaptSpec ) 38 | } 39 | }) -------------------------------------------------------------------------------- /UMapDefs/select_16.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \select_16 3 | 4 | Creates an UMap that can select one from 16 values (or UMaps). If you need to select from <= 8 values, use \select_8 instead. 5 | 6 | index: the index of the value (0-15) 7 | smooth: smoothening parameter (0: hard steps, 1: linear interpolation) 8 | value0 - value15: the values of the steps (can be UMaps) 9 | 10 | The 'value[0-15]' arg ranges are mapped to that of the parameter to which the UMap is connected. 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the Unit lib default UMapDefs set 15 | */ 16 | 17 | UMapDef( \select_16, { 18 | var values, smooth; 19 | var phase, step, resetPos, sig; 20 | Udef.buildUdef.dontStoreSynthDef = true; 21 | phase = \index.kr(0); 22 | smooth = \smooth.kr(0.0); 23 | values = 16.collect({ |i| 24 | ("value"++i).asSymbol.ukr(0.5); 25 | }); 26 | phase = (phase.floor * (1-smooth)) + (phase * smooth); 27 | sig = LinSelectX.kr( phase, values ); 28 | UMapOut.kr( sig ); 29 | }).category_( \private ) 30 | .uchainInitFunc_({ |unit, chain| 31 | var values, smooth; 32 | values = 16.collect({ |i| unit.get( ("value"++i).asSymbol ) }); 33 | smooth = unit.smooth; 34 | unit.def = \select; 35 | unit.interpolate = smooth.booleanValue; 36 | unit.n = values.size; 37 | if( values.any( _.isKindOf( UMap ) ) ) { 38 | unit.vals = [ \expand, 39 | 16.collect({ |i| [ ("value"++i).asSymbol, values[i] ] }).flatten(1); 40 | ]; 41 | } { 42 | unit.vals = values; 43 | }; 44 | unit 45 | }) 46 | .setSpec( \index, [0,15].asSpec ) 47 | .mappedArgs_( 16.collect({ |i| ("value"++i).asSymbol }) ); -------------------------------------------------------------------------------- /UMapDefs/tempo_factor.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \tempo_factor 3 | 4 | This UMap is intended for use on the 'pattern' value of an UPattern. It allows the sustain and timeToNext values of the pattern to be set in a specific tempo (BPM) 5 | 6 | sustain: sustain time as number or fraction of beats (0.125-8) 7 | timeToNext: time to next as number or fraction of beats (0.125-8) 8 | tempo: beats per minute 9 | 10 | -- 11 | this is an UMapDef definition file 12 | part of the Unit lib default UMapDefs set 13 | */ 14 | 15 | FuncUMapDef( \tempo_factor, { |unit, sustain = 1, timeToNext = 1, tempo = 60, quantize = 0.0| 16 | var timeCorrection, currentTime; 17 | timeToNext = timeToNext / tempo * 60; 18 | sustain = sustain / tempo * 60; 19 | if( quantize > 0 ) { 20 | currentTime = thisThread.seconds; 21 | currentTime = currentTime.round( (quantize / tempo * 60).min( timeToNext ) ) - currentTime; 22 | if( ((UPattern.nowCallingPattern !? _.localPos) == 0) && { currentTime.abs > 1.0e-10 } ) { 23 | sustain = 0; timeToNext = currentTime; 24 | } { 25 | //timeToNext = currentTime + timeToNext; 26 | } 27 | }; 28 | [ sustain, timeToNext ]; 29 | }) 30 | .category_( 'upattern' ) 31 | .valueIsMapped_( false ) 32 | .mappedArgs_( [] ) 33 | .setSpec( \sustain, [0,8,1.calcCurve(0,8),0,1].asSpec ) 34 | .setSpec( \timeToNext, [0.125,8,\exp,0,1].asSpec ) 35 | .setSpec( \tempo, [10,300,\exp,0,60].asSpec ) 36 | .setSpec( \value, DisplaySpec( SMPTESpec(), _.asSMPTEString(1000) ), private: true ) 37 | .dontStoreValue_( true ) 38 | .canUseUMapFunc_({ |unit, key, umapdef| 39 | unit.getSpec( key ).isKindOf( UPatternSpec ); 40 | }) -------------------------------------------------------------------------------- /UnitDefs/sos_bell.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \sos_bell 3 | 4 | A simple bell sound by Dan Stowell. based on a sound-on-sound 'synth secrets' tutorial. Adapted to sound indefinitely. 5 | 6 | freq: frequency (Hz) of the bell 7 | decay: decay time (s) of the bell. 8 | amp: amplitude (0-1) 9 | seed: random seed (positive whole number). The same seed will always result in exactly the same signal on any computer. 10 | 11 | -- 12 | this is an Udef definition file 13 | part of the Unit lib default Udefs set 14 | */ 15 | 16 | Udef(\sos_bell,{ |freq = 440, decay = 10, amp = 0.1| 17 | var out, env; 18 | var son, strike, hum; 19 | var trig; 20 | trig = \trigger.tr(1); 21 | 22 | URandSeed.ir(); // always the same sound 23 | 24 | // Stretched harmonic series 25 | son = SinOsc.ar(#[2, 3, 4.1, 5.43, 6.8, 8.21] * freq, 0, 26 | #[1, 0.9, 0.8, 0.7, 0.6, 0.5] * 0.1); 27 | 28 | son = son * EnvGen.ar(Env.new([0,1,0.3, 0.2, 0], [0, 0.3, 0.3, 0.3] * decay), trig); 29 | 30 | // A bit of FM adds 'warble' 31 | son = son * LFTri.ar({TRand.kr(1.0, 1.8,trig)}.dup(6), 1, 0.3, 0.7); 32 | 33 | // Mix down the partials in the main sound 34 | son = son.mean; 35 | 36 | strike = SinOsc.ar(LFNoise1.ar(freq * 36, 100, freq*8), 1, 0.1) * 37 | EnvGen.ar(Env.new([0,1,0.2, 0.1, 0], [0, 0.01, 0, 0.04]), trig); 38 | 39 | hum = SinOsc.ar([freq*1.01, freq*0.47], 0, 40 | EnvGen.ar(Env.new([0,0.05,0.05,0], [decay/2,decay/2,decay]), trig ) 41 | ).mean; 42 | 43 | UMixOut.ar(0, (son + strike + hum) * 4 * amp, 0, true ); 44 | 45 | }).category_( \synthesis ) 46 | .setSpec( \trigger, TriggerSpec() ) 47 | .setSpec( \decay, [0.3,1000,\exp].asSpec ) -------------------------------------------------------------------------------- /Classes/SyncCenter/+ Server.sc: -------------------------------------------------------------------------------- 1 | /* 2 | Unit Library 3 | The Game Of Life Foundation. http://gameoflife.nl 4 | Copyright 2006-2011 Miguel Negrao, Wouter Snoei. 5 | 6 | GameOfLife Unit Library: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | GameOfLife Unit Library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with GameOfLife Unit Library. If not, see . 18 | */ 19 | 20 | + Server { 21 | 22 | listSendSyncedBundle{ |delta = 0.2, msgs, syncCenter| 23 | syncCenter = syncCenter ? SyncCenter.current; 24 | if( syncCenter.notNil ) { 25 | syncCenter.listSendSyncedBundle( this, delta, msgs ); 26 | } { 27 | if( SyncCenter.verbose ) { "falling back to normal bundle".postln; }; 28 | this.listSendBundle( delta, msgs ); 29 | }; 30 | 31 | } 32 | 33 | sendSyncedBundle{ |delta = 0.2, syncCenter ... msgs| 34 | syncCenter = syncCenter ? SyncCenter.current; 35 | if( syncCenter.notNil ) { 36 | syncCenter.sendSyncedBundle( this, delta, *msgs ); 37 | } { 38 | if( SyncCenter.verbose ) { "falling back to normal bundle".postln; }; 39 | this.sendBundle( delta, *msgs ); 40 | }; 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /Classes/GUI/Misc/UDragSource.sc: -------------------------------------------------------------------------------- 1 | UDragSource { 2 | 3 | classvar <>mouseSynth; 4 | 5 | var <>view; 6 | var <>beginDragAction; 7 | 8 | *initClass { 9 | Platform.case( 10 | \osx, { 11 | StartUp.defer({ 12 | if( GUI.id == \cocoa ) { 13 | SynthDef( "UDragSource_mouseState", { 14 | var state = MouseButton.kr( 0, 1, 0 ); 15 | FreeSelf.kr( HPZ1.kr( state ) < 0 ); 16 | }).writeOnce 17 | }; 18 | }) 19 | } 20 | ); 21 | } 22 | 23 | *viewClass { ^DragSource } 24 | 25 | *new { |parent, bounds| 26 | ^super.new.view_( this.viewClass.new( parent, bounds ) ).init; 27 | } 28 | 29 | init { 30 | if( GUI.id == \cocoa ) { 31 | view.beginDragAction_({ |vw| 32 | if( Server.default.isLocal ) { 33 | mouseSynth = Synth( 'UDragSource_mouseState' ).onFree({ 34 | { 35 | if( View.currentDrag.notNil ) { 36 | View.currentDrag = nil; 37 | UChainGUI.all.do({ |x| x.view.refresh }); 38 | UGlobalControlGUI.current !? {|x| x.view.view.refresh }; 39 | }; 40 | }.defer(0.1); 41 | mouseSynth = nil; 42 | }); 43 | }; 44 | this.beginDragAction.value( vw ); 45 | }); 46 | } { 47 | view.beginDragAction_({ |vw| 48 | this.beginDragAction.value( vw ); 49 | }); 50 | }; 51 | } 52 | 53 | applySkin { |skin| 54 | view.applySkin( skin ); 55 | } 56 | 57 | doesNotUnderstand { arg ... args; 58 | var result = view.perform( *args ); 59 | ^if( result === view, { this }, { result }); // be sure to replace view with base 60 | } 61 | } 62 | 63 | UDragBoth : UDragSource { 64 | 65 | *viewClass { ^DragBoth } 66 | 67 | } -------------------------------------------------------------------------------- /Examples/Test FilePlayers 0.1.scd: -------------------------------------------------------------------------------- 1 | //run this first 2 | Udef.loadAllFromDefaultDirectory.do(_.loadSynthDef(s)); 3 | 4 | // example 5 | ~path = "sounds/a11wlk01-44_1.aiff"; 6 | 7 | //buffer 8 | //not looped 9 | x = BufSndFile(~path); 10 | //looped 11 | x = BufSndFile(~path, startFrame: 44100*0.2, rate:1.5, loop: true); 12 | 13 | x.postcs; ""; 14 | //disk 15 | x = DiskSndFile(~path, startFrame: 44100*0.1, endFrame:44100*2); 16 | //looped (infinite duration) 17 | x = DiskSndFile(~path, loop: true); 18 | 19 | //play 20 | ( 21 | y = x.makeUnit; 22 | z = UChain(y,\output); 23 | z.useSndFileDur; // use duration 24 | z.prepareAndStart(s); 25 | ) 26 | 27 | // or shorter: 28 | ( 29 | z = x.makeUChain; 30 | z.prepareAndStart(s); 31 | ) 32 | 33 | z.release(0.5); // release of 0.5s (for looping variants) 34 | 35 | // play while keeping buffers 36 | ( 37 | z = x.makeUChain; 38 | z[0].disposeOnFree = false; 39 | z.prepare(s); 40 | ) 41 | 42 | z.start(s); // as many times as you want 43 | 44 | z.release; // stop all 45 | 46 | z.dispose(s); // frees all active buffers 47 | 48 | //this should be empty when nothing is playing or after dispose 49 | z[0].get(\soundFile).buffers; 50 | 51 | 52 | // this will create Chain, allocate buffer, play, and when finished, free the buffer. 53 | z = x.play(s); 54 | 55 | z.gui; 56 | 57 | x.plot 58 | 59 | //RichBuffer 60 | ( 61 | Udef(\testBuffer,{ |buf| 62 | Out.ar(0,BufAllpassN.ar(buf, Decay.ar(Dust.ar(1,0.5), 0.2, WhiteNoise.ar), 0.2, 3) ) 63 | }); 64 | x = U(\testBuffer,[\buf,RichBuffer(44100*1)]); 65 | x.prepareAndStart(s); 66 | ) 67 | 68 | x.get( \buf ).buffers; // try again after stop 69 | 70 | x.stop; 71 | -------------------------------------------------------------------------------- /UMapDefs/p_time_quantize.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \p_time_quantize 3 | 4 | Creates an pattern UMap intended to use on the 'timeToNext' value of UPatterns. It is capable of quantizing incoming time values to a grid based on tempo and note division. The quantization grid is absolute, based on the starting time of the UPattern. That means that if two patterns with a 'p_time_quantize' are started at the exact same time, they will always quantize together when their settings are the same, even if tempo and/or factor are modulated over time. 5 | 6 | time: value or UMap to quantize 7 | factor: number or fraction of beats to quantize to (0.125-8) 8 | tempo: beats per minute 9 | 10 | The 'input' arg ranges is mapped to that of the parameter to which the UMap is connected 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the Unit lib default UMapDefs set 15 | */ 16 | 17 | UPatDef( \p_time_quantize, { |unit, time = 1, factor = 1, tempo = 60| 18 | { 19 | var logical = 0, actual = 0, qtime = 0; 20 | var ttime, round; 21 | loop { 22 | ttime = time.next; 23 | logical = logical + ttime; 24 | round = (factor.next / tempo.next) * 60; 25 | qtime = logical.round( round ) - actual; 26 | actual = actual + qtime; 27 | qtime.yield; 28 | }; 29 | }.r; 30 | }) 31 | .setSpec( \time, UAdaptSpec() ) 32 | .setSpec( \factor, [0.125,8,\exp].asSpec ) 33 | .setSpec( \tempo, [10,300,\exp,0,60].asSpec ) 34 | .canUseUMapFunc_({ |unit, key, umapdef| 35 | unit.getSpec( key ).isKindOf( SMPTESpec ) or: { 36 | unit.getSpec( key ).isKindOf( UAdaptSpec ) 37 | } 38 | }) 39 | .useMappedArgs_( false ) 40 | .mappedArgs_([ \time ]).category_( 'pattern_time' ); 41 | -------------------------------------------------------------------------------- /UnitDefs/bufSoundFile.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \bufSoundFile 3 | 4 | A soundfile player. This plays soundfiles of any duration, with any (*) number of channels, 5 | by loading the whole file into the memory. 6 | Use this typically for shorter (less than apx 2 minutes) audiofiles. 7 | For longer files it is advised to use \diskSoundFile instead 8 | 9 | soundFile: a BufSndFile object, a region of an existig soundfile url on your hard drive. 10 | The object knows the duration and file path of the soundfile, and can be set to clip 11 | off the start and end of the file. 12 | - start: region startoffset (samples or seconds) 13 | - end: end of the region (samples or seconds) 14 | - loop: loop mode on or off (can be changed during playback) 15 | - rate: playback rate (semitones or ratio) 16 | level: playback level (amplitude of the soundfile) 17 | 18 | (*) only the following numbers of channels are allowed: 19 | 1,2,3,4,5,6,7,8,10,12,16,24,32 20 | 21 | -- 22 | this is an Udef definition file 23 | part of the Unit lib default Udefs set 24 | */ 25 | 26 | MultiChannelUdef( \bufSoundFile, { 27 | UMixOut.ar( 0, BufSndFilePlayer.ar( Udef.numChannels, \soundFile, \trigger.utr(1) ) 28 | * \level.ukr( 1, \amp ), 0, true ); 29 | }, [ [ \soundFile, nil, BufSndFileSpec(nil) ] ], \soundFile, true ) 30 | .chooseFunc_({ |args| 31 | var sf, numChannels; 32 | sf = (args ? []).pairsAt( \soundFile ); 33 | if( sf.notNil ) { sf.numChannelsForPlayBuf } { 1 }; 34 | }) 35 | .nameFunc_({ |unit| 36 | var sf, path; 37 | if( (sf = unit.get( \soundFile )).notNil && { sf.path.notNil } ) { 38 | sf.path.basename ++ " : bufSoundFile"; 39 | } { 40 | "bufSoundFile" 41 | }; 42 | }); -------------------------------------------------------------------------------- /Classes/Arg/USharedValueIO.sc: -------------------------------------------------------------------------------- 1 | /* 2 | Unit Lib reserved bus numbers: 3 | 4 | 1100 - 1199: shared buffer 5 | 1200 - 1399: shared point (WFSCollider Class Library) 6 | 1400 - 1499: shared value 7 | 1500 - 1999: UMap map bus 8 | 2000 - 20**: wfs panner Udefs (WFSCollider Class Library) 9 | */ 10 | 11 | USharedValueIn { 12 | 13 | classvar <>busOffset = 1400; 14 | 15 | *spec { |default| ^SharedValueIDSpec( default ) } 16 | 17 | *makeInput { |id, default = 0| 18 | if( id.isNil ) { id = \id }; 19 | if( id.isKindOf( Symbol ) ) { 20 | Udef.addBuildSpec( 21 | ArgSpec(id, default, this.spec( default ) ) 22 | ); 23 | id = id.kr( default ); 24 | }; 25 | ^id 26 | } 27 | 28 | *kr { |id, default = 0| 29 | ^In.kr( this.makeInput( id, default ) + this.busOffset ); 30 | } 31 | } 32 | 33 | USharedValueOut : USharedValueIn { 34 | 35 | *kr { |id, channelsArray, default = 0| 36 | if( id.isArray ) { 37 | channelsArray = channelsArray.asArray; 38 | default = default.asArray; 39 | ^id.collect({ |id, i| 40 | this.single( id, channelsArray.wrapAt(i), default.wrapAt(i) ); 41 | }); 42 | } { 43 | ^this.single( id, channelsArray, default ); 44 | } 45 | } 46 | 47 | *single { |id, channel, default = 0| 48 | ^ReplaceOut.kr( this.makeInput( id, default ) + this.busOffset, channel ); 49 | } 50 | } 51 | 52 | USharedBufferIn : USharedValueIn { 53 | classvar <>busOffset = 1100; 54 | 55 | *spec { |default| ^SharedBufferIDSpec( default ) } 56 | } 57 | 58 | USharedBufferOut : USharedBufferIn { 59 | 60 | *kr { |id, channel, default = 0| 61 | ^ReplaceOut.kr( this.makeInput( id, default ) + this.busOffset, channel ); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /UMapDefs/p_wchoose_8.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \p_wchoose_8 3 | 4 | Creates an pattern UMap that chooses between 8 values based on a probability rate for each value. 5 | 6 | value0..value7: values to choose from 7 | weight0..weight8: weight of each value. If all weights are equal, probabilities are also equal 8 | 9 | The 'value0'..'value7' arg ranges are mapped to that of the parameter to which the UMap is connected 10 | 11 | -- 12 | this is an UMapDef definition file 13 | part of the Unit lib default UMapDefs set 14 | */ 15 | 16 | UPatDef( \p_wchoose_8, { |unit, 17 | value0 = 0.5, value1 = 0.5, value2 = 0.5, value3 = 0.5, 18 | value4 = 0.5, value5 = 0.5, value6 = 0.5, value7 = 0.5, 19 | weight0 = 1.0, weight1 = 1.0, weight2 = 1.0, weight3 = 1.0, 20 | weight4 = 1.0, weight5 = 1.0, weight6 = 1.0, weight7 = 1.0| 21 | { 22 | loop { 23 | [ 24 | value0, value1, value2, value3, 25 | value4, value5, value6, value7, 26 | ].wchoose( [ 27 | weight0.next, weight1.next, weight2.next, weight3.next, 28 | weight4.next, weight5.next, weight6.next, weight7.next, 29 | ].normalizeSum 30 | ).next.yield; 31 | }; 32 | }.r; 33 | }).mappedArgs_([ \value0, \value1, \value2, \value3, \value4, \value5, \value6, \value7 ]) 34 | .useMappedArgs_( false ) 35 | .canUseUMapFunc_({ |unit, key, umapdef| unit.isKindOf( UPattern ).not }) 36 | .setSpec( \value0, UAdaptSpec() ) 37 | .setSpec( \value1, UAdaptSpec() ) 38 | .setSpec( \value2, UAdaptSpec() ) 39 | .setSpec( \value3, UAdaptSpec() ) 40 | .setSpec( \value4, UAdaptSpec() ) 41 | .setSpec( \value5, UAdaptSpec() ) 42 | .setSpec( \value6, UAdaptSpec() ) 43 | .setSpec( \value7, UAdaptSpec() ) 44 | .category_( 'private' ); 45 | -------------------------------------------------------------------------------- /Examples/test UPattern.scd: -------------------------------------------------------------------------------- 1 | ~pat = UPattern( \sine, \output ); // create an UPattern 2 | 3 | ~pat.gui; // show GUI (sustain and timeToNext are not yet shown) 4 | 5 | // make random start times and durations 6 | ~pat.sustain = UMap( \random_value, [ \range, [0.05,0.5] ] ); 7 | ~pat.timeToNext = UMap( \random_value, [ \range, [0.05,0.5] ] ); 8 | 9 | // single values for regular times 10 | ~pat.sustain = 0.1; 11 | ~pat.timeToNext = 0.1; 12 | 13 | // define some UPatDefs 14 | ( 15 | UPatDef( \p_brown, { |unit, lo = 0.0, hi = 1.0, step = 0.125| 16 | Pbrown( lo, hi, step, inf ).asStream; 17 | }).mappedArgs_([\lo, \hi]).category_( 'pattern' ); 18 | 19 | UPatDef( \p_step, { |unit, lo = 0.0, hi = 1.0, steps = 12| 20 | { 21 | var current = 0; 22 | current.linlin( 0, 1, lo.next, hi.next ).yield; 23 | inf.do { |i| 24 | current = (current + ((1/steps.next).clip2( 1.0e12 ))).wrap( 0.0, 1.0 ); 25 | current.linlin( 0, 1, lo.next, hi.next ).yield; 26 | }; 27 | }.r; 28 | }).mappedArgs_([\lo, \hi]) 29 | .setSpec( \steps, [-100,100,\lin].asSpec ) 30 | .category_( 'pattern' ); 31 | ); 32 | 33 | // various assignments for freq of sine wave 34 | ~pat[0].freq = [ \p_brown, [ \lo, 440, \hi, 880, \step, 0.1 ] ]; 35 | 36 | ~pat[0].freq = [ \p_step, [ \lo, 440, \hi, 880, \steps, 12 ] ]; 37 | 38 | // can be nested too 39 | ~pat[0].freq.lo = [ \p_step, [ \lo, 220, \hi, 660, \steps, 2 ] ]; 40 | 41 | // defs can be changed during playback 42 | ~pat.prepareAndStart; 43 | 44 | ~pat.stop; 45 | 46 | ~pat.duration = 5; // limit duration 47 | ~pat.repeats = 5; // limit max repeats 48 | 49 | ~pat.duration = inf; // don't limit duration 50 | ~pat.repeats = inf; // don't limit max repeats -------------------------------------------------------------------------------- /Classes/Misc/OSCMethodPatternDispatcher.sc: -------------------------------------------------------------------------------- 1 | /* 2 | Unit Library 3 | The Game Of Life Foundation. http://gameoflife.nl 4 | Copyright 2006-2011 Miguel Negrao, Wouter Snoei. 5 | 6 | GameOfLife Unit Library: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | GameOfLife Unit Library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with GameOfLife Unit Library. If not, see . 18 | */ 19 | 20 | /* 21 | this is here as long as there isn't any incoming pattern matching functionality in sc itself. 22 | It is used for UOSCsetter 23 | */ 24 | 25 | OSCMethodPatternDispatcher : OSCMessageDispatcher { 26 | 27 | classvar <>compatibilityMode = false; 28 | 29 | *initClass { 30 | compatibilityMode = OSCMessageDispatcher.findMethod( \value ).argNames[1] == \time; 31 | } 32 | 33 | value {|msg, time, addr, recvPort| 34 | var pattern; 35 | if( compatibilityMode ) { 36 | #time, addr, recvPort, msg = [ msg, time, addr, recvPort ]; 37 | }; 38 | pattern = msg[0]; 39 | active.keysValuesDo({|key, func| 40 | if(pattern.matchOSCAddressPattern(key), {func.value(msg, time, addr, recvPort);}); 41 | }) 42 | } 43 | 44 | typeKey { ^('OSC patternmatched').asSymbol } 45 | 46 | } -------------------------------------------------------------------------------- /UMapDefs/global_control.scd: -------------------------------------------------------------------------------- 1 | /* 2 | \global_control 3 | 4 | Creates an UMap that listens to a control in UGlobalControl 5 | 6 | value: the actual output value (this will change when the variable changes, but can also be changed manually) 7 | active: if true, the UMap will listen to the specified global control and update it whenever it changes. If a non-existing key is used, it will be added to UGlobalControl automatically when 'active' == true. 8 | controlKey: the name of the globalControl (a Symbol) 9 | 10 | The 'value' arg range is mapped to that of the parameter to which the UMap is connected. 11 | 12 | -- 13 | this is an UMapDef definition file 14 | part of the Unit lib default UMapDefs set 15 | */ 16 | 17 | ValueUMapDef( \global_control, { |unit, ctrl| 18 | var key, spec; 19 | UGlobalControl.removeDependant( ctrl ); 20 | spec = unit.getSpec( \value ); 21 | key = unit.get( \controlKey ); 22 | if( key.isNil ) { 23 | key = 'global_0'; 24 | unit.set( \controlKey, key ); 25 | }; 26 | key = key.asSymbol; 27 | "listening to UGlobalControl '%'\n".postf( key ); 28 | ctrl = { |obj, key| 29 | var val; 30 | if( unit.get( \learn ) ) { 31 | unit.set( \controlKey, key ); 32 | }; 33 | if( key === unit.get( \controlKey ) ) { 34 | val = UGlobalControl.current.get( key ); 35 | if( val.notNil ) { 36 | unit.mapSet( \value, val ); 37 | }; 38 | }; 39 | }; 40 | UGlobalControl.addDependant( ctrl ); 41 | UGlobalControl.current.put( key, UGlobalControl.current.at( key ) ); 42 | ctrl; 43 | }, { |unit, ctrl| 44 | UGlobalControl.removeDependant( ctrl ); 45 | nil; 46 | }, [ 47 | [ \controlKey, nil, UGlobalControlKeySpec() ], 48 | [ \learn, false, BoolSpec() ] 49 | ], \private ); --------------------------------------------------------------------------------