Update site.

This commit is contained in:
2016-09-02 11:47:33 +02:00
parent 86b86ccdc0
commit 327ac4250c
32 changed files with 821 additions and 943 deletions

View File

@@ -1,31 +1,31 @@
#+title: Sound Programming
#+summary: Programming sound in Live-Sequencer and ChucK
#+license: wtfpl, unless otherwise noted
#+startup: showall
#&toc
---
abstract: Programming sound in Live-Sequencer and ChucK
---
* Sound Programming
Sound Programming
=================
Much can be programmed, and that includes sound. In the digital world, sound is
typically represented by sequences of about 90 kB per second, so "printing"
sound is merely a matter of printing bytes. As such, any general purpose
language can be used to generate sounds.
Much can be programmed, and that includes sound. In the digital world,
sound is typically represented by sequences of about 90 kB per second,
so "printing" sound is merely a matter of printing bytes. As such, any
general purpose language can be used to generate sounds.
However, it's boring to create a program that does nothing but print bytes, and
it's potentially difficult to make those bytes sound nice; we want abstractions
to simplify matters for us: instruments, drums, musical notes, and a high-level
program structure. Many programming languages have good libraries that allow us
to achieve just that, but to keep it simple we'll focus on how to program sound
in two languages designed to output sound: ChucK and Live-Sequencer.
However, it's boring to create a program that does nothing but print
bytes, and it's potentially difficult to make those bytes sound nice; we
want abstractions to simplify matters for us: instruments, drums,
musical notes, and a high-level program structure. Many programming
languages have good libraries that allow us to achieve just that, but to
keep it simple we'll focus on how to program sound in two languages
designed to output sound: ChucK and Live-Sequencer.
Let's create some sounds.
* The square wave
The square wave
===============
We'll start with ChucK and a small square wave program:
#+BEGIN_SRC c
``` {.c}
// Connect a square oscillator to the sound card.
SqrOsc s => dac;
@@ -39,16 +39,17 @@ SqrOsc s => dac;
while (true) {
1000::second => now;
}
#+END_SRC
```
ChucK is an imperative language. Instructions on how to install and run it can
be found on its [[http://chuck.cs.princeton.edu/][website]], along with other useful information. You can listen to
the above sound [[square.flac][here]].
ChucK is an imperative language. Instructions on how to install and run
it can be found on its [website](http://chuck.cs.princeton.edu/), along
with other useful information. You can listen to the above sound
[here](square.flac).
To do the same in Live-Sequencer, we must find a square wave "instrument" and use
that.
To do the same in Live-Sequencer, we must find a square wave
"instrument" and use that.
#+BEGIN_SRC haskell
``` {.haskell}
module SquareWave where
-- Basic imports.
@@ -65,22 +66,24 @@ main = concat [ program lead1Square -- Use a square wave instrument.
note 1000000 (a 4) -- Play 1000000 milliseconds of the musical note A4
) -- about 440 Hz.
]; -- End with a semicolon.
#+END_SRC
```
Live-Sequencer differs from ChucK in that it is functional, but another major
difference is that while ChucK (in general) generates raw sound bytes,
Live-Sequencer generates so-called MIDI codes, which another program converts to
the actual audio. Live-Sequencer has a couple of funky features such as
highlighting which part of one's program is played; read about it and how to
install and run it at [[http://www.haskell.org/haskellwiki/Live-Sequencer][this wiki]]. You can listen to the above sound [[squarewave.flac][here]].
Live-Sequencer differs from ChucK in that it is functional, but another
major difference is that while ChucK (in general) generates raw sound
bytes, Live-Sequencer generates so-called MIDI codes, which another
program converts to the actual audio. Live-Sequencer has a couple of
funky features such as highlighting which part of one's program is
played; read about it and how to install and run it at [this
wiki](http://www.haskell.org/haskellwiki/Live-Sequencer). You can listen
to the above sound [here](squarewave.flac).
Something more advanced
=======================
* Something more advanced
Let's try to create a small piece of music which can be expressed easily
in Live-Sequencer (listen [here](melodyexample.flac)):
Let's try to create a small piece of music which can be expressed easily in
Live-Sequencer (listen [[melodyexample.flac][here]]):
#+BEGIN_SRC haskell
``` {.haskell}
module MelodyExample where
import Prelude
@@ -137,19 +140,20 @@ mel2 x y n = concat [ twice (note qn (x 3))
, concatMap (note hn . y) [3, 4, 4]
, note wn (x n) =:= note wn (y n)
];
#+END_SRC
```
When you play the program from the Live-Sequencer GUI, the code in use is
highlighted:
When you play the program from the Live-Sequencer GUI, the code in use
is highlighted:
#&img;url=sound-highlight.png, width=640, center, caption=Highlighting of sound, screenshot
![Highlighting of sound](sound-highlight.png){width=700}
The same could be expressed in ChucK, but the comparison wouldn't be fair. While
Live-Sequencer is designed for describing melodies, ChucK's purpose is sound
synthesis, which is more general. We'll create something more fitting of ChucK's
capabilities, while still focusing on the use of instruments (listen [[more_advanced.flac][here]]):
The same could be expressed in ChucK, but the comparison wouldn't be
fair. While Live-Sequencer is designed for describing melodies, ChucK's
purpose is sound synthesis, which is more general. We'll create
something more fitting of ChucK's capabilities, while still focusing on
the use of instruments (listen [here](more_advanced.flac)):
#+BEGIN_SRC c
``` {.c}
// Background music for an old sci-fi horror B movie.
// Filters.
@@ -209,32 +213,33 @@ while (true) {
a_melody(mandolin, Math.random2(0, 350));
a_melody(sitar, Math.random2(200, 360));
}
#+END_SRC
```
* Algorithmic composition
Algorithmic composition
=======================
Why not have the computer generate the melody as well as the sound? That
*sounds* like a great idea!
**sounds** like a great idea!
Enter [[https: / / en.wikipedia.org / wiki / L-system][L-systems]]. An L-system has an alphabet and a set of rules, where each rule
is used to transform the symbol on the left-hand side to the sequence of symbols
on the right-hand side. We'll use this L-system to generate music:
Enter [L-systems](https: / / en.wikipedia.org / wiki / L-system). An
L-system has an alphabet and a set of rules, where each rule is used to
transform the symbol on the left-hand side to the sequence of symbols on
the right-hand side. We'll use this L-system to generate music:
#+BEGIN_SRC c
``` {.c}
-- Based on https://en.wikipedia.org/wiki/L-system#Example_7:_Fractal_plant
Alphabet: X, F, A, B, P, M
Rules:
X -> FMAAXBPXBPFAPFXBMX
F -> FF
#+END_SRC
```
If we evaluate a L-system on a list, the system's rules are applied to each
element in the list, and results are concatenated to make a new list. If we
assign each symbol to a sequence of sounds and run the L-system a few times, we
get [[lsystem.flac][this]].
If we evaluate a L-system on a list, the system's rules are applied to
each element in the list, and results are concatenated to make a new
list. If we assign each symbol to a sequence of sounds and run the
L-system a few times, we get [this](lsystem.flac).
#+BEGIN_SRC haskell
``` {.haskell}
module LSystem where
import Prelude
@@ -277,17 +282,19 @@ getLSystemSound expand interpret iterations start
-- Use the third iteration of the L-System, and start with just X.
main = channelInsts ++ getLSystemSound expand interpret 3 [X];
#+END_SRC
```
Using an L-system is one of many ways to take composition to a high
level. L-systems can be used to generate fractals, which are nice.
* And so on
And so on
=========
Many abstractions in sound generation allow for fun sounds to happen. Interested
people might want to also take a look at e.g. [[http://haskell.cs.yale.edu/euterpea-2/][Euterpea]], [[http://puredata.info/][Pure Data]], or [[http://csounds.com/][Csound]].
Many abstractions in sound generation allow for fun sounds to happen.
Interested people might want to also take a look at e.g.
[Euterpea](http://haskell.cs.yale.edu/euterpea-2/), [Pure
Data](http://puredata.info/), or [Csound](http://csounds.com/).
#&line
Originally published [[http://dikutal.dk/artikler/sound-programming][here]].
Originally published
[here](http://dikutal.metanohi.name/artikler/sound-programming).