Im letzten Teil habe ich Grundlegendes zu Instrumenten und deren Kompositionen (Scores) geschrieben, diesmal möchte ich auf ein paar weitere Details hierzu eingehen.

Die GEN10 Routine

Das letzte mal habe ich die GEN10 Routine benutzt, um eine simple Sinuswelle zu erzeugen. Man kann aber noch viel mehr mit dieser Routine anstellen. Ich könnte beispielsweise ein Funktion mit fünf harmonisch verknüpften Sinuswellen erstellen, einfach indem ich die 1 fünf mal hinter den GEN Typen schreibe.

f1  0  4096  10   1    1    1    1    1

Alle Partiellen haben dieselbe Amplitude. GEN10 erstellt ausschließlich harmonische Komponenten, somit müssen wir der Routine nicht extra sagen, dass die Relationen harmonisch sein sollen. Wenn ich im Instrument also die Grundfrequenz ändere, werden automatisch alle Partiellen angepasst. Z.B. wenn die Grundfrequenz 220Hz beträgt, dann wird die zweite Harmonische 440 und die dritte 660 sein. Wenn wir die Fundamentale nun auf 100Hz ändern, wird die zweite zu 200 und die dritte zu 400 geändert.

Wichtig ist dabei die Amplitude der einzelnen Harmonischen zu beachten. Generell kann man sagen, dass je größer die Amplitude einer einzelnen Harmonischen ist, desto hörbarer/lauter wird dieser dann auch sein. Das verändert dann natürlich das Timbre des Tons.

Man kann also einen tonalen Unterschied hören, wenn ich so etwas schreibe:

f1 0 4096 10 1 1 1 15 1  

oder eben jenes:

f1 0 4096 10 1 1 1 1 15

Beim ersten Beispiel ist die 4. Harmonische lauter und beim zweiten Beispiel die 5. Harmonische.

Hier ein größeres Beispiel:

<CsoundSynthesizer>

<CsOptions>
-odac               ;realtime audio
</CsOptions>


<CsInstruments>
  sr = 48000
  ksmps = 10
  nchnls = 1

  instr   1
      aneworc oscil 10000, 320, 1  ;oscillator with 10000 amplitude,  
                                   ;320Hz (frequency), function #1
      out aneworc
  endin
</CsInstruments>

<CsScore>
  f1 0 4096 10 10 9 8 7 6 5 4 3 2 1
  ;with this line, we obtain a waveform made of the fundamental 
  ;plus harmonics up to the tenth, with decreasing amplitude

  f1 3 4096 10 10 5 3.3 2.5 2 1.6 1.4 1.25 1.1 1
  ;with this line, components add up to approximate a sawtooth waveform

  f1 6 4096 10 10 0 3.3 0 2 0 1.4 0 1.1
  ;with this line, components add up to approximate a squared waveform

  f1 9  4096 10 1                 ;a sine wave
  f1 12 4096 10 0  1              ;2nd harmonic only
  f1 15 4096 10 0  0 1            ;3rd harmonic only
  f1 18 4096 10 0  0 0 1          ;4th harmnonic only
  f1 21 4096 10 1  1 1 1          ;fund+2nd+3rd+4th
  f1 24 4096 10 10 0 0 0 0 0 1    ;fund+7th
  f1 27 4096 10 0  0 0 0 0 0 1    ;7th only

  i1 0  2
  i1 3  2
  i1 6  2
  i1 9  2
  i1 12 2
  i1 15 2
  i1 18 2
  i1 21 2
  i1 24 2
  i1 27 2
</CsScore>

</CsoundSynthesizer> 

Wie man im Beispiel sieht und vor allem hört, kann man verschiedene Timbres kreieren, wenn man verschiedene Harmonische hinzufügt, die aber alle über derselben fundamentalen Frequenz von 320Hz arbeiten. Die Amplitude wurde mit 10.000 im Instrument festgelegt, wurde aber anhand der einzelnen Komponenten variiert. In einer Funktion wie diesen:

f1 0 4096 10 1 1 1 1

hat jede der vier Komponenten dieselbe Lautstärke, während hier:

f1 0 4096 10 2 1 1 1

die Fundamentale doppelt so laut ist wie die anderen Komponenten.

Falls jemand neugierig ist und etwas über die anderen GEN Routinen erfahren möchte, der kann sich gerne mal die entsprechenden Seiten der offiziellen Dokumentation ansehen.

Wie man die Amplitude und Frequenz für jeder einzelnen Note ändert

Man kann natürlich für jede Note eine Funktion schreiben, wenn man verschiedene Frequenzen und Lautstärken wünscht. Allerdings geht das auch einfacher. Bei einer Änderung der Lautstärke muss ich einfach die feste Amplitude von 1000 mit dem Ton ändern. Im letzten Kapitel haben wir schon Parameter kennengelernt. Anstatt eine Konstante für jedes Argument des Oszillators zu benutzen, können wir auch Parameter nutzen.

Wenn ich nun also die 10.000 mit dem Parameter p4 ersetze und die Frequenz von 320 mit dem Parameter p5, kann ich diese p-Fields im Score nutzen, um die besagten Parameter variabel anzugeben.

<CsoundSynthesizer>

<CsOptions>
-odac               ;realtime audio
</CsOptions>


<CsInstruments>
  sr = 48000
  ksmps = 10
  nchnls = 2

  instr   1
      aneworc oscil p4, p5, 1  
      out aneworc
  endin
</CsInstruments>

<CsScore>
  f1 0 4096 10 1 1 1 1

  i1 0 2 9000  440   ;plays a note starting at 0sec, with
                     ;a duration of 2sec, amp level of 9000
                     ;and a fund.freq 110Hz
  i1 3 2 12000 550   ;starts at 3sec, for 2sec, amp lvl. 12000
                     ;and fund.freq 550Hz...
  i1 6 2 6000  360
  i1 9 2 15000 360
</CsScore>

</CsoundSynthesizer> 

Mit mehreren Instrumenten spielen

Natürlich ist ein Orchester nicht auf ein Instrument beschränkt, was wäre das denn auch für ein Orchester? Ich kann einfach mal ein weiteres Instrument hinzufügen. Das erste Instrument spielt eine Sinuswelle und das zweite eine Rechteckwelle:

<CsoundSynthesizer>

<CsOptions>
-odac               ;realtime audio
</CsOptions>


<CsInstruments>
  sr = 48000
  ksmps = 10
  nchnls = 1

  instr 1
      aone oscil p4, p5, 1  
      out aone
  endin

  instr 2
      atwo oscil p4, p5, 2
      out atwo
  endin
</CsInstruments>

<CsScore>
  f1 0 4096 10 1                     ;instrument1 sinus
  f2 0 4096 10 1 0.33 0 2 0.14 0.11  ;instrument2 square

  i1 0  3 10000 322   ;instr1, lasts 3sec, freq 320Hz
  i2 4  3 10000 322   ;instr2, lasts 3sec, freq 320Hz
  i1 8  3 8000  800   ;instr1, lasts 3sec, freq 800Hz
  i2 12 3 8000  800   ;instr2, lasts 3sec, freq 800Hz
</CsScore>

</CsoundSynthesizer> 

Glissandos

Bisher hatten alle von mir programmierten Noten eine durchgängige Frequenz. Es ist aber möglich, Klänge zu erzeugen, dessen Tonhöhe geschmeidig von einem Ton zum nächsten gleitet. Dies erzielt man mithilfe einer sogenannten Rampe, die linear von eine Anfangsfrequenz zu einer bestimmten Endfrequenz führt. Diese Rampe kann dann als zweites Argument (Frequenz) des Oszillators dienen.

<CsoundSynthesizer>

<CsOptions>
-odac      ;realtime audio
</CsOptions>


<CsInstruments>
  sr = 48000
  ksmps = 10
  nchnls = 1

  instr 1
      kglis line 320, 1, 440    ;linear ramp from 320Hz zo 440Hz
      aone oscil p4, kglis, 1   ;freq glissando
      out aone
  endin
</CsInstruments>

<CsScore>
  f1 0 4096 10 1               ;instrument1 sinus

  i1 0 3 10000                ;instr1, lasts 3sec, amp 10000
</CsScore>

</CsoundSynthesizer> 

kglis ist eine sogenannte Kontrollvariable (control variable). Im letzten Artikel haben wir schon Audiovariablen (beginnend mit einem a) kennengelernt. Kontrollvariablen müssen im Namen immer mit einem k beginnen! Kontrollvariablen werden mit einer Auflösung der kr Varibalen (angegeben im Header des Orchesters) wiederholt (in unserem Beispiel ist kr = 4800, weil wir das Verhältnis von sr/kr angegeben haben -> ksmps=10).

Im oberen Beispiel generiert line eine Serie von Werten, die linear von 320 nach 440 ansteigen. Das Resultat wird in kglis gespeichert (diese Kontrollvariable hätten wir auch anders nennen können, sie muss halt nur mit einem k beginnen).

Die Rampe von 320Hz zu 440Hz benötigt genau p3 Sekunden. Das entnimmt man dem zweiten Argument von line. Wir erinnern uns: Das 3. p-Field (p3) in jedem Csound i-Statement gibt die Dauer der Note an. Wenn ich diese Dauer bspw. auf 0.5 Sekunden ändere, dann dauert auch das Glissando nur eine halbe Sekunde. Es ist natürlich auch möglich Glissandos zu erstellen, die weitaus komplexer sind und unabhängig von der Dauer der Note, aber dazu an anderer Stelle mehr…

Der line Opcode generiert eine gerade Linie und benötigt dazu folgende Argumente:

initial value, time, final value

Wenn ich z.B. den Anfangswert (initial value) mit der Variablen ia und den Endwert (final value) mit der Variablen ib beschreibe, dann sehen die Variablen für line so aus: ia, idur, ib

Diese Art von Variablen beginnen mit einem i. Es handelt sich hierbei weder um Audiovariablen (a), noch um Kontrollvariablen (k). Dies sind sogenannte Initialisierungsvariablen (init variables i). D.h. ihnen werden ihre Werte noch vor dem Beginn einer Note zugewiesen und diese ändern sich dann auch nicht mehr, bis zur nächsten Note.

Soviel zu dem Thema. Im nächsten Teil gehe ich dann etwas näher auf Kontrollvariablen ein…