tag:blogger.com,1999:blog-56482271771048983742024-03-05T22:09:57.755-08:00A touch of music<p>A hobbyist's music page. I do welcome comments :) </p><p><i>Any correspondence of this blog's name to names of individuals, organizations, companies, products or other blogs is pure coincidence. Except where explicitly noted, all material posted on this site is available under a <a href="http://creativecommons.org/licenses/by-sa/3.0/us/">creative commons attribution sharealike license</a>. If you believe I've infringed on your copyright please notify me.</i></p>shiihshttp://www.blogger.com/profile/01738225085577318818noreply@blogger.comBlogger15125tag:blogger.com,1999:blog-5648227177104898374.post-4843706998790512162016-05-28T05:08:00.000-07:002016-05-28T14:22:39.033-07:00Modeling rhythms using numbers - part 2This is a continuation of my <a href="http://a-touch-of-music.blogspot.com/2015/12/modeling-rhythms-using-numbers.html" target="_blank">previous post on modeling rhythms using numbers</a>.<br />
<h2>
Euclidean rhythms</h2>
<div>
The Euclidean Rhythm in music was discovered by <a href="https://en.wikipedia.org/wiki/Godfried_Toussaint" target="_blank">Godfried Toussaint</a> in 2004 and is described in a 2005 paper "<a href="http://cgm.cs.mcgill.ca/~godfried/publications/banff.pdf" target="_blank">The Euclidean Algorithm Generates Traditional Musical Rhythms</a>". The greatest common divisor of two numbers is used rhythmically giving the number of beats and silences, generating the majority of important World Music rhythms.</div>
<h2>
Do it yourself</h2>
<div>
You can play with a slightly generalized version of euclidean rhythms <a href="http://stefaanhimpe.pythonanywhere.com/euclidean/static/index.html" target="_blank">in your browser</a> using a <a href="https://p5js.org/" target="_blank">p5js</a> based sketch I made to test my understanding of the algorithms involved. If it doesn't work in your preferred browser, retry with <a href="https://www.google.com/chrome/" target="_blank">google chrome</a>. </div>
<h2>
The code</h2>
<div>
The code may still evolve in the future. There are some possibilities not explored yet (e.g. using ternary number systems instead of binary to drive 3 sounds per circle). You can download <a href="https://github.com/shimpe/euclidean_rhythm" target="_blank">the full code</a> for the <a href="https://p5js.org/" target="_blank">p5js</a> sketch on <a href="https://github.com/shimpe/euclidean_rhythm" target="_blank">github</a>. </div>
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAQbicv-DoUioiJqbzq-Ko4-zvncUixZxVXudU27Wu5M_tjfaGM9ofjzCugq2vG4FQcIYjmh9rpnIXPPCObqal0sRlFoAFS6esIKJDywR2U5SCAyS7sS8-_HeZMRb_gVmvwsAVDTiK9nA/s1600/screenshot.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAQbicv-DoUioiJqbzq-Ko4-zvncUixZxVXudU27Wu5M_tjfaGM9ofjzCugq2vG4FQcIYjmh9rpnIXPPCObqal0sRlFoAFS6esIKJDywR2U5SCAyS7sS8-_HeZMRb_gVmvwsAVDTiK9nA/s640/screenshot.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">screenshot of the p5js sketch running. click the image <span style="font-size: 12.8px;">to enlarge</span></td></tr>
</tbody></table>
<h2>
The theory</h2>
<div>
So what does it do and how does it work? Each wheel contains a number of smaller circles. Each small circle represents a beat. With the length slider you decide how many beats are present on a wheel. </div>
<div>
<br /></div>
<div>
Some beats are colored dark gray (these can be seen as strong beats), whereas other beats are colored white (weak beats). To strong and weak beats one can assign a different instrument. The target pattern length decides how many weak beats exist between the strong beats. Of course it's not always possible to honor this request: in a cycle with a length of 5 beats and a target pattern length of 3 beats (left wheel in the screenshot) we will have a phrase of 3 beats that conforms to the target pattern length, and a phrase consisting of the 2 remaining beats that make a "best effort" to comply to the target pattern length. </div>
<div>
<br /></div>
<div>
Technically this is accomplished by running <a href="https://en.wikipedia.org/wiki/Euclidean_algorithm" target="_blank">Euclid's algorithm.</a> This algorithm is normally used to calculate the greatest common divisor between two numbers, but here we are mostly interesting in the intermediate results of the algorithm. In Euclid's algorithm, to calculate the greatest common divisor between an integer m and a smaller integer n, the smaller number n is repeatedly subtracted from the greater
until the greater is zero or becomes smaller than the smaller, in which case it is called the remainder. This
remainder is then repeatedly subtracted from the smaller number to obtain a new remainder. This process
is continued until the remainder is zero. When that happens, the corresponding smaller number is the greatest common divisor between the original two numbers n and m.</div>
<div>
<br /></div>
<div>
Let's try it out on the situation of the left wheel in the screenshot. The greater number m is 5 (length) and the smaller number n is 3 (target pattern length). Now the recipe says to repeatedly subtract 3 from 5 until you get something smaller than 3. We can do this exactly once:</div>
<div>
<br /></div>
<div>
<span style="background-color: #20124d; color: white;">5</span> - (<span style="background-color: #660000;">1</span>).<span style="background-color: #7f6000;">3</span> = <span style="background-color: #274e13;">2</span></div>
<div>
<br /></div>
<div>
We can rewrite this as:</div>
<div>
<br /></div>
<div>
<span style="background-color: #20124d;">5</span> = (<span style="background-color: #660000;">1</span>).<span style="background-color: #7f6000;">3</span> + <span style="background-color: #274e13;">2</span></div>
<div>
<br /></div>
<div>
This we can interpret as: the cycle of <span style="background-color: #20124d;">5</span> beats is to be decomposed as <span style="background-color: #660000;">1</span> phrase with <span style="background-color: #7f6000;">3</span> beats, followed by a phrase with <span style="background-color: #274e13;">2</span> beats (the remainder). Each phrase consists of a single strong beat followed by all weak beats. In a symbolic representation easier read by musicians one might write: x..x. (In the notation of the previous part of this article one could also write 10010).</div>
<div>
<br /></div>
<div>
Euclid's algorithm doesn't stop here. Now we have to repeatedly subtract the remainder <span style="background-color: #274e13;">2</span> from the smaller number <span style="background-color: #7f6000; color: white;">3</span>:</div>
<div>
<br /></div>
<div>
3 = (1).2 + 1</div>
<div>
<br /></div>
<div>
This in turn can be read as: the phrase of 3 beats can be further decomposed as 1 phrase of 2 beats followed by a phrase consisting of 1 beat. In a symbolic representation: x.x Euclid continues:</div>
<div>
<br /></div>
<div>
2 = (2).1 + 0</div>
<div>
<br /></div>
<div>
The phrase of two beats can be represented symbolically as: xx. We've reached remainder 0 and Euclid stops: apparently the greatest common divisor between 5 and 3 is 1.</div>
<div>
<br /></div>
<div>
Now it's time to realize what we really did: </div>
<div>
<ul>
<li>We decomposed a phrase of 5 beats in a phrase of 3 beats and a phrase of 2 beats making a rhythm x..x. </li>
<li>Then we further decomposed the phrase of 3 beats into a phrase of 2 beats followed by a phrase of 1 beat. </li>
<li>We can substitute this refined 3 beat phrase in our original rhythm of 5 = 3+2 beats to get a rhythm consisting of 5 = (2 + 1) + 2 beats: x.xx. </li>
<li>I hope it's clear by now that by choosing how long to continue using Euclid's algorithm, we can decide how fine-grained we want our rhythms to become. </li>
<li>This is where the max pattern length slider comes into play. </li>
</ul>
The length slider and the target pattern slider will determine a rough division between strong and weak beats by running Euclid's algorithm just once, whereas the max pattern length slider helps you decide how long to carry on Euclid's algorithm to further refine the generated rhythm.</div>
<div>
<br /></div>
<div>
<br /></div>
shiihshttp://www.blogger.com/profile/01738225085577318818noreply@blogger.com2tag:blogger.com,1999:blog-5648227177104898374.post-2862681931185081442014-03-08T15:03:00.000-08:002014-03-21T13:46:34.664-07:00Olivier Messiaen - a closer look at his modes of limited transposition<h2>
Olivier who?</h2>
Olivier Messiaen was a French composer (December 10, 1908 – April 27, 1992), known for inventing a new musical language. He wrote a book about his ideas on rhythm, melody and harmony and is generally regarded as one of the great innovators in music. He drew inspiration mostly from his Christian beliefs and from bird songs. I personally fell in love with this musical language after hearing his work "<i>Vingt Regards sur l'Enfant-Jésus</i>".<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/ruYEGQ004gk" width="560"></iframe>
<br />
One key element of his compositions is a set of scales that he "invented" (or rather, selected from the vast space of possible scales). They consist of symmetrical note groups. While writing music he would often adhere to using only notes from one or more of his scales, leading to special music (with very rewarding harmonies).<br />
<br />
I was curious about these special scales and wondered about the mechanisms that cause the scales to "work so well" with a listener, so<br />
I set up my own private investigation and took a close look at his scales.<br />
I discovered quite a number of interesting things (which may be known already in literature, I don't want to claim I found something new, but they were certainly new to me)<br />
<br />
I've written up what I came up with so far and put it online on github. The pdf can be seen here: <a href="https://github.com/shimpe/mints/blob/master/out/document.pdf?raw=true">https://github.com/shimpe/mints/blob/master/out/document.pdf?raw=true</a> . All the code required to reconstruct the article is available here <a href="https://github.com/shimpe/mints">https://github.com/shimpe/mints</a>: <br />
<br />
Feel free to contact me with questions or remarks about this document.<br />
<br />
<br />shiihshttp://www.blogger.com/profile/01738225085577318818noreply@blogger.com2tag:blogger.com,1999:blog-5648227177104898374.post-3989238966409743792013-12-29T02:57:00.002-08:002013-12-30T18:13:49.907-08:00Virtual choir: auto harmonize your voice in real time with supercollider<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK8ABd45PIwGT1JYJPq0F6ziD6DWXixvxhmWTfc_AnLbtjylTv5EK58osbYIzRNDAUA7HiZ0fFxHaRIvlLc7hG-U89Ka8mDz-57xGAJx3XPJ9vdGB4Tl4-M58MxPXoBXzkYdMQ96gF7Lo/s1600/virtualchoir.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="114" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK8ABd45PIwGT1JYJPq0F6ziD6DWXixvxhmWTfc_AnLbtjylTv5EK58osbYIzRNDAUA7HiZ0fFxHaRIvlLc7hG-U89Ka8mDz-57xGAJx3XPJ9vdGB4Tl4-M58MxPXoBXzkYdMQ96gF7Lo/s320/virtualchoir.png" width="320" /></a></div>
<br />
<br />
This blog entry is about to describe an experiment I did with the <b><span style="font-weight: normal;"> real time audio synthesis and algorithmic composition programming language</span> </b><a href="http://supercollider.github.io/" target="_blank">supercollider</a>. <b>Before you read on, please realize that this stuff is highly addictive.</b><br />
<br />
So you've always wanted to sing in a choir, but didn't have the
opportunity or courage to join one near you? Here's an easy way to turn
your singing into a choir piece in real time using supercollider.<br />
<br />
The system is based on the following example from the supercollider documentation:<br />
<div style="font-family: "Courier New",Courier,monospace;">
<span style="font-size: x-small;"><br /></span></div>
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;">s.boot;</span></span><br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> </span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">(</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">SynthDef("pitchFollow1",{</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> var in, amp, freq, hasFreq, out;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> in = Mix.new(SoundIn.ar([0,1]));</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> amp = Amplitude.kr(in, 0.05, 0.05);</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> # freq, hasFreq = Pitch.kr(in, ampThreshold: 0.02, median: 7);</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> //freq = Lag.kr(freq.cpsmidi.round(1).midicps, 0.05);</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> out = Mix.new(VarSaw.ar(freq * [0.5,1,2], 0, LFNoise1.kr(0.3,0.1,0.1), amp));</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> 6.do({</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> out = AllpassN.ar(out, 0.040, [0.040.rand,0.040.rand], 2)</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> });</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> Out.ar(0,out)</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">}).play(s);</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">)</span></span><br />
<br />
This example does something very interesting: it reads sound from your microphone using the SoundIn command, then tracks its frequency using the Pitch command and then synthesizes a new sawtooth wave at different multiples of the detected frequency. The new sawtooth wave is then sent to the speakers, allowing you to hear the sawtooth following your voice's pitch.<br />
<br />
Upon hearing this, I immediately thought of harmonizing singing voice in real time, with the possibility to harmonize every note differently, so as to arrive at an (hopefully somewhat interesting) choir piece.<br />
<br />
So I sat out to improve the example (combine it with pitch-shifting instead of synthesizing a new sawtooth wave, and add a bit of a GUI to it, to allow reconfiguring the harmonization on the fly), and came up with the following.<br />
<br />
<i>Please note that I'm very new to the supercollider programming language, and I'm glad for any suggestions you may have w.r.t. code style! The following code can also be cloned/forked from <a href="https://github.com/shimpe/sc-virtual-choir" target="_blank">the github repository</a>.</i><br />
<br />
<span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;">s.boot;</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">(</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">var table;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">var gap = 40;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">var mapped, mapped2, diffbuf, diffbuf2;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">var miditoname;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">var nametomidi;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">var sound;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">var difference, difference2;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">var tf, tf2;</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">// define a function to convert a midi note number to a midi note name</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">miditoname = ({ arg note = 60, style = \American ;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> var offset = 0 ;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> var midi, notes;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> case { style == \French } { offset = -1}</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> { style == \German } { offset = -3} ;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> midi = (note + 0.5).asInteger;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> (notes[midi%12] ++ (midi.div(12)-1+offset))</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">});</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">// define a function to convert a midi note name to a midi note number</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">nametomidi = ({ arg name = "C4", style = \American ;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> var offset = 0 ; // French usage: +1 ; German usage: +3</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> var twelves, ones, octaveIndex, midis;</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> case { style == \French } { offset = 1}</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> { style == \German } { offset = 3} ;</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> midis = Dictionary[($c->0),($d->2),($e->4),($f->5),($g->7),($a->9),($b->11)];</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> ones = midis.at(name[0].toLower);</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> if( (name[1].isDecDigit), {</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> octaveIndex = 1;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> },{</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> octaveIndex = 2;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> if( (name[1] == $#) || (name[1].toLower == $s) || (name[1] == $+), {</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> ones = ones + 1;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> },{</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> if( (name[1] == $b) || (name[1].toLower == $f) || (name[1] == $-), {</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> ones = ones - 1;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> });</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> });</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> });</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> twelves = (name.copyRange(octaveIndex, name.size).asInteger) * 12;</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> (twelves + 12 + ones + (offset*12))</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">});</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">// define a table of reference notes [c c# d ... b]</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">table = Array.fill(12, {arg i; i + 60}); // [60,61,...,71]</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">// define a table of mapped notes (Default values)</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">mapped = [nametomidi.value("g3"),</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> nametomidi.value("a3"),</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> nametomidi.value("b3"),</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> nametomidi.value("bb3"),</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> nametomidi.value("c4"),</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> nametomidi.value("c4"),</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> nametomidi.value("a3"),</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> nametomidi.value("d4"),</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> nametomidi.value("e4"),</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> nametomidi.value("f4"),</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> nametomidi.value("f4"),</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> nametomidi.value("g4"),</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">];</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">mapped2 = [nametomidi.value("e3"),</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> nametomidi.value("g3"),</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> nametomidi.value("g3"),</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> nametomidi.value("g#3"),</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> nametomidi.value("a3"),</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> nametomidi.value("a4"),</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> nametomidi.value("d4"),</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> nametomidi.value("b4"),</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> nametomidi.value("c4"),</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> nametomidi.value("d4"),</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> nametomidi.value("d4"),</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> nametomidi.value("d4"),</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">];</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">// define a table to store the difference between reference and mapped note</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">difference = Array.fill(table.size, {0});</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">// define a buffer on the server for consultation from the SynthDef</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">diffbuf= Buffer.loadCollection(s,table,action:{|msg| msg.postln;});</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">difference2= Array.fill(table.size, {0});</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">diffbuf2=Buffer.loadCollection(s,table,action:{|msg| msg.postln;});</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">tf = List.new(table.size);</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">tf2 = List.new(table.size);</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">// define a window called "Setup mapping"</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">w = Window.new("Setup mapping", Rect(200,200,15*gap,190));</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">// add the reference notes as labels (fixed), and the mapped notes as text fields (editable)</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">// whenever a text field is updated, update the list of mapped notes (mapped)</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">table.do({arg item, i;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> var t, u;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> StaticText(w, Rect(10+gap*i, 10, gap, 30)).string_(miditoname.value(item));</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> t = TextField(w, Rect(10+gap*i, 50, gap, 30)).string_(miditoname.value(mapped[i]));</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> t.action = { mapped[i] = nametomidi.value(t.value); ("upper map note number " ++ i ++ " from " ++ table[i] ++ " to " ++ mapped[i]).postln; diffbuf.set(i, (table[i] - mapped[i]).midiratio.reciprocal)};</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> tf.add(t);</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> u = TextField(w, Rect(10+gap*i, 90, gap, 30)).string_(miditoname.value(mapped2[i]));</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> u.action = { mapped2[i] = nametomidi.value(u.value); ("lower map note number " ++ i ++ " from " ++ table[i] ++ " to " ++ mapped2[i]).postln; diffbuf2.set(i, (table[i]-mapped2[i]).midiratio.reciprocal);</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> tf2.add(u);</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> };</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">});</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">// add a button to play a reference note</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">c = Button(w, Rect(10,130,100,30)).states_([["Play C4",Color.black,Color.gray]]);</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">c.action_({arg butt;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> if (butt.value == 0,</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> {</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> var env = Env.perc;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> SinOsc.ar(nametomidi.value("c4").midicps)*EnvGen.kr(env, doneAction:2)!2;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> }.play,</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> {})</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">});</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">// also add a start/stop button</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">// when the button is set to start, instantiate a new Synth, otherwise free the Synth</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">b= Button(w, Rect(110,130,100,30)).states_([</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> ["Start",Color.black, Color.red],</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> ["Stop",Color.black, Color.green]]);</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">b.action_({arg butt;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> if (butt.value == 1,</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> {</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> tf.do({arg item; item.action});</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> tf2.do({arg item; item.action});</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> table.do({arg item, i;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> difference2[i] = (table[i] - mapped2[i]).midiratio.reciprocal;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> difference[i] = (table[i] - mapped[i]).midiratio.reciprocal;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> });</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> diffbuf.setn(0,difference);</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> diffbuf2.setn(0,difference2);</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> sound = Synth.new("pitchFollow1");</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> },</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> { sound.free;}</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> )</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">});</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">// define the Synth itself:</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">// - first it determines the pitch of what it hears in the microphone</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">// - then it harmonizes the pitch with the notes as defined in the ui</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">SynthDef.new("pitchFollow1",{</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> var in, amp, freq, hasFreq, out;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> var t, midinum;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> var harmony, harmony2, partials;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> in = Mix.new(SoundIn.ar([0,1]));</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> amp = Amplitude.kr(in, 0.05, 1);</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> # freq, hasFreq = Pitch.kr(in);</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> midinum = freq.cpsmidi.round(1);</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> midinum.postln;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> freq = Lag.kr(midinum.midicps, 0.05);</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> //freq = midinum.midicps;</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> harmony2= WrapIndex.kr(diffbuf2.bufnum, midinum);</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> harmony = WrapIndex.kr(diffbuf.bufnum, midinum);</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> partials = [</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> 0.5,</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> 1,</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> 0.5*harmony,</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> 1*harmony,</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> 0.5*harmony2,</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> 1*harmony2,</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> ];</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> out = Mix.new(PitchShift.ar(in, 0.2, partials, 0, 0.004));</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> 7.do({</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> out = AllpassN.ar(out, 0.040, [0.040.rand,0.040.rand], 2)</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> });</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> Out.ar(0,out/partials.size)</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">}).add;</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">// make the ui visible</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">w.front;</span><br style="font-family: "Courier New",Courier,monospace;" /><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">)</span></span><br />
<br />
<br />
Here's a sound example. It's not perfect, obviously, but to hear the computer create this in real time while you sing into the microphone is quite cool...<br />
<br />
<iframe frameborder="no" height="166" scrolling="no" src="https://w.soundcloud.com/player/?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F126953368&show_artwork=true" width="100%"></iframe>
<br/>
And a complete piece:
<br/>
<iframe width="100%" height="166" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F127207949&show_artwork=true"></iframe>shiihshttp://www.blogger.com/profile/01738225085577318818noreply@blogger.com5tag:blogger.com,1999:blog-5648227177104898374.post-55319754963645050212013-08-24T16:26:00.000-07:002015-09-06T05:31:19.801-07:00Algorithmic composition: generating tonal canons with Python and music21<div class="separator" style="clear: both; text-align: center;">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8AbUmUVDlUej07Z5YSiY6Hgdock1EKAACiViGoSaNdQTZXU95upQGIPrcpwLYRYuu7FbhpBWWAsj9m9xrR5VPeLizxdrA6Jm35lIoj0MS15jlpEoQQqtccCQwrvRmb_ublGURWCTneQk/s1600/spiced_up-blog.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="302" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8AbUmUVDlUej07Z5YSiY6Hgdock1EKAACiViGoSaNdQTZXU95upQGIPrcpwLYRYuu7FbhpBWWAsj9m9xrR5VPeLizxdrA6Jm35lIoj0MS15jlpEoQQqtccCQwrvRmb_ublGURWCTneQk/s640/spiced_up-blog.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">1x spiced up chord progression (intermediate step in canon generation)</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
</div>
<h2>
</h2>
<h2>
What?</h2>
According to wikipedia: <br />
<blockquote class="tr_bq">
<b>Algorithmic composition</b> is the technique of using <a href="http://en.wikipedia.org/wiki/Algorithm" title="Algorithm">algorithms</a> to create <a href="http://en.wikipedia.org/wiki/Music" title="Music">music</a>.<br />
<br />
Some algorithms that have no immediate musical relevance are used by composers as creative inspiration for their music. Algorithms such as <a class="mw-redirect" href="http://en.wikipedia.org/wiki/Fractals" title="Fractals">fractals</a>, <a href="http://en.wikipedia.org/wiki/L-system" title="L-system">L-systems</a>, <a href="http://en.wikipedia.org/wiki/Statistics" title="Statistics">statistical models</a>, and even arbitrary <a href="http://en.wikipedia.org/wiki/Data" title="Data">data</a> (e.g. <a href="http://en.wikipedia.org/wiki/Census" title="Census">census</a> figures, <a href="http://en.wikipedia.org/wiki/Geographic_information_system" title="Geographic information system">GIS</a> coordinates, or <a href="http://en.wikipedia.org/wiki/Magnetic_field" title="Magnetic field">magnetic field</a> measurements) have been used as source materials.</blockquote>
And: <br />
<blockquote class="tr_bq">
In <a href="http://en.wikipedia.org/wiki/Music" title="Music">music</a>, a <b>canon</b> is a <a href="http://en.wikipedia.org/wiki/Counterpoint" title="Counterpoint">contrapuntal</a> compositional technique that employs a <a href="http://en.wikipedia.org/wiki/Melody" title="Melody">melody</a> with one or more <a href="http://en.wikipedia.org/wiki/Imitation_%28music%29" title="Imitation (music)">imitations</a> of the melody played after a given <a href="http://en.wikipedia.org/wiki/Duration_%28music%29" title="Duration (music)">duration</a> (e.g., quarter rest, one measure, etc.). </blockquote>
<h2>
How?</h2>
Last year I wrote a series of articles on an easy method for writing some types of canons:<br />
<ul>
<li> <a href="http://a-touch-of-music.blogspot.be/2012/07/tutorial-on-my-technique-for-writing.html" target="_blank">Tutorial on my technique for writing a Canon</a></li>
</ul>
<ul>
<li><a href="http://a-touch-of-music.blogspot.be/2012/08/how-to-write-crab-canon.html" target="_blank">How to write a crab Canon</a></li>
</ul>
<ul>
<li><a href="http://a-touch-of-music.blogspot.be/2012/07/6-part-invention.html" target="_blank">6-part Invention</a></li>
</ul>
<ul>
<li>
<a href="http://a-touch-of-music.blogspot.be/2012/08/how-to-write-table-canon.html" target="_blank">How to write a table Canon</a></li>
</ul>
In at least one of those articles I claimed that the methods described there should be easy to use as basis for automation. Here I automate the
method for writing a simple canon as explained in the first of these articles.<br />
<h2>
Code?</h2>
The code discussed below is available under GPLv3 license on github: <a href="https://github.com/shimpe/canon-generator">https://github.com/shimpe/canon-generator.</a> Similar to the gcc compiler, the music you generate with this program is yours. The GPLv3 license only applies to the code itself.<br />
<br />
It depends on free software only: <a href="http://www.python.org/download/releases/2.7.5/" target="_blank">python 2.7</a>, <a href="http://web.mit.edu/music21/" target="_blank">music21</a> and <a href="http://musescore.org/" target="_blank">MuseScore</a>.<br />
<h2>
Explanation? </h2>
This program generates canons from a given chord progression in a fixed key (no modulations for now, sorry!).<br />
<br />
It does <b>NOT</b> generate atonal or experimental music, that is, if you're willing to accept the limitations of the program. It can occasionally generate "grave" errors against common practice rules (e.g. parallel fifths/octaves) -> see further explanation.<br />
<br />
It closely follows the method as explained in the <a href="http://a-touch-of-music.blogspot.be/2012/07/tutorial-on-my-technique-for-writing.html" target="_blank">Tutorial on my technique for writing a Canon</a> article referenced above. If you want to understand in detail how it all works, please read that article first, and then come back here. If you just want to experiment with the different program settings, continue :)<br />
<br />
<br />
One thing is worth explaining in more detail: the article mentions in one of the
first steps of the recipe that the composer can start from a chord progression, and
"spice it up" to get a choral. So: how to we get a computer to spice up a chord progression, without
building in thousands of composition rules?<br />
<br />
I introduced some note
transformations that:<br />
<ul>
<li>introduce small steps between notes so as to generate something that could be interpreted as a melody <br />
</li>
<li>do not fundamentally alter the harmonic function in the musical context <br />
</li>
</ul>
To accomplish this I replace with a sequence of notes without altering the total duration of the fragment, e.g.<br />
<ul>
<li>original note (half note) -> original note (quarter note), neighbouring note (8th note), original note (8th note)</li>
</ul>
Other transformations look at the current note and the next note, and interpolate a note in between (again, without changing total duration)<br />
<ul>
<li>original note (half note), next note -> original note (quarter note), note between original note and next note (quarter note), next note</li>
</ul>
A property of generating melodies by spicing up lists of notes using this method is that after spicing up a list of notes, you can spice the spiced up list again to get an even spicier list (more complex melody, both in pitch and in rhythm).<br />
<br />
Finally a warning for the sensitive ears: for a composer to write a choral
that obeys all the rules of the "common practice" takes years of study
and lots of practice. Given the extreme simplicity of the program, the computer
doesn't have any of this knowledge and it will happily generate errors against
the common practice rules (e.g. parallel fifths and octaves). Not always, but sometimes, as dicated by randomness. Note that this is an area in which the program could be improved, by checking for errors while spicing up and skipping proposed spicings that introduce errors against the common practice rules. <br />
<br />
Yet, despite the extreme simplicity of the method, the results can be surprisingly complex and in some cases sound interesting. <br />
<h2>
How can I use it?</h2>
In its current form, the program is not really easy to install and use, at least if you have no computer experience:<br />
<ul>
<li>You need to install the free python programming language from <a href="http://www.python.org/download/releases">http://www.python.org/download/releases</a>. I recommend using version 2.7. <u><i><b>Version 3 and later of python won't work!</b></i></u> </li>
<li>You also need to install the free <a href="http://web.mit.edu/music21/" target="_blank">music21toolkit for computer-aided musicology</a>. Follow the instructions on their website. Music21 provides for vast amounts of music knowledge which would take a long time to write ourselves. I'm using only a fraction of its possibilities in the canon generator.</li>
<li>Then you need something to visualize and audition the MusicXml that is generated by the program. For our purposes, the free <a href="http://musescore.org/" target="_blank">MuseScore </a>program works perfectly.</li>
<li>Finally you need to get the free canon-gen.py program from the github repository <a href="https://github.com/shimpe/canon-generator">https://github.com/shimpe/canon-generator</a>.</li>
</ul>
The main function defined near the bottom of the canon-gen.py file contains some parameters you can edit to experiment with the generator:<br />
<ul>
<li><i>chords = "C F Am Dm G C"</i> <br />#You can insert a new chord progression here.<i> </i></li>
<li><i>scale = music21.scale.MajorScale("C")</i>
<br />#You can define a new scale in which the notes of the chords should be interpreted here<i> </i></li>
<li><i>voices = 5</i>
<br />#Define the number of voices in your canon here<i> </i></li>
<li><i>quarterLength = 2</i>
<br />#Define the length of the notes used to realize the chord progression
<br />#(don't choose them too short, since the automatic spicing-up will make them shorter)<i> </i></li>
<li><i>spice_depth = 1</i>
<br /># Define how many times a stream (recursively) should be spiced up
<br /># e.g. setting 2 will first spice up the chords, then again spice up the already spiced chords.
<br /># scores very quickly become rhytmically very complex for settings > <i>2</i></li>
<li><i>stacking = 1</i>
<br /># the code can generate multiple versions of the spiced up chord progression, and use those
<br /># versions to create extra voices
<br /># e.g. setting stacking = 2 will turn a 3-voice canon into a 3*2 = 6-voice canon<i> </i></li>
<li><i>voice_transpositions = { VOICE1 : +12, VOICE2 : 0, VOICE3 : -12, VOICE4: -24, VOICE5: 0 }</i>
<br /># allow extra octave jumps between voices</li>
</ul>
<h2>
What does it sound like?</h2>
This is a simple example generated with the program with settings<br />
<ul>
<li><i>chords = "C F Am Dm G C"</i></li>
<li><i></i><i>scale = music21.scale.MajorScale("C")</i></li>
<li><i></i><i>voices = 5</i></li>
<li><i>quarterLength = 2</i>
<i></i></li>
<li><i>spice_depth = 1</i></li>
<li><i>stacking = 1</i>
<i></i></li>
<li><i>voice_transpositions = { VOICE1 : 0, VOICE2 : 0, VOICE3 : -12, VOICE4: -24, VOICE5: 0 } </i>
</li>
</ul>
<h2>
<iframe frameborder="no" height="166" scrolling="no" src="https://w.soundcloud.com/player/?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F107077393&show_artwork=true" width="100%"></iframe> Ideas for future improvements</h2>
I see many possible improvements, most of which are low-hanging fruits. Feel free to jump in and improve the code :D<br />
<ul>
<li>fix a known bug related to octaviations in keys other than C </li>
<li>support modulations, i.e. keep musical key per measure/beat instead of over the complete chord progression </li>
<li>extend the code to cover the things explained in the later articles: crab and table canons</li>
<li>see if the method/code can be extended to generate canons at the third, fifth, ... </li>
<li>smarter spicing up of chord progressions to avoid parallel fifths/octaves (e.g. rejecting a proposed spice if it introduces an error in the overall stream); or use Dmitry Tymoczko's voice leading spaces to ensure better voice leading by construction.</li>
<li>protect the end chord from getting spiced up</li>
<li>implement more note transformations, e.g. appogiatura</li>
<li>experiment with more rhythms</li>
<li>how can we better spice up the chord progressions without messing up too much of the original harmonies?</li>
<li>... </li>
</ul>
shiihshttp://www.blogger.com/profile/01738225085577318818noreply@blogger.com0tag:blogger.com,1999:blog-5648227177104898374.post-77030967957749727102013-06-19T11:32:00.002-07:002013-06-19T12:36:40.696-07:00Seaside canon, for Douglas Hofstadter<h1>
What?</h1>
Here's a musical crab canon inspired by <a href="http://measureofdoubt.com/2011/06/06/a-crab-canon-for-douglas-hofstadter/" target="_blank">a blog post from Julia Galef</a>, who wrote quite an impressive crab canon <b><i>poem</i></b>.
My musical interpretation of her poem is a crab canon too. It differs from <a href="http://a-touch-of-music.blogspot.be/2012/08/how-to-write-crab-canon.html">my previous crab canon</a> in the following aspects:<br />
<br />
<ol>
<li> This canon was conceived after serendipitously finding a poem written by Julia Galef, who kindly granted me permission to use it.</li>
<li>Compared to the previous crab canon, this one uses more and longer pedal notes. What can I say - I just love pedal notes! </li>
<li>In contrast to my previous crab canon, this one modulates to different keys. Have you discovered <a href="http://a-touch-of-music.blogspot.be/2012/09/modulation.html">my free modulation book</a> yet?</li>
<li>As a nice variation on a typical crab canon (where you can reverse the score), here you can also reverse the raw audio samples. That's right! When you reverse the raw audio samples and listen to the result, you get the same piece again. Mind you: I'm not just talking the notes, but also the timbres! Nothing should sound more "<i>backward</i>" than in the forward version of the piece. You can try it out! Download <a href="https://docs.google.com/file/d/0B2JcYjgxQWlLUzBtcWxsaXJDWXc/edit?usp=sharing" target="_blank">the raw audio</a> and import it into your favourite audio editor. Then listen to it, and relisten to it in reverse.</li>
<li>The spectrogram (slowly appearing in black on white) looks like the sea, and the score layed on top of it in colored rectangles looks like a frontal view of a crab. Very appropriate for a crab canon about seaside :) Ok, that's a joke (or not? Try squinting your eyes... :D ) </li>
</ol>
With respect to the images that pass by: in black on white you can see a spectrogram of the piece.
In colored rectangles I've overlayed half of the notes that are being played in the canon (four voices). The other half of the notes you hear come from those same voices simultaneously playing backwards.<br />
<br />
I've developed a systematic method for constructing music canons, crab & palindrome canons, and table canons using <a href="http://lilypond.org">Lilypond</a>, fully documented in a series of articles that you can freely download and use. It's advised to read them in the order listed below:<br />
<br />
<a href="http://a-touch-of-music.blogspot.be/2012/07/tutorial-on-my-technique-for-writing.html" target="_blank">Tutorial on my technique for writing a Canon</a><br />
<a href="http://a-touch-of-music.blogspot.be/2012/08/how-to-write-crab-canon.html" target="_blank">How to write a crab Canon</a><br />
<a href="http://a-touch-of-music.blogspot.be/2012/07/6-part-invention.html" target="_blank">6-part Invention</a><br />
<a href="http://a-touch-of-music.blogspot.be/2012/08/how-to-write-table-canon.html" target="_blank">How to write a table Canon</a><br />
<br />
I'm aware that the method I devised in its current form still has limitations and does not necessarily yield music that can compete with the Big Composers, but who knows... I still have some ideas for further experimentation. And besides, it's just too much fun :)<br />
<br />
<iframe width="560" height="315" src="http://www.youtube.com/embed/km4-eJ3owjk" frameborder="0" allowfullscreen></iframe>
shiihshttp://www.blogger.com/profile/01738225085577318818noreply@blogger.com0tag:blogger.com,1999:blog-5648227177104898374.post-66177663489050782532013-04-17T16:40:00.002-07:002013-04-28T14:11:23.691-07:0025 shades of random<h1>A first exploration of algorithmic composition.</h1>
<p>
I've written a simple scheduler in the programming language python and I've created some midi event generators, and combined both of those to drive the software synthesizer <b>Yoshimi</b> and the sampler engine <b>LinuxSampler</b> using the <a href="http://jackaudio.org/">jack-midi</a> protocol. I've made the complete code available on <a href="https://github.com/shimpe/twenty-five-shades-of-random">github</a>.
</p>
<p>
The midi events are generated based on a concept of <b>randomness within constraints</b>. The things you hear are randomly generated, but not in an "anything goes" manner.
<p>
Constraints are imposed to limit the disorder of the randomness. Just like harmony and counterpoint limit randomness in traditional composition, the constraints here limit randomness in the experimental composition. One could say that different constraints generate families of alternative music theories.
</p>
<p>
"Randomness within constraints" is a deep idea whose time has come. Nowadays it is extremely popular both in science (artificial intelligence) and art (abstract art) and indeed one of the basic mechanisms underlying the origin and evolution of life itself. I suspect that "randomness within constraints" is the barren wasteland where creativity and innovation hides. In this piece, I try to explore a number of different constraints. In some cases the constraints slowly evolve, in other cases they abruptly change.
</p>
<a href="http://en.wikipedia.org/wiki/Ton_de_Leeuw">Ton De Leeuw</a> in a speech once distinguished between two kinds of music:
"music that becomes" versus "music that is". "Music that becomes" is music that starts from a begin point and gradually evolves. "Music that is" is music that doesn't show any progression or evolution. Because the constraints I used are quite static (with some exceptions they don't gradually evolve as time progresses), I think this composition is closer to "music that is". Nevertheless, I hope that by combining different timbres and different constraints I have managed to keep the composition reasonably interesting to listen to.
</p>
<p>
Note: I do not consider "traditional music theory" (or rather: the different traditional music theory families) inferior or unnecessary (quite the contrary!), but in this piece I don't mind looking beyond its borders.
</p>
<p>
For this composition I programmed my own algorithmic composition system using <a href="http://python.org/">Python</a>, <a href="https://pypi.python.org/pypi/python-rtmidi/">Rtmidi</a>, <a href="http://yoshimi.sourceforge.net/">Yoshimi</a> and <a href="http://www.linuxsampler.org/">LinuxSampler</a> with <a href="http://sso.mattiaswestlund.net/">Sonatina Sound Fonts</a>,
but for a next algorithmic composition (if any ;) ) I would probably try to use the excellent
<a href="http://supercollider.sourceforge.net/">supercollider</a> environment instead.
</p>
<p>
The visualization was made with <a href="http://www.sonicvisualiser.org/">Sonic Visualiser</a>.
</p>
<p>
Enjoy!
</p>
<iframe width="560" height="315" src="http://www.youtube.com/embed/C0ojxscXbMU" frameborder="0" allowfullscreen></iframe>
shiihshttp://www.blogger.com/profile/01738225085577318818noreply@blogger.com0tag:blogger.com,1999:blog-5648227177104898374.post-68037738255362856822012-12-27T14:04:00.000-08:002013-02-15T15:35:16.817-08:00Musical key and mood<h2>
Key determines mood? Really?!</h2>
<div>
It is often argued that with the advent of <a href="http://en.wikipedia.org/wiki/Equal_temperament" target="_blank">equal temperament</a> all differences between musical keys disappeared, i.e. C major doesn't sound fundamentally different from Eb major. Yet composers still attribute certain moods to certain musical keys. In part this is probably determined by tradition, and in part it may be influenced by the mechanics of playing an instrument: playing a piece in C major on a piano (using only white keys) is quite a different experience from playing that same piece in C# major (using many black and some white keys) because of the differences between physical location of black and white keys on a piano. Also, bowed instruments will often play an F# differently than a Gb, despite both being the same note on a piano.</div>
<div>
<br /></div>
<h2><div>
So what are these traditional moods associated to certain keys?</div></h2>
This list is <a href="http://www.koelnklavier.de/quellen/schubart/s-377_tonarten.html">based on a list</a> made up by <a href="http://en.wikipedia.org/wiki/Christian_Friedrich_Daniel_Schubart">Christian Schubart</a> in his book <a href="http://www.amazon.com/Ideen-%C3%84sthetik-Tonkunst-German-Edition/dp/127972062X/ref=sr_1_fkmr2_2?ie=UTF8&qid=1356645237&sr=8-2-fkmr2&keywords=ideen+zur+einer+aesthetik+der+tonkunst">Ideen Zu Einer Ästhetik Der Tonkunst...</a>
<br/>
<div>
<table>
<tr><th>Key</th><th>Mode</th><th>Mood</th></tr>
<tr><td>C</td><td>major</td><td><i>completely pure key; speaks of innocence, simplicity, naivety, child's talk</i></td></tr>
<tr><td>Db</td><td>major</td><td><i>key to bring out unusual feelings; can smile but not laugh; can grimace but not cry</i></td>
<tr><td>D</td><td>major</td><td><i>key of triumph, hallelujah, war-cries and victory-rejoicing</i></td>
<tr><td>Eb</td><td>major</td><td><i>key of love, devotion, intimate conversation with God</i></td>
<tr><td>E</td><td>major</td><td><i>noisy shouts of love, laughing pleasure and not-yet-complete full delight </i></td>
<tr><td>F</td><td>major</td><td><i>key of complaisance and calmness</i></td>
<tr><td>Gb</td><td>major</td><td><i>key of triumph over difficulty, sigh of relief after difficulaties have been overcome</i></td>
<tr><td>G</td><td>major</td><td><i>key that is rustic, idyllic and lyrical, calm and satisfied passion, any gentle and peaceful emotion of the heart</i></td>
<tr><td>Ab</td><td>major</td><td><i>key of the grave, death, putrefaction, judgement, eternity</i></td>
<tr><td>A</td><td>major</td><td><i>declaration of innocent love, satisfaction with one's state of affairs, hope of seeing one's beloved one again when departing, youthful cheerness and trust in God</i></td>
<tr><td>Bb</td><td>major</td><td><i>cheerful love, clear conscience, hope, aspiration for a better world</i></td>
<tr><td>B</td><td>major</td><td><i>strongly colored, announcing wild passions, anger, rage, jealousy, fury, despair and every emotion of the heart</i></td>
<tr><td>C</td><td>minor</td><td><i>declaration of love with lament of unhappy love, sighing of the lovesick soul</i></td></tr>
<tr><td>C#</td><td>minor</td><td><i>penitential lamentation, intimate conversation with God, sighs of disappointed friendship and love</i></td>
<tr><td>D</td><td>minor</td><td><i>melancholy, womanliness</i></td>
<tr><td>Eb</td><td>minor</td><td><i>feelings of anxiety, the soul's deepest distress, brooding despair, blackest depression, most gloomy condition of the soul</i></td>
<tr><td>E</td><td>minor</td><td><i>naive declaration of love, lament without grumbling, sighs accompanied by a few tears, desires to resolve into the pure happiness of C major</i></td>
<tr><td>F</td><td>minor</td><td><i>deep depression, funeral lament, groans of misery and longing for the grave</i></td>
<tr><td>F#</td><td>minor</td><td><i>a gloomy key, resentment and discontent, it languishes for the calm of A major or happiness of D major</i></td>
<tr><td>G</td><td>minor</td><td><i>discontent, uneasiness, worry about a failed scheme, bad-tempered gnashing of teeth, dislike</i></td>
<tr><td>G#</td><td>minor</td><td><i>grumbling, struggling with difficulty, heart squeezed until it suffocates</i></td>
<tr><td>A</td><td>minor</td><td><i>pious womanliness, tenderness of character</i></td>
<tr><td>Bb</td><td>minor</td><td><i>mocking God and the world, discontented with itself and everything, preparation of suicide</i></td>
<tr><td>B</td><td>minor</td><td><i>key of patience, calm awaiting one's fate, submission to divine dispensation, mild lament without breaking out into offensive murmuring or whimpering, </i></td>
</table>
</div>shiihshttp://www.blogger.com/profile/01738225085577318818noreply@blogger.com11tag:blogger.com,1999:blog-5648227177104898374.post-48007573083165464682012-09-09T15:44:00.000-07:002012-09-09T15:47:09.560-07:00Modulation<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhN5d3qgxT3YSo4pcWqFhPgXxhL_wrwkmgru83IU9um81I08Lnj_fThkZZG2HGkRYRRxdWrI5jJQ4YPm3tE-6vt9jwl0kBNAY8-7Z0asNA00JDlTxWo-x-vFw5JyglwZSr3QnktdQbXYk8/s1600/modulationbook.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="311" width="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhN5d3qgxT3YSo4pcWqFhPgXxhL_wrwkmgru83IU9um81I08Lnj_fThkZZG2HGkRYRRxdWrI5jJQ4YPm3tE-6vt9jwl0kBNAY8-7Z0asNA00JDlTxWo-x-vFw5JyglwZSr3QnktdQbXYk8/s400/modulationbook.png" /></a></div>
<h1>Modulation</h1>
<p>
<a href="http://en.wikipedia.org/wiki/Modulation_(music)">Modulation</a> is the art of smoothly moving from one musical key to another. Modulation is one of the ways to make your music more interesting. If this sounds intriguing and you know how to read music notes, stay with me.
</p>
<p>
Three weeks ago, I set out to learn something about modulation. I took notes while doing so, and I'm making those notes available for anyone interested in the subject. The notes so far encompass 257 (!) pages full of modulations between different keys. Each modulation each time is written out in all keys, leading to a catalogue of modulations from any key to any key (well... almost. It's a work in progress). It also contains brief explanations about the underlying principles that make the modulation work. Using those principles, it should be possible to create new modulations yourself.
</p>
<p>
Most of the material is illustrated in the context of classical music theory (but all the underlying principles illustrated there apply also to jazz/blues/pop/gospel/...), but part III also contains some beginnings of Jazz and Gospel cadenzas.
</p>
<h1>Downloading?</h1>
<p>
Sure. The document is available under a <a href="http://creativecommons.org/licenses/by-nc-sa/3.0/">CC-BY-NC-SA license</a>. The source code is available on <a href="https://sourceforge.net/projects/modulations/">sourceforge</a>. It requires <a href="http://lilypond.org/">lilypond</a>, <a href="http://www.lyx.org/">lyx</a> and <a href="http://www.latex-project.org/">LaTeX</a> to "compile" to .pdf.
</p>
<p>
You can also download a <a href="https://sourceforge.net/projects/modulations/files/">prebuilt .pdf</a> from the files section.
</p>
<p>
If you have downloaded and skimmed the book, be sure to comment either here or on <a href="https://sourceforge.net/p/modulations/discussion/general/">the book's forum</a>.
</p>
shiihshttp://www.blogger.com/profile/01738225085577318818noreply@blogger.com3tag:blogger.com,1999:blog-5648227177104898374.post-78971497614092323812012-07-28T06:27:00.000-07:002012-09-09T15:46:21.214-07:00Explanation about technique used in writing my 6-part inventionDownload the article by <a href="https://docs.google.com/open?id=0B2JcYjgxQWlLMGNJeXM2cHFyRlU">clicking this link</a>. You may have trouble downloading it with some versions of internet explorer. In that case use chrome or firefox instead.
</p>
You can hear the result of the tutorial in <a href="http://a-touch-of-music.blogspot.be/2012/07/6-part-invention.html">my previous post</a>.shiihshttp://www.blogger.com/profile/01738225085577318818noreply@blogger.com0tag:blogger.com,1999:blog-5648227177104898374.post-35361486459379770602012-07-24T13:01:00.000-07:002012-09-09T15:46:54.444-07:00Tutorial on my technique for writing a canonI promised to write a tutorial on how to write a canon like the one I posted in my previous post <a href="http://a-touch-of-music.blogspot.be/2012/07/canon-in-5.html">Canon in 5</a>, and I did.<br />
<p>
The tutorial is 12 pages long, but most of that space is taken up by white-space and examples. You will probably get the most out of it if you already know how to read music, although strictly speaking it is not a requirement to already benefit from the material in the tutorial.
<p/>
<p>
You can get the tutorial in .pdf format by clicking <a href="https://docs.google.com/open?id=0B2JcYjgxQWlLbXJmcmkwN244SEk">this link</a>. You may have trouble downloading it with some versions of internet explorer. In that case use chrome or firefox instead.
</p>
<p>
You can listen to the result of the tutorial here:<br />
<iframe width="100%" height="166" scrolling="no" frameborder="no" src="http://w.soundcloud.com/player/?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F53964995&show_artwork=true"></iframe>
</p>
<p>
Drop me a note if you've been able to use the techniques explained in there.<br />
</p>shiihshttp://www.blogger.com/profile/01738225085577318818noreply@blogger.com10tag:blogger.com,1999:blog-5648227177104898374.post-34942542045743615582012-03-17T13:52:00.000-07:002012-03-17T13:52:06.057-07:00Mixing and mastering<i>Disclaimer: I'm by no means a professional mixing/mastering engineer (in fact, quite the opposite ;) ). I do like to research stuff, and will occasionally report on what I find out here. The explanations may contain factual errors, in which case I'd appreciate if you took the time to report errors or inaccuracies. Given the huge field that audio mixing really is, this post will necessarily skip a lot of details.</i>
<h1>Why did you write this post?</h1>
I hear many problems in my own recordings, and have decided I should educate myself a bit on the subject.
This is mainly written as a summary of things I read and remembered.
<h1>Mixing? Mastering?</h1>
First things first: what's the difference between mixing and mastering?
<p/>
In <b>mixing</b> one tries to bring together different tracks into one recording. In doing so, one can apply a whole range of effects to each track separately before combining them to a complete song. I intend to discuss some of those effects in this post.
<p/>
In <b>mastering</b> one takes a mixed song and applies effects to the whole mix at once. This would be done e.g. to make all songs on an album share a similar <i>hear and feel</i>.
<p/>
A photoshop (or gimp ;) ) analogy would be that in mixing you combine clipart into a picture, and in mastering you apply effects to the picture as a whole (cropping, change colors to sepia, ...).
<p/>
My current investigation is mostly about mixing audio.
<h1>Mixing objectives</h1>
In mixing audio one strives to create interest, mood, balance and definition.
These four dimensions can be heavily influenced by cleverly applying effects to each of the tracks.
<ul>
<li><b>Interest</b>: is all about keeping the listener's attention by adding enough variation in the mix. Example: make the chorus sound subtly different than the verse, or make verses with dark lyrics sound darker than verses with lighter lyrics. Variation keeps the interest higher. You can also decide where to put the instruments in an (imaginary) 3d audio scene. If you pay attention to recordings, you can start to hear how certain instruments seem to sound as if they are placed on different places on a sound stage. </li>
<li> <b>Mood</b>: how do you make the same music sound darker or lighter? More mellow or more aggressive ?</li>
<li> <b>Balance</b>: make sure each instrument gets the space it needs and make sure that the instruments don't sound like a bunch of aliens that happen to play simultaneously. The different instruments should sound as if they belong together, and none of the instruments should overpower all of the other instruments.</li>
<li> <b>Definition</b>: make sure enough details can be heard in each of the instruments, voices, and at the same time get rid of the unwanted details like breathing.</li>
</ul>
<h1>Mixing techniques</h1>
In order to achieve those objectives, we can apply effects to the individual tracks that must be mixed together.
Some effects will operate on the time domain (i.e. it will influence how volume changes over time, or how long certain sounds remain hearable), whereas other effects will mostly influence the frequency domain (change how a specific sound sounds, e.g. make vocals sound clearer or darker).
<h2>Phase</h2>
In itself, the phase of a single track is pretty meaningless. Sound is made of waves, and phase says something about at which moment in time the wave reaches its peaks (low and high), and passes through zero. Phase starts to matter when you combine two or more tracks. A phase difference between two tracks is a small delay between the two tracks. Funny things can happen when you mix sounds with different phase. When you mix two tracks, you basically sum them. If you take one track, make a copy of it and apply phase inversion to the copy, then mix both tracks together you end up with no sound at all: the phase inversion causes both tracks to cancel each other out. (Indeed when the original reaches its peak, the phase-inverted copy reaches its valley and vice versa. At each moment in time the waves are each other's complement.) Of course this is an extreme example that you would never encounter in practice. But if you record the same track simultaneously with different distances to different microphones a phase difference could be present, and if it is not compensated before mixing, it might lead to unwanted (partial) cancellations of sound. Applying certain effects will also affect the phase of the track. Mixing together tracks with phase differences will result in something that sounds a bit different (usually worse) than what you expected, typically a more metallic, hollow sound. Sometimes this effect is applied on purpose: then it's called <b>flanging</b>. There's another related effect called <b>phasing</b>. Both effects suppress certain frequency components (a phenomenon called <i>comb-filtering</i> takes place). In flanging the frequencies that are suppressed are harmonically related, in phasing they are not. Phasing is usually a little bit more subtle than flanging.
<p/>
Sometimes you can play with phase to achieve interesting effects. One such effect is known as the <b>"Haas" effect</b>. Basically you take a track, and hard-pan it to the left speaker. Then you take a copy of that track and hard-pan it to the right speaker + let it play starting a few milliseconds after the first track. As a result you get a very spacious open sound. Try it out in your favourite audio tool. Another trick is the <b>out-of-speakers trick</b> where you keep the tracks time-aligned, but you invert the phase of one of the tracks. This results in sound that seems to come from all around you. Works best with low-frequency (i.e. low notes) sounds.
<h2>Fading</h2>
Fading is adapting the volume of your track, in order to give each instrument equal chances of being heard. To add interest to a recording, many programs allow automating volume levels, so that variations can occur throughout the song. Beware though: humans are only human, and psychoacoustics dictate that "louder" gives the impression of sounding "better". The result is often that volumes tend to be increased, to the point where they don't make sense anymore, or don't leave enough room for other instruments to be added. If volume is set too high, also clipping can occur, which results in considerable distortion (typically clicking or crackling sounds) in the end result.
<h2>Panning</h2>
With panning you can give different instruments a different spot on the virtual sound stage you are creating in your mix. Its effect is to make the sound come more from the left or from the right. When speaking about panning, one often refers to the sound as coming from a different "hour". Hard left would be 7:00, hard right would be 17:00 and right in front of you would be 12:00.
<h2>Compressors and other dynamic range processors </h2>
The word compression has two different meanings. On one side it is used to denote the process of representing digital recordings with fewer bytes (like .mp3 is a compressed version of .wav). This is not the meaning that is used in audio mixing.
In audio mixing, compression means something different: it means reducing the dynamic range, i.e. reducing the difference between the loudest and most silent parts of a track. Like that the recorded track can blend better with other tracks. Compression is often used on vocals: without it, the more silent parts of the singing risk to drown in the sounds of the other tracks. In this context: apparently in the recording industry there's an ongoing <b>loudness war</b>: by (ab)using compression, recordings are made to sound as loud as possible. The downside is of course that a lot of dynamic range is lost that way and the music becomes less interesting as a result. Different applications of compressors include:
<ul>
<li><b>Compressor</b>: make loud sounds more quiet (while keeping a sense of louder and more silent); keep silent sounds at the same volume</li>
<li><b>Limiter</b>: ensures that the volume never exceeds a given maximum. The volume of any sound that is louder than some threshold is brought back to the threshold. Volume of sound that is more silent than the threshold is kept as-is.</li>
<li><b>Expander</b>: making quiet sounds quieter; keep louder sounds at their original level</li>
<li><b>Upward compressor</b>: make quiet sounds louder, keep loud sounds at their original volume</li>
<li><b>Upward expander</b>: make loud sounds even louder, keep silent sounds at at their original volume</li>
<li><b>Gate</b>: make all signals with a volume below some threshold a lot more quiet (with a fixed amount known as <i>the range</i>; often: completely remove)</li>
<li><b>Ducker</b>: make all signals with a volume higher than some threshold a lot more quiet (with a fixed amount known as <i>the range</i>
</ul>
Compressors can have some unwanted side effects, producing varying noise/hiss levels (<b>breathing</b>) or sudden noticeable level variations (<b>pumping</b>). In case of extreme compressing one also loses dynamic range, to the point of making the music less interesting. When used properly, compression can make sounds denser, warmer, louder. Compression can move sounds forward and backward in the virtual sound stage. To a certain extent it can be used to remove sibilance.
<h2>Equalizing</h2>
Equalizers can have various effects on your sound. They are not so easy to use effectively. They can influence separation (hearing details from individual instruments), feelings and moods, make instruments sound different, adding depth to sound, suppress unwanted content (like constant background noise or humming). To a certain extent they can also compensate for bad recordings, or to suppress unwanted sibilance. <b>Sibilance</b> is the piercing sound produced when recording fricative sounds ("s", "sh", "ch", "t") which can be quite disturbing in a song.
<p/>
Equalizers typically work on a part of the frequency spectrum. Depending on the part of the frequency you operate on, and the kind of operations you do on it, you get wildly different effects from the equalization. In short: equalizing is like the swiss knife of audio mixing, and it requires (a lot) more investigation from my side.
<p/>
A rule of thumb seems to be that equalization should be done after compressing.
<h2>Reverb</h2>
Ever noticed how the same instrument can sound very different in a different room? One of the factors that determine this difference in sound is the reverb. As you emit sound, it travels through the room and bounces off walls and furniture. Some frequencies will be absorbed by the materials in the room, others less so (this is a kind of natural equalization taking place). After a while, delayed and filtered copies of the sound will arrive at the sound source again (reflections from the walls).
<p/>
Different ways exist to add reverb to a signal. One interesting technique involves using an impulse response of a room. Think: you clap in your hands, and you record the sound with all the echos this makes. This is more or less the impulse response of the room. Now you can apply this same echo to any other sound using a mathematical operation known as <i>convolution</i>. So if you have the impulse response of a famous concert hall, you can make your piece sound as if it was played in that concert hall. The downside of convolution with an impulse response is its computational requirements, and its inflexibility: there are no parameters you can tweak. For this reason also other algorithms have been developped that allow more flexibility in reverb definition (e.g. choosing the room size). Convolution with the impulse response will more automatically result in a natural sound. Note that in principle you could also apply convolution between any two samples (say: an oboe and a talking voice). The result is <b>cross-synthesis</b>, i.e. the oboe that seems to speak the words of the voice.
<p/>
Reverb is used to add depth to a recording. A common reverb applied to all tracks can make them sound more compatible, fit better together in the mix (on the other hand, applying different reverb to different tracks can help to increase the separation between instruments). Reverb can fill up pauses in the sound. It also contributes to the mood.
<h2>Delay</h2>
Delay delays a signal with a given time. Mixing the original signal with the delayed signal creates an echo, but if the delay is short enough, we won't perceive the mix as two distinct copies of the same sound. In case of very short delays: be careful of phase differences between the original signal and the delayed copy: they can lead to unwanted side effects during mixing. With slightly longer delays you can get an effect of doubling (i.e. the basis for a chorus effect; making a less dry sound). With longer delays, you create an echo effect. See also the explanation about the "Haas" effect in the section about phase, which is another application of delay.
<h2>Vibrato and tremolo</h2>
Two kinds of vibrato exist: frequency vibrato and amplitude vibrato (sometimes called tremolo). In frequency vibrato one rapidly alterates the pitch, in tremolo one rapidly changes the volume.
<h2>Distortion</h2>
Distortion adds to aggressiveness of the end result. It is also a way of adding imperfections to sound, rendering it less boring (when applied skillfully ;) ). The easiest and least subtle way to add distortion is to clip sounds to a certain limit. Other techniques include applying amplifier simulators and bit reduction techniques.
<h2>Pitch shifting, time stretching and harmonizing</h2>
Pitch shifting and time stretching are very closely related to each other (at least from a mathematical point of view). If you play back the same recording faster (e.g. by selecting a different sampling rate or by making some tape run faster), it will become shorter, but also its pitch will increase. Sometimes you want to make recordings faster or slower without affecting the pitch. This is not easy to accomplish, and different instruments typically require different algorithms to get a convincing result. Also when the stretching or pitch shifting is very extreme, sound quality will clearly suffer. Even with the best algorithms. Pitch shifters are useful to correct instruments and vocals that are off-tune. They can also be used to turn a piece with one voice into a choir piece with multiple voices singing different pitches simultaneously (harmonizing). The algorithms used typically offer some parameters that allow you to create special effects as a side effect of the pitch shifting or time stretching.
<h1>Conclusions</h1>
This is more than enough material for this post. As you can see there's more to mixing audio than just throwing different tracks together. This post only scratched the surface of what mixing is all about. The real difficulty starts when, presented with some recordings, you have to make sense of it all: decide which effects to apply, how to configure their numerous parameters, in what order to apply them, etc etc. in order to reach a desired end result.
<p/>
Ideas for future posts (but those may may never get written, or at least not in the coming years, since I still have no experience with all these things):
<li>in-depth discussions of single effects, illustrated with ladspa or other plugins in some popular tools (audacity, snd, ardour,...?)</li>
<li>topical discussions, like: how to clean up vocals</li>
Maybe all these tutorials and discussions already exist somewhere, in which case I'd be happy to see some links in the comments section.shiihshttp://www.blogger.com/profile/01738225085577318818noreply@blogger.com2tag:blogger.com,1999:blog-5648227177104898374.post-31380638371887949252012-03-07T15:12:00.000-08:002012-03-07T15:12:04.139-08:00Swan song<h1> Swan song </h1>
<h2> Near-tonality </h2>
Something that fascinates me is the concept of near-tonality. I'm not certain if this is existing terminology, and if it means what I would like it to mean in the context of this blog post. I use it to denote music that somehow "almost" sounds tonal. A typical example would be a soloist playing something "out-of-key", while the accompaniment remains "in-key". The notes sound wrong in the context, but if you keep playing out-of-key systematically something funny happens: once you get used to the new musical language, it all starts to sound right again. You start to hear how different types of dissonances can evoke different moods, and what first sounded all weird and wrong suddenly sounds beautiful, comforting and soothing.
<p/>
<h2> Music please? </h2>
As you may have guessed, all this was but a long introduction towards my most recent somewhat experimental LMMS composition: <b>Swan song</b>!
<p/>
After 2 minutes of tonal introduction, I dip my toes into the rich world of near-tonality and atonality.
<ul>
<li> +1 @ you if you can listen to it once without questioning my mental sanity </li>
<li> +2 @ you if you can listen to it three times in a row without it getting stuck inside your head for the next two days ;) </li>
</ul>
<p/>
<iframe width="640" height="360" src="http://www.youtube.com/embed/SUQ5AEwRKso?feature=player_embedded" frameborder="0" allowfullscreen></iframe>shiihshttp://www.blogger.com/profile/01738225085577318818noreply@blogger.com3tag:blogger.com,1999:blog-5648227177104898374.post-27171398093130028002012-01-30T04:17:00.000-08:002012-02-01T03:58:37.953-08:00Tunestorm<h1>Tunestorm deadline is approaching</h1>
<p>Tunestorm is a kind of online experiment (an <i>un</i>competition as they call it) where you are given an assignment
and you are expected to carry it out in your own style, using your own ideas, instruments, background,... How cool is that?</p>
<p>More info? <a href="http://opensourcemusician.com/index.php/Tunestorm">http://opensourcemusician.com/index.php/Tunestorm</a>
I'm not affiliated with the organization in any way, but I'm ridiculously enthusiastic about contributing something to it.</p>
<p>Next <b>deadline</b> is <b>29th of february 2012</b>. Don't wait, get started today :) I don't want to end up being the sole contributor :D</p>
<h1>Current assignment</h1>
Current assignment for the seventh edition is: "Write any song of your choosing WITH lyrics in the form of a haiku, i.e. lyrics with 5-7-5 syllables"
You are expected to keep your work a secret until <i>the big revelation day</i> to avoid influencing other <i>un</i>contenstants.shiihshttp://www.blogger.com/profile/01738225085577318818noreply@blogger.com0tag:blogger.com,1999:blog-5648227177104898374.post-89054029573412015312012-01-26T16:55:00.000-08:002012-01-26T17:14:01.077-08:00Yay! My first Lmms project...I discovered the free and open source tool LMMS a few days ago via some post in the http://LinuxMusicians.com forum.
The software seemed so easy to use and so inviting to experiment with that I just had to try it out.<br />
<br />
Love it or hate it... here's my first lmms project:
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/Vvr8dsNwFU4" width="560"></iframe><br />
<br />
In case you'd want to reuse the choral parts I wrote for this piece (one never knows :) ) you can download the entire .mmpz file here: <a href="http://www.mediafire.com/?4dfov022014coe6">http://www.mediafire.com/?4dfov022014coe6</a> (creative commons attribution share-alike v3.0 license)<br />
<br />
The music was completely made with lmms in debian linux. It probably sounds best with decent headphones or a decent speaker set with subwoofer.
<br/>
The video was made with kdenlive on debian linux.
<br />
Have fun!
<br/>
(Oh and did I mention already that comments and constructive criticisms are welcome? :D )shiihshttp://www.blogger.com/profile/01738225085577318818noreply@blogger.com0tag:blogger.com,1999:blog-5648227177104898374.post-4286118742779724442012-01-02T09:15:00.000-08:002012-01-13T12:25:59.782-08:00Take-off!<h1>Yet another blog?</h1>
Yes. I have found that maintaining a blog is a good way to force myself
to document some of my musical experiments. It has happened multiple times already that
I've created some music and the little evidence that existed of it got lost in computer crashes,
or in unreadable binary proprietary file formats of defunct tools. Some of my scores (of which I had only one copy of course :) )
I lended to others but never got back.
<h1>What's the purpose of this blog?</h1>
I want a place to ponder about music, to brainstorm about music, to discuss some music related tools, perhaps post the occasional tutorial. I also want a place to occasionally link to a <a href="http://imslp.org/wiki/Tears_(Himpe,_Stefaan)">musical score</a> or <a href="http://www.youtube.com/playlist?list=PL3AD3715AF3FDA13E&feature=plcp">youtube recording</a> I've created.
<h1>Musical instruments I frequently use</h1>
I own a <a href="http://www.google.be/search?q=yamaha+gt2&hl=nl&prmd=imvnsfd&source=lnms&tbm=isch&ei=6ucBT_K3EYKF-wafu_S2AQ&sa=X&oi=mode_link&ct=mode&cd=2&ved=0CBEQ_AUoAQ&biw=1366&bih=583">Yamaha GT2 digital grand piano</a>, which I use because it is easy to record. If I ever win the lottery, I would like to check out the Yamaha Avant N3 which promises a "real piano experience" (whatever that may mean :) )
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCpqS_Gu2Dsf3rLk8rYWWmeFa4-SY3AwZ3NuJl4JwMG1jhNhs5c5rI4RsHbVdk37AQREUzG71gcLGNBYIod3zYkkra7wr1r48rkQHPlh6EsUu0-H67DC0_L4h-5Y-Nh-aRx19UNX8w9MQ/s1600/gt2.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="227" width="222" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCpqS_Gu2Dsf3rLk8rYWWmeFa4-SY3AwZ3NuJl4JwMG1jhNhs5c5rI4RsHbVdk37AQREUzG71gcLGNBYIod3zYkkra7wr1r48rkQHPlh6EsUu0-H67DC0_L4h-5Y-Nh-aRx19UNX8w9MQ/s400/gt2.jpg" /></a></div>
I use someone else's (ahem!) <a href="http://www.google.be/search?q=roland+ra30&hl=nl&prmd=imvns&tbm=isch&tbo=u&source=univ&sa=X&ei=fOMBT4blJoLrOcKI9a4B&ved=0CFoQsAQ&biw=1366&bih=630">Roland RA30</a> for an occasional synth sound.
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg31u-voBOdTZdZID3yPnbaxE8Dn4DCBl8u3-LpNk04ZtcjN7gx5LmERcc1ZNRHkSmRM0eH7mnhAFtKKwv13pXS8hz-Yc4YJ6H0n5y8u8ZAxY8vz71go5Q80TzmNDgkHxg2vjqovv9u-GE/s1600/rolandra30.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="186" width="270" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg31u-voBOdTZdZID3yPnbaxE8Dn4DCBl8u3-LpNk04ZtcjN7gx5LmERcc1ZNRHkSmRM0eH7mnhAFtKKwv13pXS8hz-Yc4YJ6H0n5y8u8ZAxY8vz71go5Q80TzmNDgkHxg2vjqovv9u-GE/s400/rolandra30.jpg" /></a></div>
I've also used software synthesizers like <a href="http://zynaddsubfx.sourceforge.net/">SynAddSubFx</a> or <a href="http://www.csounds.com/">CSound</a>.
I have a <a href="http://www.google.be/search?q=roland+ra30&hl=nl&prmd=imvns&tbm=isch&tbo=u&source=univ&sa=X&ei=fOMBT4blJoLrOcKI9a4B&ved=0CFoQsAQ&biw=1366&bih=630#hl=nl&tbm=isch&sa=1&q=fazer+piano&oq=fazer+piano&aq=f&aqi=g1g-S1&aql=&gs_sm=e&gs_upl=108904l113035l2l113253l21l13l0l3l3l2l160l720l7.2l10l0&bav=on.2,or.r_gc.r_pw.,cf.osb&fp=eabcf8265b0c4ca8&biw=1366&bih=630">fazer acoustic piano</a> but I tend not to use it that often since most of my musical activities are concentrated in the very late (or very early - as you please) hours of the day. Fazer is/was a Finnish brand of piano with a very decent quality for a relatively low price. The factory no longer exists. It was bought by Warner music corporation around 1990 who then miss-managed it until it didn't mean anything anymore.
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4c6fvTNAFbfmOL64n3dioA8nifD4ge-mdGfmyPcxuy2ATYoCfOM0-tCsQWnoWYKQwhHRGnBxVYXGMGcbimfA7F3hMU2ZGkdatELS981CxYyxdtiDE8nUJl9gqy7d29VLimVn3DfdPXsc/s1600/Fazer-Piano-Droit-Instrument-835400512_ML.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="270" width="270" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4c6fvTNAFbfmOL64n3dioA8nifD4ge-mdGfmyPcxuy2ATYoCfOM0-tCsQWnoWYKQwhHRGnBxVYXGMGcbimfA7F3hMU2ZGkdatELS981CxYyxdtiDE8nUJl9gqy7d29VLimVn3DfdPXsc/s400/Fazer-Piano-Droit-Instrument-835400512_ML.jpg" /></a></div>
I record most of my audio on a simple but adequate Roland BOSS BR-600 multitrack recorder.
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQX2dR96F-b_JlXBVczQuP3TraYKMqsdCzOnoH4Kvibipp92y0ksyLXblBfewGt74F7zKuZ2-_0nk7Z4alMLXEqWP_TBh_pyZJQuSD2W93dspN6_PkUTr1DRq55D0bL3l3KMuJhJ01xRc/s1600/br_600_top_main.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="180" width="250" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQX2dR96F-b_JlXBVczQuP3TraYKMqsdCzOnoH4Kvibipp92y0ksyLXblBfewGt74F7zKuZ2-_0nk7Z4alMLXEqWP_TBh_pyZJQuSD2W93dspN6_PkUTr1DRq55D0bL3l3KMuJhJ01xRc/s400/br_600_top_main.jpg" /></a></div>
<h1>Software tools I frequently use</h1>
I have high demands for the tools I use: they must be free ("free" as in "free speech") and open source software, and if possibly
also free ("free" as in "free beer") of cost. Luckily there are many high-quality free and open source music tools. I happen to use the linux operating system that has everything (and much more!) a musician could dream about.
<ul>
<li>Typesetting of scores: using the brilliant <a href="http://lilypond.org/">lilypond</a> program.</li>
<li>Postprocessing of audio: using <a href="http://audacity.sourceforge.net/">audicity</a>.
</ul>
<h1>Musical styles and influences</h1>
I mainly dabble with classical (in a very broad sense) music and I'm not afraid of film, jazz and folk influences. Don't bother talking to me about rock, techno, dance or other similar styles, as I know next to nothing about them and I feel very little motivation to learn more about them. It's not my thing.shiihshttp://www.blogger.com/profile/01738225085577318818noreply@blogger.com1