What is the programming of a song

Program your song

Getting started with Sonic Pi music software

Sonic Pi is free software with which you can playfully create sound effects, beats, melodies and entire songs from program code. It's fun and offers an ideal introduction to the world of programming for children and adults.

There are many ways to make music: you can play the guitar or synthesizer, or you can produce music with digital recording studios. Sonic Pi takes a different approach: the program generates sounds from codes that can be put together to form complete songs. It's easier than it sounds.

Sonic Pi was originally developed by its inventor Sam Aaron to teach programming to children. But it is anything but a toy: The intelligent, expandable structure makes the program interesting even for professionals.

This article is about the basics of Sonic Pi. All code examples can run independently and show the possibilities of the software. Sonic Pi indicates incorrect code and typing errors with error messages. In one of the next c’t issues, a second article will show how to write a beat with Sonic Pi.

Samples and Synths

Sonic Pi offers two ways to create sounds: with samples or with synths. The first type is to play pre-produced sounds. Sonic Pi brings 129 such sounds from drums to piano sounds - the selection can be expanded with sounds from other sources. Type the following command in the buffer area to start a sample:

sample: bd_haus

Press the Run button and the program will play a crisp techno bass drum. Even if only one note sounds, it is already a first, complete Sonic Pi program. Sonic Pi spits out the list of all built-in samples by typing sample and a space or by looking in the Help window under "Samples". The preinstalled sound snippets are divided into a total of eleven groups. The abbreviations before the first underscore denote the groups: ambi stands for two-dimensional sounds, bd for bass drums, drum for other drum sounds, elec for electronic sounds and loop for rhythmic fragments. Play different samples to explore the variety of sounds. Examples of interesting candidates are: guit_e_fifths,: bass_voxy_c,: loop_amen,: ambi_lunar_land. You can use the sample function to include sounds you have recorded yourself - you can find more information on this in the tutorial under 3.6.

About the box: The c’t tip for children and parents

Sonic Pi programs mostly consist of function calls. sample is one such function. It expects the name of the sound to be played as additional information. Such additional information is called arguments.

The second type of sound generation uses synthetic sounds. Synths compute sounds in real time instead of playing them from memory. With play you play a synth:

play 64

The number 64 stands for the pitch. Imagine a piano keyboard with 128 keys: The leftmost key for the lowest note has the number 0, the rightmost key with the highest note has the number 127. As an alternative to these numbers, the pitch can also be designated with the note name.

play: e4

In this case the “e” stands for the note of the same name and the “4” for the fourth octave. Sonic Pi offers many synths that can be selected with use_synth. This option is active until a new synth is selected.

use_synth: piano

play 30

Try different pitches (numbers between 0–127) and different synths, such as: chiplead (sounds like an 8-bit computer from the 80s) and: tb303 (a simulation of the legendary Roland TB-303).

Compose sequences of sounds

A swallow doesn't make a summer, and a single note isn't a song. How do you create sequences of sounds, i.e. melodies and rhythms? Simply stringing together sample and play commands is not enough, as these sounds are played back at the same time. The sleep command makes the computer wait for the next line of code to execute. How to get Sonic Pi to play the sounds one after the other:

sample: bd_haus

sleep 1

sample: drum_snare_hard

The number after sleep stands for the duration of the pause in beats; in this case 1 stands for one second. This is because the default speed of the Sonic Pi is 60 bpm (bpm = beats per minute). If you double the tempo with the command use_bpm 120 to 120 beats per minute, a beat lasts half a second, then sleep 1 provides an interruption of half a second:

use_bpm 120

sample: bd_haus

sleep 1

sample: drum_snare_hard

With sample, play and sleep you can already write whole pieces. Good practice is to choose a simple melody and recreate it.

Sound tinkerer

Sonic Pi offers many options for changing sounds. Basic options that apply to synths and samples include amp and pan. The abbreviation amp stands for amplification. The minimum value is 0, i.e. silence, there is no upper limit. Too high a volume, however, leads to distortion. The default value is 1.

sample: ambi_piano, amp: 0.5

sleep 2

sample: ambi_piano, amp: 1.5

The abbreviation pan stands for panorama. This option shifts the sound in the stereo image. pan: -1 positions the sound on the far left, pan: 0 in the middle, pan: 1 on the far right. In the following example, a drumbeat travels from left to right:

sample: drum_tom_lo_hard, pan: -1

sleep 2

sample: drum_tom_lo_hard, pan: -0.5

sleep 2

sample: drum_tom_lo_hard, pan: 0.5

sleep 2

sample: drum_tom_lo_hard, pan: 1

Changing the playback speed of samples often leads to surprising sound effects. You can do this with the rate option. The following example plays the sample first at normal speed, then again at half speed:

sample: guit_em9

sleep 4

sample: guit_em9, rate: 0.5

We know the phenomenon from the turntable: The change in playback speed also changes the pitch. The following applies: Doubling the playback speed (rate: 2) shifts the pitch up one octave; that leads to the Mickey Mouse effect; halving (rate: 0.5) does the opposite and pushes the sound down an octave. A negative sign reverses the playback direction, the sample is played backwards. This is how a sample is played backwards at half speed:

sample: guit_em9, rate: -0.5

Experiment with different samples and speeds. Such manipulations sound particularly interesting with longer samples that begin with guit, ambi or loop.

Options that influence the volume progression offer further leeway. The most important terms here are attack and release: the former determines the length of time it takes a sound to reach its full volume. The term release is used to describe the decay time. This behavior is essential for the characteristics of all sounds. A xylophone, played with a felt mallet, sounds "soft", so it has a longer attack. When using a wooden mallet, the xylophone sounds harder, more percussive (shorter attack). On the piano, pressing the right pedal raises the damper, which leads to a longer decay time, i.e. a longer release.

An example of a short, percussive sound in Sonic Pi:

play 64, release: 0.1

A sound that slowly swells and slowly fades away:

play 64, attack: 4, release: 4

The full range of sound possibilities of synths can only be fully exploited with the options. The synth blade (named after the classic film Blade Runner), for example, is well suited for creating electronic string sounds with long decay and decay phases:

use_synth: blade

play 50, attack: 2, release: 4

A lot can be done with attack and release. There are other options that change the volume progression, such as sustain and decay. You can find more information on this in the built-in tutorial under point 2.4.

Many options apply to synths as well as samples (such as amp and pan). The rate option is only useful for samples. There are also options that only apply to certain synths. The cutoff option only works with synths that have a low-pass filter. These include tb303 and blade. cutoff controls the frequency of the filter, a high value ensures a bright sound, a low value sounds deep and dark. Values ​​between 0 and 130 are allowed:

use_synth: tb303

play 30, cutoff: 50

sleep 1

play 30, cutoff: 80

sleep 1

play 30, cutoff: 110

Play it again, Sam

Programmers like to be comfortable. If a piece of code is to be executed eight times, then it is awkward to write the code down eight times. Sonic Pi offers the ability to repeat pieces of code:

8.times do

sample: bd_haus

sleep 0.25

sample: drum_snare_hard

sleep 0.25

end

Code that stands between a do and an end is called a block. 8.times ensures that this is executed eight times.

Repeating it using blocks makes the code clearer and changes only need to be made in one place.

Random music

Ideally, computers work in a strictly logical manner and do not know any coincidence. But you can simulate this. You can take advantage of this when composing.

The rand_i function generates random numbers. “Rand” stands for “random”, “i” stands for “integer” (whole number). rand_i 30..90 generates whole random numbers between 30 and 90.

The following example plays eight notes with a random pitch between 30 and 90. play takes a number as an argument. Whenever a number is expected in the code, you can also use an expression that produces a number. In this case the rand_i function returns such a number.

use_synth: piano

8.times do

play rand_i 30..90

sleep 0.25

end

If you start this code repeatedly, the exact same notes will be heard every time. There is a good reason for this: when you send code to other Sonic Pi users, they can be sure that the result will sound exactly the same everywhere, despite the random values.

With the function use_random_seed the random generator can be set to a different starting point and will generate different random numbers:

use_random_seed 672

use_synth: piano

8.times do

play rand_i 30..90

sleep 0.25

end

Choose any two numbers and put them alternately after use_random_seed. You will hear that the same values ​​for the seed produce the same number sequences. If you need floating point numbers instead of whole numbers, choose the rand function. In the following example sleep is fed with a random number between 0.1 and 0.5:

use_synth: piano

8.times do

play rand_i 30..90

sleep rand 0.1..0.5

end

Two other random functions are useful: choose selects a random value from several given values. In the following example, one of three predefined samples is played with each pass and a pause of a quarter, half or a full beat is built in:

64 times do

sample [: bd_haus,: sn_dub,:

.: elec_blup] .choose

sleep [0.125, 0.25, 0.5] .choose

end

You use the one_in (one of) function when an action is to take place with a certain probability. It is used in combination with if (if, if). In the following example, the sample is played every fifth time on average:

128 times do

if one_in 5

sample: drum_cymbal_closed

end

sleep 0.1

end

Alienation of the sound with fx

The function use_fx (fx is the English abbreviation for effect) offers another possibility to change sounds. Frequently used effects include: echo,: reverb (reverb),: distortion (distortion). For comparison, a hit on a snare drum sounds like this without any effect:

sample: drum_snare_soft

Snare strike with echo:

with_fx: echo do

sample: drum_snare_soft

end

The effects can also be edited with options. With echo you can change the duration of the delay in beats with: phase:

with_fx: echo, phase: 0.5 do

sample: drum_snare_soft

end

sleep 2

with_fx: echo, phase: 0.05 do

sample: drum_snare_soft

end

Effects can also be nested within one another. The next example first provides a snare hit with the reverb of a large room and then manipulates the sound with a flanger. This is a popular psychedelic sound effect:

with_fx: flanger do

with_fx: reverb, room: 0.99 do

sample: drum_snare_soft

end

end

The help area lists all available effects and their options in English under “FX”.

Live loops

With Sonic Pi, you can't just make beats and melodies at home. With a lot of practice, the software can be played live on stage. Sam Aaron, developer of Sonic Pi, uses this form of live coding to make people dance at festivals.

The linchpin of the live coding is the live_loop function, which also works with blocks. In the example a live loop with the name mein_beat is created. You have to choose the name of the live loop. The code in the block is repeated until the program exits:

live_loop: mein_beat do

sample: bd_haus

sleep 0.5

sample: drum_snare_hard

sleep 0.5

end

The specialty of the Live Loop is that it is possible to change the code while it is running. This feature is a prerequisite for making music live with Sonic Pi, as you don't have to interrupt the music to change the code.

Give it a try: start the live loop example. Change the code and press the Run button again. Turn individual lines of code on and off by prefixing them with a #. Experiment with multiple live loops running in parallel. Note that different live loops must have different names.

ring, tick and look

Sonic Pi can remember sequences of values. This is very useful because melodies are nothing more than sequences of pitches, tone lengths and pauses. They are stored in so-called rings. The name "ring" comes from the fact that when the end of an episode has been reached, the episode starts over.

The following example first creates a ring with the values ​​60, 55, 65 and saves it under the name notes. With notes [0] you get the first value of the ring, i.e. 60. notes [1] gives 55, and notes [2] is 65. With notes [3] you get back to the first value, i.e. 60.

notes = ring 60, 55, 65

play notes [0] # 60

sleep 1

play notes [1] # 55

sleep 1

play notes [2] # 65

sleep 1

play notes [3] # 60

sleep 1

play notes [4] # 55

sleep 1

play notes [5] # 65

# and so on ...

The rings only develop their full benefit when you use another aid. The tick function works like a counter. When the program starts, calling tick will return the value 0. Every additional time tick is in the code, the value is increased by 1. So the first time tick returns the value 0, the second time the value 1 and so on.

In the following example tick is used to query the values ​​in the ring one after the other in a live loop and to transfer them to play:

notes = ring 40, 45, 50, 55, 60

use_synth: piano

live_loop: ring_und_tick do

play notes [tick]

sleep 1

end

You can also use several rings at the same time. The following example uses a second ring for the rests between notes. Since the value of tick has already been increased by notes [tick], pauses [look] are used for the pauses. look returns the value of the tick variable without increasing it:

notes = ring 40, 45, 50, 55, 60

pause = ring 0.25, 0.25, 0.5

use_synth: piano

live_loop: ring_und_tick do

play notes [tick]

sleep breaks [look]

end

Experiment with the last example by changing the values ​​in the two rings or adding values. You can expand the Live Loop by adding another instrument or effect, the properties of which are controlled by additional rings. You can achieve exciting results by experimenting with many rings of different lengths.

Write your own functions

So far, you've been using features that Sonic Pi brings with it. You can also build your own functions with define. A function needs a name, this is elektro_specht in the following example. Here is a block that contains the code to be executed when the function is used:

define: elektro_specht do

8.times do

sample: elec_mid_snare

sleep 0.05

end

end

Once the function is defined, it can be used just like any other: by typing in its name. Many built-in functions you've used so far take arguments - like sleep, the length of the break in beats, or sample the name of a sound.Functions you have written yourself can also have arguments. Assuming you want to determine the number of strokes of the electric woodpecker with an argument, then come up with a meaningful variable name (here: anzahl_schlaege) and write it between two vertical lines (pipe characters) at the beginning of the block. In order for this variable name to take effect, it must still be inserted in the appropriate place in the block:

define: elektro_specht:

.do | number_beats |

anzahl_schlaege.times do

sample: elec_mid_snare

sleep 0.05

end

end

The use of the function looks like this:

electro_specht 16

sleep 1

electro_specht 8

If you want to use several arguments, write them one after the other, separated by commas:

define: elektro_specht do:

. | number_beats, pauses_duration |

anzahl_schlaege.times do

sample: elec_mid_snare

sleep pause_duration

end

end

Elektro_specht 10, 0.1

sleep 1

Elektro_specht 32, 0.01

If you have enjoyed composing music using code, there is now a lot to experiment and discover. The second part of this mini-series, which will appear in one of the upcoming issues, gives a deeper insight into the possibilities of Sonic Pi. ([email protected])

Download Sonic Pi, machine-oriented Creative Coding: ct.de/yvrq

The c’t tip for children and parents

Get started with Sonic Pi

K Sonic Pi, PC with Windows, macOS or Linux as well as headphones or speakers

I am confident in using the keyboard and mouse, knowledge of English is an advantage

Z Simple rhythms and melodies are created within a few minutes, you should plan significantly more time for entire songs.

J Children from around ten years of age start with parents or older siblings. Young people from around 14 years of age start on their own.

N none