Gyakorlati alapok

Csak temperáltan a temperált hangokkal!

 

A Pénzes-féle Gitáriskola egyik fontos zeneelméleti csomagja a temperált hangrendszer zenetörténeti előzményeit ismerteti, valamint részletesen analizálja, majd fel is vázolja a rendszer összes zenei hangját. Ennek megértése legalább középszintű zeneelméleti ismereteket igényel, amely magyarázatok kellő részletességgel elérhetők a linkelt honlapokon.

 

Itt és most gyártunk egy olyan algoritmust, amelyik pontosan kiszámolja a rendszer összes zenei hangjának frekvenciáját.

 

www.informatika-programozas.hu - Ezt most meg kell tanulni!

 

Kis zeneelméleti előzmény: a ma leginkább használatos zenei, az úgynevezett temperált hangrendszer összes zenei hangja matematikailag van kiszámolva. Ehhez egyetlen kiindulópontra van szükségünk, a normál zenei A hangra, mint kezdőértékre: ez 1939 óta 440 Hz, valamint a temperálás képletére, amelyre a legenda szerint először egy Andreas Werckmeister nevű német orgonista és zeneteoretikus (1645-1706) tett (megjegyzem: többféle) javaslatot. Egyik képlete azt javasolta, hogy osszuk fel az A hang oktávjai közötti frekvenciatartományt 12 egyenlően elosztott zenei hangra. A képlet a következő volt:

 

www.informatika-programozas.hu

 

A képlet eredménye voltaképpen egy földi giliszta hosszúságú tizedes tört, amely számtani sorozat formájában az A oktávhangok közti frekvenciatartományt egyszerű hozzászorzással 12 egyenlő részre osztja.

 

További segédletként nézzük meg az A oktávok frekvenciáit:

 

(13,75) ← 27,5 ← 55 ← 110 ← 220 ← 440 → 880 → 1760 → 3520 → (7040)
 

A 2 szélső, zárójelbe tett érték csak elméleti megközelítés, mert a zenei rendszer már nem tudja felhasználni (túl mély és túl magas hangzása miatt). A temperált hangrendszer legalsó hangját az orgona adja 16,35 Hz rezgésszámmal (C0), legmagasabbat pedig a pikoló 4698,63 Hz rezgésszámmal (D8). Mivel a teljesség igényével lépünk fel, megmutatunk ennél alacsonyabb, illetve magasabb hangokat is.

 

Először megírjuk a program 1. részét, amely eltárolja az A hangok frekvenciaértékeit. Mivel azonos típusú változóértékekről van szó, érdemes ezeket tárolóegységbe, például egy tömbbe pakolni. A tömb típusát -mivel előreláthatóan velük sok szorzást és gyökvonást fogunk elkövetni-, érdemes double típusra állítani.

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

public class Main {
    public static void main(String[] args) {
    double hangA = 440;
    for(int i = 0; i <= 4; i++){
        hangA /= 2;
    }
    double[] hangATomb = new double[10];
    System.out.print("Zenei 'A' hangok: ");
    for(int i = 0; i <= 10; i++){
        hangATomb[i] = hangA;
        hangA *= 2;
        System.out.print(hangATomb[i] + " ");
        }
    }
}

 

Végeredmény:

Zenei 'A' hangok: 27.5, 55.0, 110.0, 220.0, 440.0, 880.0, 1760.0, 3520.0, 7040.0,

 

Mivel meg kell találnunk a zeneileg felhasználható hang alatti A hangot (13.75 Hz), 440 Hz-ből kiindulva (double hangA = 440;) egy for ciklus felhasználásával az 5. osztás fogja nekünk szolgáltatni ezt az értéket (hangA /= 2;). Ez lesz a hangATomb 1. eleme a 0. indexen. Egy újabb for ciklus segítségével innen szorzunk felfelé tízszer (hangA *= 2;), hogy megkapjuk és egyúttal eltároljuk mind a 10 A hangot.

 

Ezután kell aktiválnunk és implementálnunk a temperálás már említett képletét. Az n-edik gyökvonásról már volt szó a Hatványozódjunk és ne vonakodjunk gyökét vonni! című fejezetben. Bevezetésképpen ide másolom az n-edik gyökvonás példakódját:

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

import java.math.*;

public class Main {
    public static void main(String[] args) {
    double gyokkitevo = 5;
    double szam = 3125;
    System.out.println(Math.pow(szam, 1/gyokkitevo)); //Végeredmény: 5.0
    }
}

 

A kódban tehát kis trükközést láthatunk, mert valójában a hatványozó függvénnyel és a gyökkitevő reciprokával számolunk (Math.pow(szam, 1/gyokkitevo)). Ezt fogjuk felhasználni a jelen számításokhoz is, eredményét pedig a double típusú eredmeny nevű változóban tároljuk (double eredmeny = Math.pow(2, 1/gyokkitevo);).

 

A zenei hangok kiszámítását 2 db egymásba ágyazott (nested) for ciklus fogja nekünk megoldani. A főciklus szolgáltatja az A hangokat (hangATomb[i]), ahonnan egyszerű felfelé szorzásokkal számítjuk ki (hang *= eredmeny;) és rögtön írjuk is ki a konkrét hangfrekvenciákat. A belső ciklusnak csak 11 lépése lesz (noha 12 hangot keresünk, int i = 0; i <= 10; i++), hiszen a 12. hang már egy oktávval magasabban lévő A hang és ezt külön tömbből vesszük.

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

import java.math.*;

public class Main {
    public static void main(String[] args) {
    double hangA = 440;
    for(int i = 0; i <= 4; i++){
        hangA /= 2;
    }
    double[] hangATomb = new double[10];
    System.out.print("Zenei 'A' hangok: \n");
    for(int i = 0; i <= 9; i++){
        hangATomb[i] = hangA;
        hangA *= 2;
        System.out.print(hangATomb[i] + ", ");
    }

    System.out.println();

    double gyokkitevo = 12;
    double eredmeny = Math.pow(2, 1/gyokkitevo);
    System.out.println("\nA temperálás képletének állandó értéke: \n" + eredmeny);
    for(int i = 0; i < 9; i++){
        double hang = hangATomb[i];
        System.out.println("\n" + hangATomb[i] + " és "

                                    + hangATomb[i+1] + " Hz-es 'A' hangok között:");
        for(int j = 0; j <= 10; j++){
            hang *= eredmeny;
            System.out.println(hang);
            }
        }
    }
}

 

Végeredmény:

Zenei 'A' hangok:
13.75, 27.5, 55.0, 110.0, 220.0, 440.0, 880.0, 1760.0, 3520.0, 7040.0,

A temperálás képletének állandó értéke:
1.0594630943592953

13.75 és 27.5 Hz-es 'A' hangok között:
14.56761754744031
15.433853164253879
16.351597831287418
17.32391443605451
18.354047994837977
19.44543648263006
20.601722307054377
21.82676446456275
23.124651419477157
24.49971474885934
25.95654359874658

27.5 és 55.0 Hz-es 'A' hangok között:
29.13523509488062
30.867706328507758
32.703195662574835
34.64782887210902
36.708095989675954
38.89087296526012
41.203444614108754
43.6535289291255
46.249302838954314
48.99942949771868
51.91308719749316

55.0 és 110.0 Hz-es 'A' hangok között:
58.27047018976124
61.735412657015516
65.40639132514967
69.29565774421803
73.41619197935191
77.78174593052024
82.40688922821751
87.307057858251
92.49860567790863
97.99885899543736
103.82617439498632

110.0 és 220.0 Hz-es 'A' hangok között:
116.54094037952248
123.47082531403103
130.81278265029934
138.59131548843607
146.83238395870382
155.5634918610405
164.81377845643502
174.614115716502
184.99721135581726
195.99771799087472
207.65234878997265

220.0 és 440.0 Hz-es 'A' hangok között:
233.08188075904496
246.94165062806206
261.6255653005987
277.18263097687213
293.66476791740763
311.126983722081
329.62755691287003
349.228231433004
369.9944227116345
391.99543598174944
415.3046975799453

440.0 és 880.0 Hz-es 'A' hangok között:
466.1637615180899
493.8833012561241
523.2511306011974
554.3652619537443
587.3295358348153
622.253967444162
659.2551138257401
698.456462866008
739.988845423269
783.9908719634989
830.6093951598906

880.0 és 1760.0 Hz-es 'A' hangok között:
932.3275230361799
987.7666025122483
1046.5022612023947
1108.7305239074885
1174.6590716696305
1244.507934888324
1318.5102276514801
1396.912925732016
1479.977690846538
1567.9817439269978
1661.2187903197812

1760.0 és 3520.0 Hz-es 'A' hangok között:
1864.6550460723597
1975.5332050244965
2093.0045224047894
2217.461047814977
2349.318143339261
2489.015869776648
2637.0204553029603
2793.825851464032
2959.955381693076
3135.9634878539955
3322.4375806395624

3520.0 és 7040.0 Hz-es 'A' hangok között:
3729.3100921447194
3951.066410048993
4186.009044809579
4434.922095629954
4698.636286678522
4978.031739553296
5274.0409106059205
5587.651702928064
5919.910763386152
6271.926975707991
6644.875161279125

 

Ezek nagyon fontos értékek a zenészek, főként a hangszerészek számára.

 

A kódot még kissé tovább tudjuk szépíteni: írja ki a hangfrekvenciához tartozó konkrét hangneveket is. Mivel a hangnevek állandók és oktávonként ismétlődnek, érdemes őket egy könnyen elérhető, stabil tárolótömbbe tenni, ez lesz a String típusú hangNev nevű tömb. Mivel adott pozícióban mindig ugyanarra a hangnévre van szükségünk, célszerű a következő deklarációt implementálnunk:

 

String [] hangNev = new String [12];
{
    hangNev[0] = "Aisz/B";
    hangNev[1] = "H";
    hangNev[2] = "C";
    hangNev[3] = "Cisz/Desz";
    hangNev[4] = "D";
    hangNev[5] = "Disz/Esz";
    hangNev[6] = "E";
    hangNev[7] = "F";
    hangNev[8] = "Fisz/Gesz";
    hangNev[9] = "G";
    hangNev[10] = "Gisz/Asz";
}

 

A standard értékű hangNev tömb elérését a belső ciklus léptetőjéhez kell igazítanunk (hangNev[j]), majd a frekvenciákkal együtt kiírni:

 

System.out.println(hang + " (" + hangNev[j] + ")");

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

import java.math.*;

public class Main {
    public static void main(String[] args) {

    String [] hangNev = new String [12];
    {
        hangNev[0] = "Aisz/B";
        hangNev[1] = "H";
        hangNev[2] = "C";
        hangNev[3] = "Cisz/Desz";
        hangNev[4] = "D";
        hangNev[5] = "Disz/Esz";
        hangNev[6] = "E";
        hangNev[7] = "F";
        hangNev[8] = "Fisz/Gesz";
        hangNev[9] = "G";
        hangNev[10] = "Gisz/Asz";
    }


    double hangA = 440;
    for(int i = 0; i <= 4; i++){
        hangA /= 2;
    }
    double[] hangATomb = new double[10];
    System.out.print("Zenei 'A' hangok: \n");
    for(int i = 0; i <= 9; i++){
        hangATomb[i] = hangA;
        hangA *= 2;
        System.out.print(hangATomb[i] + ", ");
    }

    System.out.println();

    double gyokkitevo = 12;
    double eredmeny = Math.pow(2, 1/gyokkitevo);
    System.out.println("\nA temperálás képletének állandó értéke: \n" + eredmeny);
    for(int i = 0; i < 9; i++){
        double hang = hangATomb[i];
        System.out.println("\n" + hangATomb[i] + " és "

                                    + hangATomb[i+1] + " Hz-es 'A' hangok között:");
        for(int j = 0; j <= 10; j++){
            hang *= eredmeny;
            System.out.println(hang + " (" + hangNev[j] + ")");
            }
        }
    }
}

 

Végeredmény:

Zenei 'A' hangok:
13.75, 27.5, 55.0, 110.0, 220.0, 440.0, 880.0, 1760.0, 3520.0, 7040.0,

A temperálás képletének állandó értéke:
1.0594630943592953

13.75 és 27.5 Hz-es 'A' hangok között:
14.56761754744031 (Aisz/B)
15.433853164253879 (H)
16.351597831287418 (C)
17.32391443605451 (Cisz/Desz)
18.354047994837977 (D)
19.44543648263006 (Disz/Esz)
20.601722307054377 (E)
21.82676446456275 (F)
23.124651419477157 (Fisz/Gesz)
24.49971474885934 (G)
25.95654359874658 (Gisz/Asz)

27.5 és 55.0 Hz-es 'A' hangok között:
29.13523509488062 (Aisz/B)
30.867706328507758 (H)
32.703195662574835 (C)
34.64782887210902 (Cisz/Desz)
36.708095989675954 (D)
38.89087296526012 (Disz/Esz)
41.203444614108754 (E)
43.6535289291255 (F)
46.249302838954314 (Fisz/Gesz)
48.99942949771868 (G)
51.91308719749316 (Gisz/Asz)

55.0 és 110.0 Hz-es 'A' hangok között:
58.27047018976124 (Aisz/B)
61.735412657015516 (H)
65.40639132514967 (C)
69.29565774421803 (Cisz/Desz)
73.41619197935191 (D)
77.78174593052024 (Disz/Esz)
82.40688922821751 (E)
87.307057858251 (F)
92.49860567790863 (Fisz/Gesz)
97.99885899543736 (G)
103.82617439498632 (Gisz/Asz)

110.0 és 220.0 Hz-es 'A' hangok között:
116.54094037952248 (Aisz/B)
123.47082531403103 (H)
130.81278265029934 (C)
138.59131548843607 (Cisz/Desz)
146.83238395870382 (D)
155.5634918610405 (Disz/Esz)
164.81377845643502 (E)
174.614115716502 (F)
184.99721135581726 (Fisz/Gesz)
195.99771799087472 (G)
207.65234878997265 (Gisz/Asz)

220.0 és 440.0 Hz-es 'A' hangok között:
233.08188075904496 (Aisz/B)
246.94165062806206 (H)
261.6255653005987 (C)
277.18263097687213 (Cisz/Desz)
293.66476791740763 (D)
311.126983722081 (Disz/Esz)
329.62755691287003 (E)
349.228231433004 (F)
369.9944227116345 (Fisz/Gesz)
391.99543598174944 (G)
415.3046975799453 (Gisz/Asz)

440.0 és 880.0 Hz-es 'A' hangok között:
466.1637615180899 (Aisz/B)
493.8833012561241 (H)
523.2511306011974 (C)
554.3652619537443 (Cisz/Desz)
587.3295358348153 (D)
622.253967444162 (Disz/Esz)
659.2551138257401 (E)
698.456462866008 (F)
739.988845423269 (Fisz/Gesz)
783.9908719634989 (G)
830.6093951598906 (Gisz/Asz)

880.0 és 1760.0 Hz-es 'A' hangok között:
932.3275230361799 (Aisz/B)
987.7666025122483 (H)
1046.5022612023947 (C)
1108.7305239074885 (Cisz/Desz)
1174.6590716696305 (D)
1244.507934888324 (Disz/Esz)
1318.5102276514801 (E)
1396.912925732016 (F)
1479.977690846538 (Fisz/Gesz)
1567.9817439269978 (G)
1661.2187903197812 (Gisz/Asz)

1760.0 és 3520.0 Hz-es 'A' hangok között:
1864.6550460723597 (Aisz/B)
1975.5332050244965 (H)
2093.0045224047894 (C)
2217.461047814977 (Cisz/Desz)
2349.318143339261 (D)
2489.015869776648 (Disz/Esz)
2637.0204553029603 (E)
2793.825851464032 (F)
2959.955381693076 (Fisz/Gesz)
3135.9634878539955 (G)
3322.4375806395624 (Gisz/Asz)

3520.0 és 7040.0 Hz-es 'A' hangok között:
3729.3100921447194 (Aisz/B)
3951.066410048993 (H)
4186.009044809579 (C)
4434.922095629954 (Cisz/Desz)
4698.636286678522 (D)
4978.031739553296 (Disz/Esz)
5274.0409106059205 (E)
5587.651702928064 (F)
5919.910763386152 (Fisz/Gesz)
6271.926975707991 (G)
6644.875161279125 (Gisz/Asz)