

Smalltalk.Siren defineClass: #CSLUnitGenerator
	superclass: #{Siren.AbstractEvent}
	indexedType: #none
	private: false
	instanceVariableNames: 'name scale offset inputs '
	classInstanceVariableNames: ''
	imports: ''
	category: 'MusicApps-CSL'!

!Siren.CSLUnitGenerator methodsFor: 'accessing'!

inputs

	^inputs!

inputs: aValue

	inputs := aValue!

name

	^name!

name: aValue

	name := aValue!

offset

	^offset!

offset: aValue

	offset := aValue!

scale

	^scale!

scale: aValue

	scale := aValue! !



Smalltalk.Siren defineClass: #CSLGraph
	superclass: #{Siren.CSLUnitGenerator}
	indexedType: #none
	private: false
	instanceVariableNames: 'ugens envelopes parameters '
	classInstanceVariableNames: ''
	imports: '
			Siren.CSL.*
			'
	category: 'MusicApps-CSL'!

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!


!Siren.CSLGraph class methodsFor: 'examples'!

testDynamicFilter
	"Create and run a CSL DSP graph consisting of white noise sent through a filter with dynamic 
		center freq. and bandwidth."
	"CSLGraph testDynamicFilter"

	| out center bw noiz filt |
	center := RandEnvelope frequency: 2.0 amplitude: 900.0 offset: 1200.0 step: 400.0.
	bw := RandEnvelope frequency: 4.0 amplitude: 150.0 offset: 200.0 step: 50.0.
	noiz := WhiteNoise ampl: 1.0.
	filt := Butter in: noiz type: CslNI cslNI_get_BW_BAND_PASS center: center bandwidth: bw.
	out := Siren.CSL.PAIO s_rate: 44100 b_size: 1024.
	out setRoot: filt.
	CSL logMsg: '		Start'.
	out open.
	out start.
	6 wait.
	CSL logMsg: '		Stop'.
	out clearRoot.
	out stop.
	CSL logMsg: '		Done'.
	out close.
	PAIO release!

testFM
	"Create and run a CSL DSP graph for the canonical FM example (see BeepDemo.cpp)."
	"CSLGraph testFM"

	| out freq aenv menv mod car |
	freq := 110.
	aenv := ADSR t: 2.0 a: 0.05 d: 0.05 s: 0.5 r: 0.4.		"ampl envelope"
	aenv setScale: 0.5.
	menv := AR t: 2.0 a: 1.5 r: 0.5.							"mod index envelope"
	menv setScale: freq * 2.
	mod := Sine frequency: freq.							"modulator oscillator"
	mod setScale: menv.
	mod setOffset: freq.
	car := Sine frequency: mod.							"carrier oscillator"
	car setScale: aenv.
	out := PAIO s_rate: 44100 b_size: 1024.				"output"
	out setRoot: car.
	CSL logMsg: 'Start'.
	out open.
	aenv trigger.											"trigger envelopes and start IO"
	menv trigger.
	out start.
	3 wait.													"sleep a bit"
	CSL logMsg: 'Stop'.
	out clearRoot.											"clean up and stop"
	out stop.
	out close.
	PAIO release!

testMIDIOscillatorBank
	"Create and run a CSL DSP graph with 16 sine waves under MIDI fader control."
	"CSLGraph testMIDIOscillatorBank"

	| out mix midi ctrlrData oscBank freqData rand |
	out := PAIO s_rate: 44100 b_size: 1024.
	mix := Mixer chans: 2.
	oscBank := Array new: 16.
	rand := Random new.
	1 to: 16 do:
		[ :index | | osc pos pan |
		osc := Sine frequency: (110.0 * (rand nextFrom: 9.0 to: 1.1)) ampl: 0.04.
		pos := RandEnvelope new.
		pan := Panner input: osc position: pos.
		mix addInput: pan.
		oscBank at: index put: osc].
	out setRoot: mix.
"Play!!"
	CSL logMsg: 'Start'.
	out open.
	out start.
"Now set up the MIDI faders to control the oscillators"
	ctrlrData := WordArray new: 16.					"current value"
	freqData := WordArray new: 16 withAll: 0.			"cached value"
	ctrlrData gcCopyToHeap.		"this is so that you can pass this ptr to C"
	midi := MIDIPort new.
	midi openInput: 3.			"Edit your controller device # here"
	midi startControllerCaching.
	midi startMIDIInput.
	40 timesRepeat:				"update twice a second for 20 seconds"
		[midi readControllersFrom: 48 to: 63 into: ctrlrData.
		1 to: 16 do:
			[ :index | 
			(ctrlrData at: index) = (freqData at: index) ifFalse:
				[freqData at: index put: (ctrlrData at: index).
				(oscBank at: index) setFrequency: (110.0 + ((ctrlrData at: index) * 4))]].
		(Delay forMilliseconds: 500) wait].
	CSL logMsg: 'Stop'.
	out clearRoot.
	out stop.
	out close.
	PAIO release!

testMIDIOscillatorBank1
	"Create and run a CSL DSP graph with 16 sine waves under MIDI fader control."
	"CSLGraph testMIDIOscillatorBank"

	| out mix oscBank ctrlrData rand midi |
	out := PAIO s_rate: 44100 b_size: 1024.
	mix := Mixer chans: 2.
	oscBank := Array new: 16.
	rand := Random new.
	1 to: 16 do:
		[ :index | | osc pos pan |
		osc := Sine frequency: (rand nextFrom: 110 to: 440).
		osc setScale: 0.05.
		pos := RandEnvelope frequency: 1.0 amplitude: 1.0 offset: 0.0 step: 0.5.
		pan := Panner input: osc position: pos.
		oscBank at: index put: osc.
		mix addInput: pan].
	out setRoot: mix.
	CSL logMsg: 'Start'.
	out open.		out start.
"Now set up the MIDI faders to control the oscillators"
	false ifTrue: [midi := MIDIPort new.
	midi openInput: 3.			"Edit your controller device # here"
	midi startControllerCaching.
	midi startMIDIInput.
	ctrlrData := WordArray new: 16.
	ctrlrData gcCopyToHeap.		"this is so that you can pass this ptr to C"
	60 timesRepeat:
		[midi readControllersFrom: 48 to: 63 into: ctrlrData.
		1 to: 16 do:
			[ :index | (oscBank at: index) setFrequency: (110.0 + ((ctrlrData at: index) * 4))].
		(Delay forMilliseconds: 500) wait]].
15 wait.
	CSL logMsg: 'Stop'.
"	MIDIPort testInputStop"
	out clearRoot.
	out stop!

testMIDIOscillatorBank2
	"Create and run a CSL DSP graph with 16 sine waves under MIDI fader control."
	"CSLGraph testMIDIOscillatorBank2"

	| out mix oscBank rand |
	out := PAIO s_rate: 44100 b_size: 1024.
	mix := Mixer chans: 2.
	oscBank := Array new: 16.
	rand := Random new.
	1 to: 16 do:
		[ :index | | osc pos pan |
		osc := Sine frequency: (110.0 * (rand nextFrom: 9.0 to: 1.1)) ampl: 0.02.
		pos := RandEnvelope new.
		pan := Panner input: osc position: pos.
		mix addInput: pan.
		oscBank at: index put: osc].
	out setRoot: mix.
"Play!!"
	CSL logMsg: 'Start'.
	out open.
	out start.
		(Delay forMilliseconds: 5000) wait.
	CSL logMsg: 'Stop'.
	out clearRoot.
	out stop.
	out close.
	PAIO release!

testOscillatorBank
	"Create and run a CSL DSP graph with 50 sine waves with random-walk frequencies and positions."
	"CSLGraph testOscillatorBank"

	| out mix |
	out := PAIO s_rate: 44100 b_size: 1024.
	mix := Mixer chans: 2.
	50 timesRepeat:
		[ | osc pos pan freq |
		freq := RandEnvelope frequency: 1.0 amplitude: 200.0 offset: 300.0 step: 50.0.
		osc := Sine frequency: freq ampl: 0.005.
		pos := RandEnvelope new.
		pan := Panner input: osc position: pos.
		mix addInput: pan].
	out setRoot: mix.
	CSL logMsg: 'Start'.
	out open.		out start.
	30 wait.
	CSL logMsg: 'Stop'.
	out clearRoot.
	out stop.
	out close.
	PAIO release!

testSimpleGraph
	"Create and run a simple CSL DSP graph consisting of a Sine wave with an ADSR envelope."
	"CSLGraph testSimpleGraph"

	| env sin out |
"Create a simple sine-with-envelope graph"
	env := ADSR t: 2.0 a: 0.05 d: 0.05 s: 0.5 r: 1.0.
	env dump.
	sin := Sine frequency: 110 ampl: env.
"Create an IO object and plug in the sine"
"	IO release."
	out := PAIO s_rate: 44100 b_size: 1024.
	out setRoot: sin.
"Dump the sine (look in the console for the logging output)"
"	sin dump."
"halt if shift down"
	InputState default shiftDown ifTrue: [self halt].
"Open the output, plug in the sine, and start"
	CSL logMsg: 'Start'.
	out open.
	env trigger.
	out start.
"sleep a bit"
	3 wait.
"Shut down nicely"
	CSL logMsg: 'Stop'.
	out clearRoot.
	out stop.
	out close.
	PAIO release!

testSoundFile
	"Create and run a CSL DSP graph consisting of white noise sent through a filter with dynamic 
		center freq. and bandwidth."
	"CSLGraph testSoundFile"

	| out fil |
	fil := SoundFile path: (SirenUtility findFile: 'wet.snd').
	fil openForRead.
	out := Siren.CSL.PAIO s_rate: 44100 b_size: 1024.
	out setRoot: fil.
	CSL logMsg: 'Start'.
	out open.
	out start.
	(fil duration / 44100) asFloat wait.
	CSL logMsg: 'Stop'.
	out clearRoot.
	out stop.
	out close.
	PAIO release!

testStaticFilter
	"Create and run a simple CSL DSP graph consisting of a Sine wave with an ADSR envelope."
	"CSLGraph testStaticFilter"

	| out noiz filt |
	noiz := WhiteNoise ampl: 1.0.
	filt := Butter in: noiz type: CslNI cslNI_get_BW_BAND_PASS center: 1000.0 bandwidth: 150.0.
	out := Siren.CSL.PAIO s_rate: 44100 b_size: 1024.
	out setRoot: filt.
	InputState default shiftDown ifTrue: [self halt].		"halt if shift down"
	CSL logMsg: 'Start'.
	out open.
	out start.
	3 wait.
	out clearRoot.
	CSL logMsg: 'Stop'.
	out stop.
	out close.
	PAIO release! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!


!Siren.CSLGraph methodsFor: 'accessing'!

envelopes

	^envelopes!

parameters

	^parameters!

ugens

	^ugens! !

!Siren.CSLGraph methodsFor: 'initialize-release'!

initialize
	"Set up the receiver's default state"

	envelopes := OrderedCollection new.
	ugens := OrderedCollection new.
	parameters := OrderedCollection new.
! !

!Siren.CSLGraph methodsFor: 'performance'!

play
	"Start the receiver"

	envelopes do: 
		[ :env | env trigger]! !

