Zenélgessünk

Ok, szóval tudunk csipogni, hát lássuk, tudunk-e egy Boci-boci tarkát lejátszani! (Nem ismered a dallamot? Itt találod.)

Honnan jönnek a frekvenciák?

A zenei hangokat vagy dó-ré-mi szolmizációs hangokkal, vagy az ABC betűivel jelölik. A Boci-boci első része épp C-D-C-D-E-E hangmagasságokat tartalmaz. (Ha ez nem tiszta eddig, akkor kérj segítséget valakitől, aki járatos a zene elméletében.)

A zenei hangok oktávonként ismétlődnek, azaz A-B-C-D-E-F-G-A-B-C-D-E-F-G-A-B-C-D-E-F-G egyre magasabb hangok egymás után. Azért, hogy tudjuk, hogy melyik oktávon vagyunk, a zenében mondanak olyat, hogy "egyvonalas A" meg "kétvonalas A" meg ilyenek. Az "egyvonalas A" a hangvilla A hangja, ami 440Hz.

A zongora hangjai és az oktávok

A számítógépnek az hogy hány vonalas, meg milyen A hang, az sajnos nem sokat jelent. A számítógépnek a pontos frekvencia kell, ami egy kis matekozással kinyerhető - ugyanis a zenei hangok pont azért tűnnek kellemesnek a fülnek, mert a köztük lévő frekvencia különbsége egy matematikai szabályt követ.

Tehát: az "egyvonalas C" az a negyedik oktávon van, ezért legyen C4, és ennek a frekvenciája 261Hz. Összeszedtem a netről a hangok frekvenciáit:

A3=220
    A#3/Bb3=233
B3=246
C4=261
    C#4/Db4=277
D4=293
    D#4/Eb4=311
E4=329
F4=349
    F#4/Gb4=369
G4=392
    G#4/Ab4=415
A4=440
    A#4/Bb4=466
B4=493
C5=523
    C#5/Db5=554
D5=587
    D#5/Eb5=622
E5=659
F5=698
    F#5/Gb5=739
G5=783
    G#5/Ab5=830
A5=880

A bal oldalon az egész hangok (a zongora fehér billentyűinek a hangja), míg kicsit jobbra a félhangok (a zongora fekete billentyűinek a hangja) található. Alább pedig mindez egyetlen képen: a zongora, a kotta, és a hangmagasságok betűjelei.

A zongora hangjai, a kotta és a hangok

Honnan jön az ütem?

A kotta nem határozza meg pontosan a lejátszás sebességét. Csak azt mondja meg, hogy egy hang alap hosszú (egész), vagy fele akkora (fél), vagy negyed akkora (negyed) hosszú. Ebben a dalban csak negyed hang ("tá") és nyolcad hang ("ti") van. Mondjuk akkor legyen a "tá" 400ms, a "ti" meg 200ms.

Ezek után a dolgunk egyszerű:

void setup() {
    pinMode(9, OUTPUT);
}

void loop() {
    tone(9,261); // 261 az C4
    delay(200);
    tone(9,392); // 392 az G4
    delay(200);
    tone(9,261); // 261 az C4
    delay(200);
    tone(9,392); // 392 az G4
    delay(200);
    tone(9,493); // 493 az B4
    delay(400);
    tone(9,493); // 493 az B4
    delay(400);
}

Hátőő... majdnem jó! A "tar-ka" rész nem két hang, hanem összefolyik. De miért is ne folyna össze, hiszen egymás után két azonos hangot sípolunk, és közben sosem kapcsoljuk ki a csipogót. Igaziból minden hang után kellene egy rövid kis szünet, hogy a hangok elkülönüljenek, és a "tar-ka" is jól hallható legyen.

Akkor ezeket tegyük még bele, tehát:

void setup() {
    pinMode(9, OUTPUT);
}

void loop() {
    tone(9,261);
    delay(200);
    noTone(9);
    delay(50);

    tone(9,392);
    delay(200);
    noTone(9);
    delay(50);

    tone(9,261);
    delay(200);
    noTone(9);
    delay(50);

    tone(9,392);
    delay(200);
    noTone(9);
    delay(50);

    tone(9,493);
    delay(400);
    noTone(9);
    delay(50);

    tone(9,493);
    delay(400);
    noTone(9);
    delay(50);
}

Nos, ez elrettentően ronda lett :) Tudod mit kell csinálni, ha valami csúnyán néz ki a progiban? Be kell csomagolni egy függvénybe!

Láthatóan a tone, delay, noTone, delay dolgokat ismételgettük, csak épp más hangmagassággal és más ütemmel. Csináljunk egy note függvényt (note = zenei hang angolul) ami ezt mind megcsinálja:

void note(int freq,int duration) {
    tone(9,freq);
    delay(duration);
    noTone(9);
    delay(50);
}

A teljes programunk pedig már majdnem korrekt:

void setup() {
    pinMode(9, OUTPUT);
}

void note(int freq,int duration) {
    tone(9,freq);
    delay(duration);
    noTone(9);
    delay(50);
}

void loop() {
    note(261,200);
    note(392,200);
    note(261,200);
    note(392,200);
    note(493,400);
    note(493,400);
}

Feladat: legyen kulturált!

Természetesen sokat segítene, ha konstansokat használnánk a hangmagasság és a hang hosszának megadására. Ekkor a kód egészen olvasható lenne:

void loop() {
    note(TONE_C4,TI);
    note(TONE_G4,TI);
    note(TONE_C4,TI);
    note(TONE_G4,TI);
    note(TONE_B4,TA);
    note(TONE_B4,TA);
}

Tedd bele a progiba a szükséges konstansokat ehhez.

Feladat:

Most már bármit le tudsz játszani. Csinálj:

Ha valamivel megakadtál, kérj segítséget a Facebook csoportban!

Mit tanultunk ebből?

A hangcsinálást - mint minden más macerás dolgot - a legjobb elrejteni egy függvénybe! Utána egészen egyszerű már minden!