AM & Ringmodulation: Example

The following example shows both AM and ring modulation:

Carrier Frequency

Modulator Frequeny

Modulator Offset

Output Gain:

Time Domain:

Frequency Domain:

Fourier Series: Sawtooth

Formula

The sawtooth is an asymmetric waveform with a sharp timbre. The related Fourier series is described by the following characteristics:

  • odd and even harmonics

  • alternating sign

  • slow decrease towards higher partials

\(X(t) = \frac{2}{\pi} \sum\limits_{k=1}^{N} (-1)^i \frac{\sin(2 \pi i f\ t)}{i}\)


Interactive Example

Pitch (Hz):

Number of Harmonics:

Output Gain:

Time Domain:

Frequency Domain:

In contrast to the triangular wave, the interactive example shows the occurrence of ripples at the steep edges of the waveform. The higher the number of partials, the denser the ripples. This is referred to as the Gibbs phenomenon.

Faust: Parallel Composition

Parallel processes in Faust are separated with the , operator. The following example uses two square wave oscillators, each passing through a lowpass filter. These chains are running in parallel, creating an output signal with two channels for the left and right audio output:

text


This example is a parallel combination of two sequential compositions. In Faust syntax, these need to be put in parenthesis.

Load this example in the Faust online IDE for a quick start:

import("stdfaust.lib");

freq  = hslider("Cutoff Frequency",100, 10, 1000, 0.001);

sig1  = os.square(50);
sig2  = os.square(70);

filt = fi.lowpass(5,freq);

process = (sig1:filt),(sig2:filt);

Online Tools and Materials

Faust Code

The Faust project features a rich set of properly documented examples. Nevertheless, this class has an accompanying Git Repository for code snippets and small tutorials.


Using OSC with the liblo

The OSC protocol is a wide spread means for communication between software components or systems, not only suited for music applications. Read more in the OSC chapter of the Computer Music Basics. There is a large variety of OSC libraries available in C/C++. The examples in this class are based on the liblo, a lightweight OSC implementation for POSIX systems.

Installing the Library

On Ubuntu systems, as the ones used in this class, the liblo library is installed with the following command:

$ sudo apt-get install liblo-dev

Including the Library

The liblo comes with additional C++11 wrappers to offer an object-oriented workflow. This feature is also used in the examples of this class. The following lines include both headers:

#include <lo/lo.h>
#include <lo/lo_cpp.h>

The GainExample

The GainExample is based on the ThroughExample, adding the capability to control the gain of the passed through signal with OSC messages.


Passing Command Line Arguments

The main function of this example accepts the OSC port to listen to as a command line argument. This is realized with a string comparison. The compiled binary is then started with an extra argument for the port:

$ ./gain_example -p 6666

The OSC Manager Class

The OSC-ready examples in these tutorials rely on a basic class for receiving OSC messages and making them accessible to other program parts. It opens a server thread, which listens to incoming messages in the background. With the add_method function, OSC paths and arguments specifications can be linked to a callback function.

// create new server
st = new lo::ServerThread ( p );

// / Add the example handler to the server !
st->add_method("/gain", "f", gain_callback, this);

st -> start ();

Inside the callback function gain_callback, the incoming value is stored to the member variable gain of the OscMan class.

statCast->gain = argv[0]->f;

The Processing Function

At the beginning of each call of the processing function, the recent incoming OSC messages are read from the OSC Manager:

// get the recent gain value from the OSC manager
double gain = oscman->get_gain();

The gain values are applied later in the processing function, when copying the input buffers to the output buffers:

out[chanCNT][sampCNT] = in[chanCNT][sampCNT] * gain;

Compiling

When compiling with g++, the liblo library needs to be linked in addition to the JACK library:

$ g++ -Wall -std=c++11 src/main.cpp src/gain_example.cpp src/oscman.cpp -ljack -llo -o gain_example

Working with the g++ Compiler

Compiling a Program

Examples and projects in this modules can be compiled with g++ from the GNU Compiler Collection. With the proper libraries installed, g++ can be called directly for small to medium sized projects. The first example, just passing through the audio, is compiled with the following command:

g++ -Wall src/gain_example.cpp src/oscman.cpp -ljack -o gain_example

The compiler gets the extra argument Wall to print all warnings. All source (cpp) files are passed to the compiler, followed by all libraries which need to be linked (linker arguments). The name of the binary or executable is specified after the -o flag.


Build Scripts

Physical Modeling in Faust

The functional principle of Faust is very well suited for programming physical models for sound synthesis, since these are usually described in block diagrams. Working with physical modeling in Faust can happen on many levels of complexity, from using ready instruments to basic operations.

Ready Instruments

For a quick start, fully functional physical modeling instruments can be used from the physmodels.lib library. These *_ui_MIDI functions just need to be called in the process function:

import("all.lib");

process = nylonGuitar_ui_MIDI : _;

The same algortithms can also be used on a slightly lower level, combining them with custom control and embedding them into larger models:

import("all.lib");

process = nylonGuitarModel(3,1,button("trigger")) : _;

Ready Elements

The physmodels.lib library comes with many building blocks for physical modeling, which can be used to compose instruments. These blocks are instrument-specific, as for example:

  • (pm.)nylonString

  • (pm.)violinBridge

  • (pm.)fluteHead


Bidirectional Utilities & Basic Elements

The bidirectional utitlities and basic elements in Faust's physical modeling library offer a more direct way of assembling physical models. This includes waveguides, terminations, excitation and others:

  • (pm.)chain

  • (pm.)waveguide

  • (pm.)lTermination

  • (pm.)rTermination

  • (pm.)in


From Scratch

Taking a look at the physmodels.lib library, even the bidirectional utilities and basic elements are made of standard faust functions:

https://github.com/grame-cncm/faustlibraries/blob/master/physmodels.lib

chain(A:As) = ((ro.crossnn(1),_',_ : _,A : ro.crossnn(1),_,_ : _,chain(As) : ro.crossnn(1),_,_)) ~ _ : !,_,_,_;
chain(A) = A;

References

2018

  • Romain Michon, Julius Smith, Chris Chafe, Ge Wang, and Matthew Wright. The faust physical modeling library: a modular playground for the digital luthier. In International Faust Conference. 2018.
    [details] [BibTeX▼]

2007

Spatialization in Electroacoustic Music

In electronic and electroacoustic music, spatialization is the distribution of sound in space, using loudspeakers or headphones. Although spatial aspects have also been considered in acoustic music through the spatial arrangement of musicians and instruments, electronic means allow a more dynamic use of space as a composition parameter. This can happen during studio productions or in live performance. These possibilities have been explored since the early days of electroacoustic music and have evolved with the technology over the decades.


Pupitre D'Espace

Pierre Schaeffer developed the Pupitre D'Espace, a device for spatializing tape music in real time, in 1951. This special case of spatialization for acousmatic music is also referred do as diffusion. The device works with three induction coils for detecting the position of the hand-held transponder in space.

/images/nsmi/pupitre-despace.jpg

Image from Nicolau Centola's PhD thesis.


Poème électronique

/images/nsmi/philips-pavilion.jpg

The Philips Pavilion (from medienkunstnetz )


The Philips Pavilion, built for the 1958 World's Fair in Brussels, featured a multi-channel sound system with an unconventional loudspeaker arrangement. It was used for Edgard Varèse's Poème électronique to move sound along paths defined by the loudspeaker positions.

/images/nsmi/poeme-electronique.jpg

Source movements in 'Poème électronique'


Rotationstisch

Starting in 1959, Stockhausen used a rotating table (Rotationstisch) for creating sound movements in quadraphonic tape compositions. A loudspeaker in the center is rotated with the table, captured by four fixed microphones surrounding it. The directivity but also the inherent Doppler effect creates the image of a rotating sound source, when played back on a quadraphonic setup.

/images/nsmi/rotationstisch.jpg

Loudspeaker Orchestras

A loudspeaker orchestra uses loudspeakers themselves as musical instruments, rather than as means for reproducing sound. A typical setup uses models with very different, distinct characteristics, placed at individual positions, rather than in a geometric shape. During a performance, pre-composed music, often stereo, can be sent to the different speakers or speaker groups. This process, referred to as diffusion, is a standard technique in Acousmatic Music.


The Acousmonium

The Acousmonium, launched by French GRM (Groupe de Recherches Musicales) in 1974, is the original and most prominent loudspeaker orchestra.

/images/nsmi/acousmonium.jpg

Francois Bayle with the Acousmonium from "Our Research for Lost Route to Root" (Jérôme Barthélemy, 2008)


BEAST

The BEAST (Birmingham ElectroAcoustic Sound Theatre) is a younger system, following the principles of the Acousmonium. It was brought to Berlin for the 2010 edition of the festival Inventionen, when Jonty Harrison was guest professor at TU Berlin.

/images/nsmi/BEAST_vornPult-14.jpg

The BEAST at Elisabeth-Kirche, Berlin


HaLaPhon

Principle

The HaLaPhon, developed by Hans Peter Haller at SWR in the 70s and 80s, is a device for spatialized performances of mixed music, and live electronics. The first version was a fully analog design, whereas the following ones used analog signal processing with digital control.

The HaLaPhon principle is based on digitally controlled amplifiers (DCA), which are placed between a source signal and loudspeakers. It is thus a channel-based-panning paradigm. Source signals can be tape or microphones:

/images/nsmi/halaphon/halaphon_GATE.png

DCA (called 'Gate') in the HaLaPhon.


Each DCA can be used with an individual characteristic curve for different applications:

/images/nsmi/halaphon/halaphon_kennlinien.png

DCA: Different characteristic curves.


Quadraphonic Rotation

A simple example shows how the DCAs can be used to realize a rotation in a quadraphonic setup:

/images/nsmi/halaphon/halaphon_circle.png

Circular movement with four speakers.


/images/nsmi/halaphon/halaphon_4kanal.png

Quadraphonic setup with four DCAs.


Envelopes

The digital process control of the HaLaPhon generates control signals, referred to as envelopes by Haller. Envelopes are generated through LFOs with the following waveforms:

/images/nsmi/halaphon/halaphon_huellkurven1.png

Circular movement with four speakers.


Envelopes for each loudspeaker gain are synchronized in the control unit, resulting in movement patterns. These can be stored on the device and triggered by the sound director or by signal analysis:

/images/nsmi/halaphon/halaphon_programm1.png

Quadraphonic setup with four DCAs.



References

2017

  • Andreas Pysiewicz and Stefan Weinzierl. Instruments for spatial sound control in real time music performances. a review. In Musical Instruments in the 21st Century, pages 273–296. Springer, 2017.
    [details] [BibTeX▼]

2016

2015

  • Martha Brech and Henrik von Coler. Aspects of space in Luigi Nono's Prometeo and the use of the Halaphon. In Martha Brech and Ralph Paland, editors, Compositions for Audible Space, Music and Sound Culture, pages 193–204. transctript, 2015.
    [details] [BibTeX▼]

2014

  • Martha Brech and Henrik von Coler. The Halaphon and its use in Luigi Nono's 'Prometeo' in Venice. In Proceedings of the 9th Conference on Interdisciplinary Musicology (CIM). 2014.
    [details] [BibTeX▼]

1995

  • Hans Peter Haller. Das Experimentalstudio der Heinrich-Strobel-Stiftung des Südwestfunks Freiburg 1971-1989: die Erforschung der elektronischen Klangumformung und ihre Geschichte, Teil 1. Nomos, Baden-Baden, 1995.
    [details] [BibTeX▼]
  • Hans Peter Haller. Das Experimentalstudio der Heinrich-Strobel-Stiftung des Südwestfunks Freiburg 1971-1989: die Erforschung der elektronischen Klangumformung und ihre Geschichte, Teil 2. Nomos, Baden-Baden, 1995.
    [details] [BibTeX▼]

Playing Samples in SuperCollider

The Buffer class manages samples in SuperCollider. There are many ways to use samples, based on these buffers. The following example loads a WAV file (find it in the download) and creates a looping node. When running, the playback speed can be changed:

s.boot;

// get and enter the absolute path to a sample
~sample_path = "/some/directory/sala_formanten.wav";

~buffer  = Buffer.read(s,~sample_path);

(
~sampler = {

      |rate= 0.1|

      var out = LoopBuf.ar(1,~buffer.bufnum, BufRateScale.kr(~buffer.bufnum) * rate, 1, 0,0,~buffer.numFrames);

      Out.ar(0, out);

}.play;

)

// set the play rate manually
~sampler.set(\rate,-0.1);

Exercise

Exercise

Combine the sample looper example with the control bus and mouse input example to create a synth for scratching sound files.

Create Classes in SuperCollider

At its core, SuperCollider works in a strictly object oriented way. Although SynthDefs already allow to work with multiple instances of a definition, actual classes can help in many ways. This includes the typical OOP paradigms, such as member variables and methods for quick access to properties and actions.

While SynthDefs can be sent to a server during run time, classes are compiled when booting the interpreter or recompiling the class library. Some possible errors in class definitions are detected and reported by the compiler.

This is just a brief overview, introducing the basic principles. Read the SC documentation on writing classes for a detailed explanation.


Where to put SC Classes

SuperCollider classes are defined in .sc files with a specific structure. For compiling a class when booting the interpreter, it needs to be located in a directory which is scanned by SC. For this reason, an installation of SC creates a directory for user-defined content. Inside sclang, this directory can be shown with the following command:

Platform.userExtensionDir

On Linux systems, this is usually:

/home/someusername/.local/share/SuperCollider/Extensions

For more information, read the SC documentation on extensions.


Structure of SC Classes

The following explanations are based on the example in the repository. A class is defined inside brackets, with the class name:

SimpleSynth
{
  ...
}

Member Variables

Member variables are declared in the standard way for local variables. They can be accessed anywhere inside the class.

var dur;

Constructor and Init

The constructor calls the init() function in the following way for initializing values and other tasks on object creations:

// constructor
*new { | p |
        ^super.new.init(p)
}

// initialize method
init { | p |
        dur    = 1;
}

Member Functions

Member functions are defined as follows, using either the |...| or the arg ...; syntax for defining their arguments:

play
      { | f |
    ...
  }

Creating Help Files

In SC, help files are integrated into the SCIde for quick access. Help files for classes are also created during compilation. They need to be placed in a directory relative to the .sc file with the extension .schelp:

HelpSource/Classes/SimpleSynth.schelp

Read the SC documentation on help files for more information.