Last active
December 16, 2015 07:19
-
-
Save jacobjoaquin/5398335 to your computer and use it in GitHub Desktop.
Modular Instruments Part II
2007.07.02 The Csound Blog
by Jacob Joaquin
email [email protected] (C)2007 Jacob Joaquin
Licensed under Creative Commons (see below)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The Csound Blog | |
by Jacob Joaquin | |
email [email protected] | |
web www.thumbuki.com/csound/blog | |
(C)2007 Jacob Joaquin | |
Licensed under Creative Commons (see below) | |
2007.07.02 | |
Modular Instruments Part II | |
In the previous blog, "Modular Instruments"[1], I presented an | |
instrument design model that takes advantage of Csound's modular | |
nature by breaking the common instrument structure apart into three | |
elements: Synth Engine, Memory and Interface. (SEMI) | |
In todays blog, I create a new synth named MonoSynth based on the | |
original SEMI Simple synth by replacing the zak memory with a memory | |
core based on the chn opcodes, extending functionality of the engine, | |
introducing modulation parameters, and by incorporating a method that | |
links instances of instruments into an audio chain from within the | |
score. | |
The chn Software Bus | |
Though the zak opcodes work very well with the SEMI system, it does | |
have one significant draw back. Every zak channel has to be | |
explicitly declared by hand. If I want to use multiple Simple synth | |
engines, each with their own distinct set of parameters, I have to | |
manually declare and name every memory for every parameter for each | |
independent voice. I could get around some of the labor by writing a | |
Perl or Python script that automatically generates long lists of macro | |
definitions. However, there exists in Csound a solution that allows | |
us to create individual memory structures dynamically from within the | |
score by using the chn opcodes. | |
According to the Csound 5 manual, the chn software bus system was | |
authored by Istvan Varga in 2005.[2] I discovered these opcodes while | |
reading Steven Yi's CSound Journal article "Creating Encapsulated | |
Instruments in Csound5."[3] From my understanding, the chn opcodes | |
were designed for external applications to talk bidirectionally with | |
Csound. Though they can be used within a solely Csound environment. | |
There are a couple of features which chn offers that make them highly | |
useful. First, memory can be created from within an instrument. | |
Second, chn supports strings. | |
Memory Objects | |
The chn opcodes can be used to create memory structures that loosely | |
resemble the syntax of object-oriented programming languages.[4] A | |
memory structure starts as a class with a list of members. When an | |
object is created from the class, a new chn bus is created for each | |
member of that class. The name of each new memory is a combination of | |
the user-specified object name and the name of the member, separated | |
by a period. | |
For example, the Mixer class in todays example has six parameter: | |
SaAudioIn, kAmp, kAmpMod, kPan, kPanMod and aAudioOut. When a Mixer | |
object is created with the name "spoon", the following memory | |
structure is generated. | |
spoon.SaAudioIn | |
spoon.kAmp | |
spoon.kAmpMod | |
spoon.kPan | |
spoon.kPanMod | |
spoon.aAudioOut | |
Figure 1. A memory object created from the Mixer class. | |
This is really where the parallels between this memory structure and | |
OOP end. There is no encapsulation, as these memory structures can | |
be accessed globally. There is no methods associated with the the | |
object, as external instrument interfaces are created separately to | |
access the object's members. Technically speaking, "there is no | |
spoon"[5], just a group of memories with a useful naming scheme. | |
Some of you are probably thinking that these memory objects more | |
closely resemble C structs[6] than OOP objects. You are 100% correct. | |
The reason I've chosen the OOP metaphor is because I'm still in the | |
early experimentation phase, and I plan on adding more OOP type | |
functionality to this line of work later. | |
To aid in the creation, reading and writing of memory objects, I've | |
made a handful of user-defined opcodes: objnew_x, objget_x and | |
obset_x. There is much string work required to make these faux | |
objects to behave like OOP objects, and these UDO's handle much of it. | |
Score Signal Routing | |
I'm always looking for ways to push more orchestra-like capabilities | |
into the score. The chn opcodes have proven to be a great asset in | |
doing this. Memory objects and their associated synth engines can be | |
designed so that they can stream audio and control data to each other, | |
with the patching being done from within the score. Taken to the | |
extreme, it is entirely possible to build score based instruments with | |
a large pool of compatible SEMI instruments. | |
Here is a quick run down of how this works. Instead of having a synth | |
engine send the audio directly to the DAC or soundfile, the engine | |
writes the data to an a-rate chn member. For example, the instrs | |
MonoSynth, RingMod and Reverb write audio to their local member | |
"aAudioOut". | |
In order for another object to tap the "aAudioOut" stream of another | |
instrument, a special string member "SaAudioIn" is used to reference | |
an instance of "aAudioOut" by name, such as "spoon.aAudioOut". In | |
essence, this string member acts like a C pointer.[7] The instrs | |
RingMod, Reverb and Mixer tap into audio streams by referring to them | |
by the names stored in their members "SaAudionIn". | |
In order to connect objects together, I've created the Attach instr. | |
It accepts two arguments: The input and the output. Since Csound | |
only currently supports a single string per i-event at this time, | |
these two arguments have been consolidated into a single p-field and | |
separated by a single colon. | |
i $Attach 0 1 "cereal.SaAudioIn:spoon.aAudioOut" | |
Figure 2. This connects the audio output from spoon to the | |
audio input of cereal. | |
In the score at the bottom, I create two MonoSynth objects named | |
"lead" and "perc". The output of "perc" is read by the Mixer object | |
"percOut", which then sends the audio to the DAC or soundfile. The | |
other voice, "lead", is read by "leadRing", which is read by | |
"leadReverb" which is read by "leadOut", which is then sent to the DAC | |
or soundfile. | |
; "perc" -> "percOut" | |
i $Attach 0 1 "percOut.SaAudioIn:perc.aAudioOut" | |
; "lead" -> "leadRing" -> "leadReverb" -> "leadOut" | |
i $Attach 0 1 "leadRing.SaAudioIn:lead.aAudioOut" | |
i $Attach 0 1 "leadVerb.SaAudioIn:ring.aAudioOut" | |
i $Attach 0 1 "leadOutput.SaAudioIn:leadVerb.aAudioOut" | |
Figure 3. Two examples of audio chains from the score. | |
Modulation Instruments | |
When I was converting Simple into MonoSynth, I made some fundamental | |
changes to the way the synth engine worked in relation to the way the | |
external control instruments fed data to it. I duplicated members I | |
wanted to improve upon and appended "Mod", as in modulation, to their | |
their names. I then created/converted a series of modulation | |
instruments for controlling "Mod" parameters. | |
This newer design allows modulation instruments to be stacked and | |
overlapped. This was not possible with Simple. | |
i $MonoSynth_note 0 16 "foo" 7.00 | |
i $mLFO 0 12 "foo.kPitchMod" 1 3 0 12 0 | |
i $mLFO 4 12 "foo.kPitchMod" 2 3 3 7 0 | |
i $mPattern 0 16 "foo.kPitchMod" 4 22 | |
Figure 4. Modulation instruments can be stacked and | |
overlapped. | |
I should warn you that these modulation instruments are designed to be | |
used with "Mod" members only, as they will most likely break anything | |
else they tamper with. | |
What's Next | |
I plan on continuing work on this synth, though it may be awhile | |
before the next version surfaces publicly. I have an idea for | |
implementing envelopes better than they are now. Basically, I want to | |
keep the envelope engine(s) separate from the synth engine, and build | |
in an envelope input member for each parameter I want envelope | |
controllable. I think it'll work. Though how cluttery it'll make | |
things is still a big unknown at this time. | |
Until next time, | |
Jake | |
Permalink | |
http://www.thumbuki.com/20070702/modular-instruments-part-ii.html | |
References | |
[1] The Csound Blog - Modular Instruments | |
http://www.thumbuki.com/csound/files/thumbuki20070620.csd | |
[2] Csound 5 Manual - chn | |
http://www.csounds.com/manual/html/chn.html | |
[3] Creating Encapsulated Instruments in Csound5 by Steven Yi | |
http://www.csounds.com/journal/2006winter/encapsulatedInstruments.html | |
[4] Object-oriented programming | |
http://en.wikipedia.org/wiki/Object_oriented_programming | |
[5] Quote from The Matrix | |
http://en.wikipedia.org/wiki/The_matrix | |
[6] Composite Type - struct | |
http://en.wikipedia.org/wiki/Composite_type | |
[7] Pointer | |
http://en.wikipedia.org/wiki/Pointer | |
License | |
(cc) Creative Commons Attribution-ShareAlike 2.5 | |
You are free: | |
* to Share -- to copy, distribute, display, and perform the work | |
* to Remix -- to make derivative works | |
Under the following conditions: | |
* Attribution. You must attribute the work in the manner specified by | |
the author or licensor. | |
* Share Alike. If you alter, transform, or build upon this work, you | |
may distribute the resulting work only under a license identical to | |
this one. | |
* For any reuse or distribution, you must make clear to others the license | |
terms of this work. | |
* Any of these conditions can be waived if you get permission from the | |
copyright holder. | |
http://creativecommons.org/licenses/by-sa/2.5/ | |
<CsoundSynthesizer> | |
<CsInstruments> | |
sr = 44100 | |
kr = 11025 | |
ksmps = 4 | |
nchnls = 2 | |
; ---- Create new Object.Member ---- | |
opcode objnew_i, 0, SS | |
Sobject, Smember xin | |
Sname sprintf "%s.%s", Sobject, Smember | |
chn_k Sname, 3 | |
endop | |
opcode objnew_k, 0, SS | |
Sobject, Smember xin | |
Sname sprintf "%s.%s", Sobject, Smember | |
chn_k Sname, 3 | |
endop | |
opcode objnew_a, 0, SS | |
Sobject, Smember xin | |
Sname sprintf "%s.%s", Sobject, Smember | |
chn_a Sname, 3 | |
endop | |
opcode objnew_S, 0, SS | |
Sobject, Smember xin | |
Sname sprintf "%s.%s", Sobject, Smember | |
chn_S Sname, 3 | |
endop | |
; ---- Set value of Object.Member ---- | |
opcode objset_i, 0, iSS | |
ival, Sobject, Smember xin | |
Sname sprintf "%s.%s", Sobject, Smember | |
chnset ival, Sname | |
endop | |
opcode objset_k, 0, kSS | |
kval, Sobject, Smember xin | |
Sname sprintf "%s.%s", Sobject, Smember | |
chnset kval, Sname | |
endop | |
opcode objset_a, 0, aSS | |
aval, Sobject, Smember xin | |
Sname sprintf "%s.%s", Sobject, Smember | |
chnset aval, Sname | |
endop | |
opcode objset_S, 0, SSS | |
Sval, Sobject, Smember xin | |
Sname sprintf "%s.%s", Sobject, Smember | |
chnset Sval, Sname | |
endop | |
; ---- Get value from Object.Member ---- | |
opcode objget_i, i, SS | |
Sobject, Smember xin | |
Sname sprintf "%s.%s", Sobject, Smember | |
iout chnget Sname | |
xout iout | |
endop | |
opcode objget_k, k, SS | |
Sobject, Smember xin | |
Sname sprintf "%s.%s", Sobject, Smember | |
kout chnget Sname | |
xout kout | |
endop | |
opcode objget_a, a, SS | |
Sobject, Smember xin | |
Sname sprintf "%s.%s", Sobject, Smember | |
aout chnget Sname | |
xout aout | |
endop | |
opcode objget_S, S, SS | |
Sobject, Smember xin | |
Sname sprintf "%s.%s", Sobject, Smember | |
Sout chnget Sname | |
xout Sout | |
endop | |
; ---- Instrument Definitions ---- | |
# define MonoSynth_new # 1 # | |
# define RingMod_new # 2 # | |
# define Reverb_new # 3 # | |
# define Mixer_new # 4 # | |
# define Attach # 5 # | |
# define Parameter # 6 # | |
# define Fader # 7 # | |
# define mEnvelope # 8 # | |
# define mLFO # 9 # | |
# define mSampleAndHold # 10 # | |
# define mPattern # 11 # | |
# define MonoSynth_note # 12 # | |
# define MonoSynth # 13 # | |
# define RingMod # 14 # | |
# define Reverb # 15 # | |
# define Mixer # 16 # | |
; ---- Tempo ---- | |
# define tempo # 135 # | |
# define duration # 77 # | |
instr $MonoSynth_new | |
Sobject strget p4 | |
; Create members of Sobject | |
objnew_k Sobject, "kPitch" | |
objnew_k Sobject, "kPitchMod" | |
objnew_k Sobject, "kOsc1Transpose" | |
objnew_k Sobject, "kOsc1TransposeMod" | |
objnew_k Sobject, "kOsc1Waveform" | |
objnew_k Sobject, "kOsc1Amplitude" | |
objnew_k Sobject, "kOsc1AmplitudeMod" | |
objnew_k Sobject, "kOsc2Transpose" | |
objnew_k Sobject, "kOsc2TransposeMod" | |
objnew_k Sobject, "kOsc2Waveform" | |
objnew_k Sobject, "kOsc2Amplitude" | |
objnew_k Sobject, "kOsc2AmplitudeMod" | |
objnew_k Sobject, "kFilterMode" | |
objnew_k Sobject, "kFilterModeMod" | |
objnew_k Sobject, "kFilterFreq" | |
objnew_k Sobject, "kFilterFreqMod" | |
objnew_k Sobject, "kFilterRes" | |
objnew_k Sobject, "kFilterResMod" | |
objnew_k Sobject, "kAmplitude" | |
objnew_k Sobject, "kAmplitudeMod" | |
objnew_k Sobject, "kAmpAttack" | |
objnew_k Sobject, "kAmpRelease" | |
objnew_k Sobject, "kAmpEnv" | |
objnew_k Sobject, "kAmpEnvCurve" | |
objnew_a Sobject, "aAudioOut" | |
; Set default values for members | |
objset_i 0, Sobject, "kPitch" | |
objset_i 0, Sobject, "kPitchMod" | |
objset_i 0, Sobject, "kOsc1Transpose" | |
objset_i 0, Sobject, "kOsc1TransposeMod" | |
objset_i 1, Sobject, "kOsc1Waveform" | |
objset_i 1, Sobject, "kOsc1Amplitude" | |
objset_i 1, Sobject, "kOsc1AmplitudeMod" | |
objset_i 0, Sobject, "kOsc2Transpose" | |
objset_i 0, Sobject, "kOsc2TransposeMod" | |
objset_i 1, Sobject, "kOsc2Waveform" | |
objset_i 1, Sobject, "kOsc2Amplitude" | |
objset_i 1, Sobject, "kOsc2AmplitudeMod" | |
objset_i 0, Sobject, "kFilterMode" | |
objset_i 0, Sobject, "kFilterModeMod" | |
objset_i 22050, Sobject, "kFilterFreq" | |
objset_i 0, Sobject, "kFilterFreqMod" | |
objset_i 0.0, Sobject, "kFilterRes" | |
objset_i 0.0, Sobject, "kFilterResMod" | |
objset_i 0.0, Sobject, "kAmplitude" | |
objset_i 1.0, Sobject, "kAmplitudeMod" | |
objset_i 2.0, Sobject, "kAmpAttack" | |
objset_i 6.0, Sobject, "kAmpRelease" | |
objset_i 0, Sobject, "kAmpEnv" | |
objset_i 2, Sobject, "kAmpEnvCurve" | |
endin | |
instr $RingMod_new | |
Sobject strget p4 | |
; Create members of Sobject | |
objnew_S Sobject, "SaAudioIn" | |
objnew_k Sobject, "kFreq" | |
objnew_k Sobject, "kFreqMod" | |
objnew_k Sobject, "kTable" | |
objnew_k Sobject, "kMix" | |
objnew_k Sobject, "kMixMod" | |
objnew_a Sobject, "aAudioOut" | |
; Set Default Internal Parameters | |
objset_i 440, Sobject, "kFreq" | |
objset_i 0, Sobject, "kFreqMod" | |
objset_i 1, Sobject, "kTable" | |
objset_i 0.5, Sobject, "kMix" | |
objset_i 0, Sobject, "kMixMod" | |
endin | |
instr $Reverb_new | |
Sobject strget p4 | |
; Create members of Sobject | |
objnew_S Sobject, "SaAudioIn" | |
objnew_k Sobject, "kTime" | |
objnew_k Sobject, "kTimeMod" | |
objnew_k Sobject, "kDiffuse" | |
objnew_k Sobject, "kDiffuseMod" | |
objnew_k Sobject, "kMix" | |
objnew_k Sobject, "kMixMod" | |
objnew_a Sobject, "aAudioOut" | |
; Set Default Internal Parameters | |
objset_i 1, Sobject, "kTime" | |
objset_i 0, Sobject, "kTimeMod" | |
objset_i 0, Sobject, "kDiffuse" | |
objset_i 0, Sobject, "kDiffuseMod" | |
objset_i 0.5, Sobject, "kMix" | |
objset_i 0, Sobject, "kMixMod" | |
endin | |
instr $Mixer_new | |
Sobject strget p4 | |
; Create members of Sobject | |
objnew_S Sobject, "SaAudioIn" | |
objnew_k Sobject, "kAmp" | |
objnew_k Sobject, "kAmpMod" | |
objnew_k Sobject, "kPan" | |
objnew_k Sobject, "kPanMod" | |
objnew_a Sobject, "aAudioOut" | |
; Set Default Internal Parameters | |
objset_i 1, Sobject, "kAmp" | |
objset_i 0, Sobject, "kAmpMod" | |
objset_i 0.5, Sobject, "kPan" | |
objset_i 0, Sobject, "kPanMod" | |
endin | |
instr $Attach | |
Smember strget p4 | |
; Parse Smember | |
istrlen strlen Smember | |
idelimiter strindex Smember, ":" | |
Sobject strsub Smember, 0, idelimiter | |
SmodSource strsub Smember, idelimiter + 1, istrlen | |
chnset SmodSource, Sobject | |
endin | |
instr $Parameter | |
Smember strget p4 | |
ivalue = p5 | |
chnset ivalue, Smember | |
endin | |
instr $Fader | |
idur = p3 | |
Smember strget p4 | |
ivalue = p5 | |
isteepness = p6 | |
ioldvalue chnget Smember | |
if ( isteepness == 1.0 ) kgoto line | |
kphasor phasor 1 / idur | |
kline expcurve kphasor, isteepness | |
kgoto end | |
line: | |
kline line 0, idur, 1 | |
end: | |
kline = kline * ( ivalue - ioldvalue ) + ioldvalue | |
chnset kline, Smember | |
endin | |
instr $mEnvelope | |
idur = p3 | |
Smember strget p4 | |
ivalue1 = p5 | |
ivalue2 = p6 | |
isteepness = p7 | |
kget chnget Smember | |
if ( isteepness == 1.0 ) kgoto line | |
kphasor phasor 1 / idur | |
kline expcurve kphasor, isteepness | |
kgoto end | |
line: | |
kline line 0, idur, 1 | |
end: | |
kline = kline * ( ivalue2 - ivalue1 ) + ivalue1 | |
chnset kline + kget, Smember | |
endin | |
instr $mLFO | |
idur = p3 | |
Smember strget p4 | |
ifreq = p5 ; In Beats | |
ishape = p6 | |
imin = p7 | |
imax = p8 | |
iphase = p9 | |
kget chnget Smember | |
koscil oscil 0.5, ifreq * $tempo / 60, ishape, iphase | |
koscil = ( koscil + 0.5 ) * ( imax - imin ) + imin | |
chnset koscil + kget, Smember | |
endin | |
instr $mSampleAndHold | |
idur = p3 | |
Smember strget p4 | |
ifreq = p5 | |
imin = p6 | |
imax = p7 | |
idistribution = p8 | |
kget chnget Smember | |
krnd randh 0.5, ifreq * $tempo / 60 | |
krnd = ( krnd + 0.5 ) | |
if ( idistribution <= 1.0 ) kgoto skip | |
krnd expcurve krnd, idistribution | |
skip: | |
krnd = krnd * ( imax - imin ) + imin | |
chnset krnd + kget, Smember | |
endin | |
instr $mPattern | |
idur = p3 | |
Smember strget p4 | |
ifreq = p5 | |
itable = p6 | |
kget chnget Smember | |
itableng tableng itable | |
kclock phasor ifreq * $tempo / 60 / itableng | |
kpattern table kclock, itable, -1 | |
chnset kpattern + kget, Smember | |
endin | |
instr $MonoSynth_note | |
idur = p3 | |
Smember strget p4 | |
ipch = cpspch( p5 ) | |
kattack objget_k Smember, "kAmpAttack" | |
krelease objget_k Smember, "kAmpRelease" | |
kampEnv objget_k Smember, "kAmpEnv" | |
kampEnv = kampEnv + 1 / kattack / kr + 1 / krelease / kr | |
kampEnv limit kampEnv, 0, 1 | |
objset_i ipch, Smember, "kPitch" | |
objset_k kampEnv, Smember, "kAmpEnv" | |
endin | |
instr $MonoSynth | |
idur = p3 | |
Sobject strget p4 | |
kpitch objget_k Sobject, "kPitch" | |
kpitchMod objget_k Sobject, "kPitchMod" | |
ktranspose1 objget_k Sobject, "kOsc1Transpose" | |
ktransposeMod1 objget_k Sobject, "kOsc1TransposeMod" | |
kwaveform1 objget_k Sobject, "kOsc1Waveform" | |
kosc1Amp objget_k Sobject, "kOsc1Amplitude" | |
kosc1AmpMod objget_k Sobject, "kOsc1AmplitudeMod" | |
ktranspose2 objget_k Sobject, "kOsc2Transpose" | |
ktransposeMod2 objget_k Sobject, "kOsc2TransposeMod" | |
kwaveform2 objget_k Sobject, "kOsc2Waveform" | |
kosc2Amp objget_k Sobject, "kOsc2Amplitude" | |
kosc2AmpMod objget_k Sobject, "kOsc2AmplitudeMod" | |
kfilterMode objget_k Sobject, "kFilterMode" | |
kfilterModeMod objget_k Sobject, "kFilterModeMod" | |
kfilterFreq objget_k Sobject, "kFilterFreq" | |
kfilterFreqMod objget_k Sobject, "kFilterFreqMod" | |
kfilterRes objget_k Sobject, "kFilterRes" | |
kfilterResMod objget_k Sobject, "kFilterResMod" | |
kamplitude objget_k Sobject, "kAmplitude" | |
kamplitudeMod objget_k Sobject, "kAmplitudeMod" | |
kampRelease objget_k Sobject, "kAmpRelease" | |
kampEnv objget_k Sobject, "kAmpEnv" | |
kampEnvCurve objget_k Sobject, "kAmpEnvCurve" | |
; Oscillator | |
aosc1 oscilikt 1, (kpitch)*2^((ktranspose1+ktransposeMod1+kpitchMod)/12), kwaveform1, -1 | |
aosc2 oscilikt 1, (kpitch)*2^((ktranspose2+ktransposeMod2+kpitchMod)/12), kwaveform2, -1 | |
aosc = ( aosc1 * kosc1Amp * kosc1AmpMod + aosc2 * kosc2Amp * kosc2AmpMod ) * 0.5 | |
; Filter | |
alp moogladder aosc, kfilterFreq + kfilterFreqMod, kfilterRes + kfilterResMod, 0 | |
ahp buthp aosc, kfilterFreq + kfilterFreqMod | |
afilter = alp * ( 1 - ( kfilterMode + kfilterModeMod ) ) + ahp * ( kfilterMode + kfilterModeMod ) | |
; Amplifier | |
kampEnvFunction expcurve kampEnv, kampEnvCurve | |
avca = afilter * ( kamplitude * kamplitudeMod ) * kampEnvFunction | |
; Output | |
objset_a avca, Sobject, "aAudioOut" | |
; Setup for next pass | |
objset_k 0, Sobject, "kPitchMod" | |
objset_k 0, Sobject, "kOsc1TransposeMod" | |
objset_k 0, Sobject, "kOsc2TransposeMod" | |
objset_k 1, Sobject, "kOsc1AmplitudeMod" | |
objset_k 1, Sobject, "kOsc2AmplitudeMod" | |
objset_k 0, Sobject, "kFilterModeMod" | |
objset_k 0, Sobject, "kFilterFreqMod" | |
objset_k 0, Sobject, "kFilterResMod" | |
objset_k 1, Sobject, "kAmplitudeMod" | |
kampEnv = kampEnv - 1 / kampRelease / kr | |
kampEnv limit kampEnv, 0, 1 | |
objset_k kampEnv, Sobject, "kAmpEnv" | |
endin | |
instr $RingMod | |
Sobject strget p4 | |
SaaudioIn objget_S Sobject, "SaAudioIn" | |
aaudioIn chnget SaaudioIn | |
kfreq objget_k Sobject, "kFreq" | |
kfreqMod objget_k Sobject, "kFreqMod" | |
ktable objget_k Sobject, "kTable" | |
kmix objget_k Sobject, "kMix" | |
kmixMod objget_k Sobject, "kMixMod" | |
kmix = kmix + kmixMod | |
kmix limit kmix, 0, 1 | |
a1 oscilikt 1, kfreq + kfreqMod, ktable | |
a1 = aaudioIn * ( 1 - kmix ) + aaudioIn * a1 * kmix | |
objset_k 0, Sobject, "kFreqMod" | |
objset_k 0, Sobject, "kMixMod" | |
objset_a a1, Sobject, "aAudioOut" | |
endin | |
instr $Reverb | |
Sobject strget p4 | |
SaaudioIn objget_S Sobject, "SaAudioIn" | |
aaudioIn chnget SaaudioIn | |
ktime objget_k Sobject, "kTime" | |
ktimeMod objget_k Sobject, "kTimeMod" | |
kdiffuse objget_k Sobject, "kDiffuse" | |
kdiffuseMod objget_k Sobject, "kDiffuseMod" | |
kmix objget_k Sobject, "kMix" | |
kmixMod objget_k Sobject, "kMixMod" | |
kdiffuse = kdiffuse + kdiffuseMod | |
kdiffuse limit kdiffuse, 0, 1 | |
kmix = kmix + kmixMod | |
kmix limit kmix, 0, 1 | |
areverb nreverb aaudioIn, ktime + ktimeMod, kdiffuse | |
aaudioOut = aaudioIn * ( 1 - kmix ) + areverb * kmix | |
objset_a aaudioOut, Sobject, "aAudioOut" | |
; Setup for next pass | |
objset_k 0, Sobject, "kTimeMod" | |
objset_k 0, Sobject, "kMixMod" | |
endin | |
instr $Mixer | |
Sobject strget p4 | |
SaaudioIn objget_S Sobject, "SaAudioIn" | |
aaudioIn chnget SaaudioIn | |
kamp objget_k Sobject, "kAmp" | |
kampMod objget_k Sobject, "kAmpMod" | |
kpan objget_k Sobject, "kPan" | |
kpanMod objget_k Sobject, "kPanMod" | |
aaudioIn = aaudioIn * ( kamp * kampMod ) * 0dbfs | |
kpan = kpan + kpanMod | |
kpan limit kpan, 0, 1 | |
aleft = aaudioIn * ( 1 - kpan ) | |
aright = aaudioIn * kpan | |
outs aleft, aright | |
objset_k 1, Sobject, "kAmpMod" | |
objset_k 0, Sobject, "kPanMod" | |
endin | |
</CsInstruments> | |
<CsScore> | |
; ---- Instrument Definitions ---- | |
# define MonoSynth_new # 1 # | |
# define RingMod_new # 2 # | |
# define Reverb_new # 3 # | |
# define Mixer_new # 4 # | |
# define Attach # 5 # | |
# define Parameter # 6 # | |
# define Fader # 7 # | |
# define mEnvelope # 8 # | |
# define mLFO # 9 # | |
# define mSampleAndHold # 10 # | |
# define mPattern # 11 # | |
# define MonoSynth_note # 12 # | |
# define MonoSynth # 13 # | |
# define RingMod # 14 # | |
# define Reverb # 15 # | |
# define Mixer # 16 # | |
; ---- Tempo ---- | |
# define tempo # 135 # | |
# define duration # 77 # | |
; ---- f-tables ---- | |
; Waveforms | |
f1 0 65537 10 1 ; Sine | |
f2 0 65537 -7 0 16384 1 32768 -1 16386 0 ; Triangle | |
f3 0 65537 -7 1 32768 1 0 -1 32768 -1 ; Square | |
f4 0 65537 -7 -1 65526 1 ; Saw Up | |
f5 0 65537 21 1 ; White Noise | |
f10 0 65537 10 1 0 [-1/11] 0 [1/19] 0 [-1/27] 0 [1/35] ; Band-limited Triangle | |
f11 0 65537 10 1 0 [1/3] 0 [1/5] 0 [1/7] 0 [1/9] ; Band-limited Square | |
f12 0 65537 10 1 [1/2] [1/3] [1/4] [1/5] [1/6] [1/7] [1/8] [1/9] ; Band-limited Saw | |
; Note Patterns | |
f22 0 9 -2 12 9 4 0 12 9 4 11 | |
;f23 0 9 -2 12 7 3 -2 -2 12 7 0 | |
;f23 0 9 -2 12 7 7 -2 3 3 12 0 | |
f23 0 9 -2 12 7 7 -2 3 3 -2 5 | |
; Windows | |
f50 0 513 -7 1 32 -1 480 -1 ; Window for perc amp | |
f51 0 4096 -7 1 2000 1 48 -1 2000 -1 48 1 ; Window for lead amp output gating | |
f52 0 5 -7 440 880 262 100 | |
; Half second delay before starting audio | |
s | |
f0 0.5 | |
s | |
; Tempo | |
t 0 $tempo | |
; ---- Create Objects ---- | |
i $MonoSynth_new 0 1 "perc" | |
i $Mixer_new 0 1 "percOut" | |
i $MonoSynth_new 0 1 "lead" | |
i $RingMod_new 0 1 "leadRing" | |
i $Reverb_new 0 1 "leadVerb" | |
i $Mixer_new 0 1 "leadOutput" | |
; ---- Turn on Objects ---- | |
i $MonoSynth 0 $duration "perc" | |
i $Mixer 0 $duration "percOut" | |
i $MonoSynth 0 $duration "lead" | |
i $RingMod 0 $duration "leadRing" | |
i $Reverb 0 $duration "leadVerb" | |
i $Mixer 0 $duration "leadOutput" | |
; ---- Assemble Audio Chain ---- | |
i $Attach 0 1 "percOut.SaAudioIn:perc.aAudioOut" | |
i $Attach 0 1 "leadRing.SaAudioIn:lead.aAudioOut" | |
i $Attach 0 1 "leadVerb.SaAudioIn:leadRing.aAudioOut" | |
i $Attach 0 1 "leadOutput.SaAudioIn:leadVerb.aAudioOut" | |
; ---- Set Initial Parameter ---- | |
; synth | |
i $Parameter 0 1 "lead.kOsc1Waveform" 2 | |
i $Parameter 0 1 "lead.kOsc2Waveform" 2 | |
i $Parameter 0 1 "lead.kOsc2Transpose" 0.1 | |
i $Parameter 0 1 "lead.kOsc1Amplitude" 1 | |
i $Parameter 0 1 "lead.kOsc2Amplitude" 1 | |
i $Parameter 0 1 "lead.kAmplitude" 0.25 | |
i $Parameter 0 1 "lead.kAmpAttack" 0.05 | |
i $Parameter 0 1 "lead.kAmpRelease" 3 | |
i $Parameter 0 1 "lead.kAmpEnvCurve" 10000 | |
i $Parameter 0 1 "perc.kOsc1Waveform" 5 | |
i $Parameter 0 1 "perc.kOsc2Waveform" 2 | |
i $Parameter 0 1 "perc.kOsc2Transpose" 0 | |
i $Parameter 0 1 "perc.kOsc1Amplitude" 1 | |
i $Parameter 0 1 "perc.kOsc2Amplitude" 1.25 | |
i $Parameter 0 1 "perc.kFilterMode" 0.9 | |
i $Parameter 0 1 "perc.kFilterFreq" 100 | |
i $Parameter 0 1 "perc.kAmplitude" 0.25 | |
i $Parameter 0 1 "perc.kAmpAttack" 0.001 | |
i $Parameter 0 1 "perc.kAmpRelease" 0.01 | |
i $Parameter 0 1 "perc.kAmpEnvCurve" 10000 | |
; fx | |
i $Parameter 0 1 "leadRing.kMix" 0 | |
i $Parameter 0 1 "leadRing.kFreq" 440 | |
i $Parameter 0 1 "leadVerb.kMix" 0.1 | |
i $Parameter 0 1 "leadVerb.kTime" 1 | |
i $Parameter 0 1 "leadVerb.kDiffuse" 0.5 | |
; mixers | |
i $Parameter 0 1 "leadOutput.kAmp" 3 | |
i $Parameter 0 1 "percOut.kAmp" 2.5 | |
; ---- Synth Music Demo ---- | |
; ---- Measures 1 - 8 ---- | |
i $Parameter 0 1 "percOut.kPan" 0.7 | |
i $mLFO 17 11 "perc.kAmplitudeMod" 0.5 50 -1 0 0 | |
i $MonoSynth_note 17 10.25 "perc" 8.00 | |
i $mLFO 28 0.5 "perc.kAmplitudeMod" 0.5 50 -1 0 0 | |
i $MonoSynth_note 28 0.25 "perc" 8.00 | |
i $mPattern 0 28 "lead.kPitchMod" 4 22 | |
i $MonoSynth_note 0 1 "lead" 7.00 | |
i $MonoSynth_note 4 . "lead" 7.07 | |
i $MonoSynth_note 8 . "lead" 7.09 | |
i $MonoSynth_note 12 . "lead" 7.04 | |
i $MonoSynth_note 16 . "lead" 7.00 | |
i $MonoSynth_note 20 . "lead" 7.07 | |
i $MonoSynth_note 24 . "lead" 7.09 | |
i $Parameter 28 1 "lead.kOsc1Waveform" 4 | |
i $Parameter 28 1 "lead.kOsc2Waveform" 4 | |
i $Parameter 28 1 "lead.kOsc1Transpose" -0.1 | |
i $Parameter 28 1 "lead.kOsc2Transpose" 0.1 | |
i $Parameter 28 1 "lead.kFilterMode" 0 | |
i $Parameter 28 1 "lead.kFilterFreq" 1200 | |
i $Parameter 28 1 "lead.kFilterRes" 0.9 | |
i $Parameter 28 1 "lead.kAmplitude" 0.3 | |
i $Fader 28 4 "leadVerb.kMixMod" 0.8 2 | |
i $MonoSynth_note 28 4 "lead" 5.00 | |
i $mLFO 30 2 "leadOutput.kPanMod" 8 1 -0.25 0.25 0 | |
i $mEnvelope 30 2 "lead.kPitchMod" 0 48 2 | |
; ---- Measures 9 - 17 ---- | |
i $mLFO 31 33 "perc.kAmplitudeMod" 0.5 50 -1 0 0 | |
i $MonoSynth_note 31 32.5 "perc" 8.00 | |
i $Parameter 32 1 "lead.kOsc1Waveform" 2 | |
i $Parameter 32 1 "lead.kOsc2Waveform" 3 | |
i $Parameter 32 1 "lead.kOsc2Transpose" 0.1 | |
i $Parameter 32 1 "lead.kOsc1Amplitude" 1 | |
i $Parameter 32 1 "lead.kOsc2Amplitude" .25 | |
i $Parameter 32 1 "lead.kFilterMode" 0 | |
i $Parameter 32 1 "lead.kFilterFreq" 22000 | |
i $Parameter 32 1 "lead.kFilterRes" 0.0 | |
i $Parameter 32 1 "lead.kAmplitude" 0.25 | |
i $Parameter 32 1 "lead.kAmpAttack" 0.05 | |
i $Parameter 32 1 "lead.kAmpRelease" 3 | |
i $Parameter 32 1 "lead.kAmpEnvCurve" 10000 | |
i $Parameter 32 1 "leadVerb.kMix" 0.1 | |
i $Parameter 32 1 "leadVerb.kTime" 1 | |
i $Fader 32 0.1 "leadVerb.kMixMod" 0.1 | |
i $Parameter 32 1 "leadOutput.kPan" 0.4 | |
i $mLFO 32 32 "leadOutput.kPanMod" 0.333 1 -0.15 0.15 0 | |
i $mPattern 32 32 "lead.kPitchMod" 4 23 | |
i $Fader 32 32 "leadRing.kFreq" 1000 2 | |
i $mLFO 32 32 "leadRing.kFreqMod" 2 3 0 440 0 | |
i $mPattern 32 32 "leadRing.kFreqMod" 1 52 | |
i $MonoSynth_note 32 2.5 "lead" 7.00 | |
i $Parameter 34.5 1 "leadRing.kMix" 1 | |
i $mEnvelope 34 2 "leadVerb.kMixMod" 0 0.4 2 | |
i $MonoSynth_note 36 2.5 "lead" 7.05 | |
i $Parameter 36 1 "leadRing.kMix" 0 | |
i $Parameter 38.5 1 "leadRing.kMix" 1 | |
i $mEnvelope 38 2 "leadVerb.kMixMod" 0 0.4 2 | |
i $MonoSynth_note 40 2.5 "lead" 7.00 | |
i $Parameter 40 1 "leadRing.kMix" 0 | |
i $Parameter 42.5 1 "leadRing.kMix" 1 | |
i $mEnvelope 42 2 "leadVerb.kMixMod" 0 0.4 2 | |
i $MonoSynth_note 44 2.5 "lead" 7.07 | |
i $Parameter 44 1 "leadRing.kMix" 0 | |
i $mEnvelope 46 2 "leadVerb.kMixMod" 0 0.4 2 | |
i $mLFO 46 2 "leadOutput.kAmpMod" 5 51 0 1 0.0 | |
i $mLFO 48 16 "lead.kOsc2TransposeMod" 1 3 7 12 0 | |
i $MonoSynth_note 48 2.5 "lead" 7.00 | |
i $mEnvelope 50 2 "leadRing.kMixMod" 0 0.7 2 | |
i $mEnvelope 50 2 "leadVerb.kMixMod" 0 0.9 2 | |
i $MonoSynth_note 52 2.5 "lead" 7.05 | |
i $mEnvelope 54 2 "leadRing.kMixMod" 0 0.7 2 | |
i $mEnvelope 54 2 "leadVerb.kMixMod" 0 0.9 2 | |
i $MonoSynth_note 56 2.5 "lead" 7.00 | |
i $mEnvelope 58 2 "leadRing.kMixMod" 0 0.7 2 | |
i $mEnvelope 58 2 "leadVerb.kMixMod" 0 0.9 2 | |
i $MonoSynth_note 60 2.5 "lead" 7.07 | |
i $mEnvelope 62 2 "leadRing.kMixMod" 0 0.7 2 | |
i $mEnvelope 62 2 "leadVerb.kMixMod" 0 0.9 2 | |
i $mLFO 62 2 "leadOutput.kAmpMod" 3.3 51 0 1 0.0 | |
i $Parameter 64 1 "lead.kOsc1Waveform" 4 | |
i $Parameter 64 1 "lead.kOsc2Waveform" 4 | |
i $Parameter 64 1 "lead.kOsc1Transpose" -0.1 | |
i $Parameter 64 1 "lead.kOsc2Transpose" 0.1 | |
i $Parameter 64 1 "lead.kOsc1Amplitude" 1 | |
i $Parameter 64 1 "lead.kOsc2Amplitude" 1 | |
i $Parameter 64 1 "lead.kFilterMode" 0 | |
i $Parameter 64 1 "lead.kFilterFreq" 1200 | |
i $Parameter 64 1 "lead.kFilterRes" 0.9 | |
i $Parameter 64 1 "lead.kAmpRelease" 6 | |
i $MonoSynth_note 64 4 "lead" 5.00 | |
i $Fader 68 7 "lead.kFilterFreq" 50 100 | |
i $Parameter 64 1 "perc.kOsc1Waveform" 5 | |
i $Parameter 64 1 "perc.kOsc2Waveform" 5 | |
i $Parameter 64 1 "perc.kOsc2Transpose" 0 | |
i $Parameter 64 1 "perc.kOsc1Amplitude" 1 | |
i $Parameter 64 1 "perc.kOsc2Amplitude" 1 | |
i $Parameter 64 1 "perc.kFilterMode" 0 | |
i $Parameter 64 1 "perc.kFilterFreq" 100 | |
i $Parameter 64 1 "perc.kFilterRes" 0.9 | |
i $Parameter 64 1 "perc.kAmplitude" 0.125 | |
i $Parameter 64 1 "perc.kAmpAttack" 0.05 | |
i $Parameter 64 1 "perc.kAmpRelease" 0.25 | |
i $Parameter 64 1 "perc.kAmpEnvCurve" 2 | |
i $Parameter 64 1 "percOut.kPan" 0 | |
i $Fader 64 2 "perc.kAmplitude" 0.125 2 | |
i $mSampleAndHold 64 12 "perc.kFilterFreqMod" 2 0 2000 2 | |
i $mSampleAndHold 64 12 "percOut.kPanMod" 2 0 1 2 | |
i $Fader 66 10 "perc.kAmplitude" 0 2 | |
i $MonoSynth_note 64 0.1 "perc" 7.00 | |
i $MonoSynth_note 64.5 . "perc" . | |
i $MonoSynth_note 65 . "perc" . | |
i $MonoSynth_note 65.5 . "perc" . | |
i $MonoSynth_note 66 . "perc" . | |
i $MonoSynth_note 66.5 . "perc" . | |
i $MonoSynth_note 67 . "perc" . | |
i $MonoSynth_note 67.5 . "perc" . | |
i $MonoSynth_note 68 . "perc" . | |
i $MonoSynth_note 68.5 . "perc" . | |
i $MonoSynth_note 69 . "perc" . | |
i $MonoSynth_note 69.5 . "perc" . | |
i $MonoSynth_note 70 . "perc" . | |
i $MonoSynth_note 70.5 . "perc" . | |
i $MonoSynth_note 71 . "perc" . | |
i $MonoSynth_note 71.5 . "perc" . | |
i $MonoSynth_note 72 . "perc" . | |
i $MonoSynth_note 72.5 . "perc" . | |
i $MonoSynth_note 73 . "perc" . | |
i $MonoSynth_note 73.5 . "perc" . | |
i $MonoSynth_note 74 . "perc" . | |
i $MonoSynth_note 74.5 . "perc" . | |
i $MonoSynth_note 75 . "perc" . | |
i $MonoSynth_note 75.5 . "perc" . | |
i $MonoSynth_note 76 . "perc" . | |
i $MonoSynth_note 76.5 . "perc" . | |
e $duration | |
</CsScore> | |
</CsoundSynthesizer> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment