You're viewing all posts tagged with music

Very simple implementation of Karplus-Strong algorithm in coffeescript

I’m a bit over excited as I just managed to successfully implement Karplus-Strong’s guitar string algorithm.

http://en.wikipedia.org/wiki/Karplus-Strong_string_synthesis

The Wikipedia description was too complicated for me. I had to get the original paper and try to study it. It’s rather old and the terminology was a bit weird, so it took me a while to really understand it.

This snippet assumes you have SRATE defined somewhere (the sample rate), and that you already managed to setup the audio output and the mixer and everything else. I’m using audiodata.js to output audio using Firefox4’s Audio Data API.

The function guitar here returns a function which takes a sample index/point and returns the sample. It assumes that it will be called with all the samples sequentially, otherwise it won’t work. Something like:

signal_fn = guitar(440) # 440 being the frequency we want to sound

point = 0
while not done
    sample = signal_fn(point++)
    # output sample

Not exactly that, but something like that.

Here’s the code:

period_len = (freq) -> Math.floor (SRATE/freq)

avg = (a, b) -> (a + b) / 2

ks_noise_sample = (val) ->
    # get either val or -val with 50% chance
    if Math.random() > 0.5
        val
    else
        -val

# karplus strong algorithm
guitar = (freq) ->
    samples = period_len freq
    table = new Float32Array(samples)
    getsample = (index) ->
        point = index % samples
        if index == point
            table[point] = ks_noise_sample(1)
        else
            prev = (index - 1) % samples
            table[point] = avg(table[point], table[prev])

Note that this is coffee-script, where the last expression in a function is returned, and A = B expressions return B. So, guitar returns the getsample function, and getsample return table[point] after we calculate it.

Here’s what this does:

Fill a table of length p with random values (actually: fill it with either A or -A, with 50% chance each). Where p is the period of the signal, which is the sample_rate/frequency.

To produce samples, just keep cycling on this table. That is, to get any point t, take table[t % p].

BUT, as you loop on the table, average each two adjacent samples. That is, everytime you get table[t] (except the first time around), let table[t] be (table[t] + table[t-1]) / 2.

This causes the signal to decay overtime, or something like that.

That’s it.

What you need to know about music to write a music keyboard app

I only do music as a small hobby on the side. I know almost nothing about western music theory, and I know only very very little tiny bit of middle eastern music theory.

But, I think I know enough to start making a music keyboard application, so I’ll try to pass what I know for anybody who is interested in this kind of thing.

I’ll try to be brief as much as I can.

A really important note: please don’t take my word for anything I will say, I’m pretty much an ignorant in this field, and I only know basic dumbed down stuff. While this model should work in practice, the ideas presented here do not necessarily represent reality, so be warned.

Tones and Frequencies

You know how the piano keyboard has white and black keys? And they have a pattern that repeats? When you press a key, you get a certain “tone”, when you press a different key, you get a different “tone”, and it’s the production of these tones together in sequence that creates melodies.

So:

Each key produces a tone

Each tone has a frequency, and its defined by its frequency. So if you know the frequency of a certain tone, you can generate it.

This is not entirely true of course. We’re ignoring many aspects of the actual sound you hear. You can produce the same tone from a guitar or a piano, and they will sound different, but the tone will be the same. So think of tones as something a bit more abstract than the actual sound you hear.

Tones (in the abstract sense) lie on a linear scale, so we can represent tones using real numbers, and we can talk about the distance between tones.

Take a look at the piano keyboard:

In that picture, I’ve numbered the keys sequentially. The first two white keys are 1 and 3, each has a distinct tone. The distance between these two tones is said to be 1 unit. In other words, we define one unit of tonal distance as the distance between the first two white keys on the piano octave.

In Western notation, the white keys are, in order, are notated by: C D E F G A B

Notice the black key, 2, which lies between 1 and 3. The distance between 1 and 2 is said to be half a tone, and the distance between 2 and 3 is also half a tone.

In other words, on the piano, each two adjacent keys have a distance of 0.5 tone between them (half tones).

Note that #1 and #3 are not adjacent; they are separated by #2. However, #5 and #6 are adjacent; there’s no black note in between them, and so the distance between them is half a tone.

You can also get quarter tones by getting the tone between 1 and 2. The piano has no key to get this tone, but rest assured that it exists. This is a limitation of the piano keyboard; not all instruments suffer this limitation.

Western music only uses half tones, but Middle Eastern music uses quarter tones. This means that there are middle eastern melodies that can’t really be played on the piano because the piano lacks some of the required tones. For instance, this piece on the Rast scale is an example of such a melody (although you can probably approximate it somewhat).

Notice how the pattern on the piano keyboard keeps repeating? These are “octaves”. I don’t know exactly what’s an octave, but you can notice key #1 always produces the same “note” but in higher or lower pitch. When I say “same note”, I don’t really know what I’m talking about, so just take it at face value. Also take it with a grain of salt. It’s not the “same same note”, it’s more like “same note, different octave”. So note #13 is (kinda) the same as note #1 but on a different octave, but they’re still different notes in that one of them has a number #1 and the note has a number #13, and #13 has a higher pitch.

(Note: I’m being rather liberal in my terminology here, I use “tone” to mean “the actual sound you hear”, and “note” as “a way we denote musical tones”. I don’t know if this coincides with the canonical usage of these terms or not).

Tones don’t map to frequencies linearly. The mapping is more, exponential, I suppose. Fortunately there’s a simple mathematical formula that will find the frequency of any given tone.

def freq(n):
      return 440 * pow(2, n/12)

Where n represents the tone in terms of how many half-steps it’s away from the A4 tone. That is the A note, on the fourth octave. A is note #10 in my picture above. But what’s the fourth octave? Well to be honest I don’t know which octave is the first, but it’s all relative and I think you should try to measure it by ear and the whole point is to pick a base to start numbering tones.

The important thing is that this formula allows us to find out the frequency for each key on the piano.

This formula works for arbitrary real numbers, so n could be 1.5, and this is a good thing because it allows us to produce quarter tones and arbitrary microtones.

This is important for me because I actually want to support quarter tones and other microtones, so the application I have in mind will not really work like a piano keyboard. Instead, the interface will be something that allows you to map keys to arbitrary tones, so you can make up your own scale.

If you do some more math, you can adapt the formula above to different units, for example, I think the 12 comes from the fact that we divide each octave to 12 parts, and 440 is just the frequency of A4. You can change these numbers.

Here’s a more generic function:

def freqn(tone, base=440, tpo=12):
     return base * pow(2, float(tone)/tpo)

This allows you to choose an arbitrary base frequency base and divide an octave into an arbitrary number of notes tpo (tones per octave). For example, if you wish you could divide an octave into 6 tones, this way the tone parameter actually represents the tonal distance.

You should note that I made this up, and I suck at math, so do the math yourself and don’t take my word for it (though I’m pretty sure it works).

In theory, producing a musical tone requires only knowing the frequency for the tone. What I mean is, given the frequency of a tone as the only input, a machine can generate (synthesize) the musical tone.

Synthesis

So now you have a mock up of the UI, and you can figure out what frequency to play for each key.

How do you actually produce a sound with that frequency? And how can you make it sound like some specific instrument?

This is something I myself am still experimenting with, so maybe I’ll make another post about it sometime later.

So, for now, the rest is left as an exercise to the reader :P

Scales

This bit is not necessary to create a music keyboard, but it’s something I’m interested in for my particular application.

Let’s go back to the white keys on the piano. Why are they differentiated from black keys? The white keys are mapped to the C Major scale. If you play the white keys in sequence, they sound nice together. If you play all the white keys AND all the black keys, they sound a bit weird. If you replace some white keys with black keys, they may sound nice together.

Don’t ask me why, I don’t know :)

You may notice that different combination of keys have a different sort of feel to them.

I define a scale by two things: a starting point and a series of “tonal distances”.

The C Major scale starts at note C and the distances are: [1, 1, 0.5, 1, 1, 1, 0.5] and then it keeps repeating. (Again, we’re defining 1 tonal distance as the distance between C and D).

The names of the notes C D E F G A B are mapped on the C Major scale. That is, the distance between E and F is 0.5, which is different from the distance between C and D.

If you change the starting point of a scale, but keep the distances, you can still play the same melodies and they will sound pretty much the same.

There are many, many scales. maqamworld provides a decent database of middle eastern scales. For instance, here’s the Rast scale, notice the distances are: [1, 0.75, 0.75, 1, 1, 0.75, 0.75]. That’s why I said earlier that you can’t play it on a piano. If you look closely, it’s very similar to the Major scale. The only difference is the third note and the seventh note.

Major:
   o  -  -  -  o  -  -  -  o  -  o  -  -  -  o  -  -  -  o  -  -  -  o  -  o 

Rast:
   o  -  -  -  o  -  -  o  -  -  o  -  -  -  o  -  -  -  o  -  -  o  -  -  o

تخطيط العود

الطريقة مأخوذة من هذا المنتدى: http://www.saudimusicians.com/vb/showthread.php?t=5475

لتخطيط العود نأخذ اولا طول العود و نقسمه على الرسم السحري 1.059463094 و هو جذر 2 للقوة 12

>>> pow(2, 1/12.0)
1.0594630943592953

انظر: http://en.wikipedia.org/wiki/Twelfth_root_of_two

نتيجة القسمة هي مكان الخط الاول.

ناخذ النتيجة و نقسمها على نفس الرقم .. و نحصل على الخط الثاني.

و لتسهيل العملية لا داعي لان نقوم بهذه الحسابات .. يكفي تشغيل كود يقوم برسم الخطوط بالابعاد الصحيحة، و من ثم نطبع الصورة الناتجة و نستخدمها كمقياس للتخطيط، و لا اسهل من فعل ذلك بصفحة html تحتوي على سكربت صغير يقوم بالعمليات الحسابية، مع اعتبار طول الوتر 60 سانتيمتر.

<p>تخطيط العود</p>
<style type="text/css">
    p { direction: rtl; text-align: center; font: 24pt normal serif; width: 400px; }
    div { float: left; height: 100px; border: solid 1px gray; border-right: none; }
</style>
<script type="text/javascript">
// <div style="width: 3.3cm;">&nbsp;</div>
    var m = 1.059463094; //magic number
    var a = 60;
    var b = a;
    for(var i = 0; i < 8; i++) {
        b = a/m;
        var w = a - b;
        document.write("<div style='width:" + w + "cm;'>&nbsp</div>\n");
        a = b;
    }
</script>

قمت بوضع الكود على github https://gist.github.com/813039

تعديل

قمت بوضع الصفحة على النت و اضفت عليها بعض التطويرات: http://misc.hasenj.org/oud-lines.html

يمكن اختيار طول الوتر و عدد الخطوط اللتي تحتاجها