Inhaltsverzeichnis

4d2013-01 Listings

Wave Engine (5)

freqtab.fs

\ -------1---------2---------3---------4---------5-----| 
  cr cr ." Last edit: 22feb2013 22:40" cr 
\ ###################################################### 
\ Aus Tonnummer (1...478, entspr. ,,C ... c""") Frequenz 
\ und Phasenschritt berechnen. Die Schrittwerte werden 
\ in Tabellen geladen und dort vom Generator ausgelesen. 
\ ###################################################### 
\ 
\ Ausgehend vom "Kammerton" a' mit 440 Hz ergeben sich 
\ für den tiefsten (Subkontra-)Ton ,,C je nach Stimmung 
\ unterschiedliche Frequenzen: 
\ 
\ Reine Stimmung (Oktaven 1:2 und Quinten 2:3): 
\ Von a' aus 3 Quinten (3/2) und 3 Oktaven (2/1) tiefer: 
\      freq = 440/((3/2)^3*(2/1)^3) = 16,29630 [Hz] 
\ (Nur zum Vergleich, nicht verwendet) 
\ 
\ Fast reine temperierte Stimmung mit 53stel Oktaven: 
\ Von a' aus 40+4*53 = 252 Kommas (2^(1/53)) tiefer: 
\      freq = 440/(2^(1/53))^252 = 16,29822 [Hz] 
\ 
\ Die übliche temperierte Stimmung mit Zwölftel-Oktaven: 
\ Von a' aus 9+4*12 = 57 Halbtöne (2^(1/12)) tiefer: 
\      freq = 440/(2^(1/12))^57 = 16,35160 [Hz] 
\ 
\ Der vom Sinus-Generator benötigte Phasenschritt wird 
\ aus der Frequenz nach folgender Formel berechnet: 
\      step = freq * 2pi / frames/sec [rad (Bogenmaß)] 
\ 
\ Bei einer Auflösung von 44100 frames/sec beträgt der 
\ Phasenschritt für den tiefsten Ton: 
\      step = 16,29822 * 2pi / 44100 = 0,002322103 [rad] 
\ bzw. step = 16,35160 * 2pi / 44100 = 0,002329708 [rad] 
\ 
\ Dasselbe für den höchsten Ton c""", 9 Oktaven höher: 
\      step = 8344,690 * 2pi / 44100 = 1,188917 [rad] 
\ bzw. step = 8372,018 * 2pi / 44100 = 1,192810 [rad] 
\ 
\ ====================================================== 
  2e 1e 53e f/ f**  fconstant 53root2 \ 2^(1/53) Komma 
  2e 1e 12e f/ f**  fconstant 12root2 \ 2^(1/12) Halbton 
          pi 2e f*  fconstant 2pi 
                    fvariable 440Hz 
	                 440e 440Hz f!  \ Stimmgabel 
                    fvariable frames    \ Auflösung 
                       44100e frames f! \ Draft: 11025e 
\ ------------------------------------------------------ 
\ Frequenz des tiefsten Tons der "53er"-Tabelle finden 
: base53  ( r-440Hz -- r-freq)  53root2 252e f** f/ ; 

\ Frequenz eines Tons der "53er"-Tabelle berechnen 
: freq53  ( r-440Hz offs53 -- r-freq) 
       base53 53root2 s>f f** f* ; 
\ ------------------------------------------------------ 
\ Frequenz des tiefsten Tons der "12er"-Tabelle finden 
: base12  ( r-440Hz -- r-freq)  12root2  57e f** f/ ; 

\ Frequenz eines Tons der "12er"-Tabelle berechnen 
: freq12  ( r-440Hz offs12 -- r-freq) 
       base12 12root2 s>f f** f* ; 
\ ------------------------------------------------------ 
\ Aus der Frequenz den Phasenschritt berechnen 
: freq>step  ( r-freq -- r-step)  2pi f* frames f@ f/ ; 

\ Wandlung des "53er"-Offset in den "12er"-Offset 
: shrink  ( offs53 -- offs12)  12 * 22 + 53 / ; 

\ ====================================================== 
\ Tabelle für die "53er"-Temperatur anlegen 
  478   dup constant ftab53-items  \ 9*53 (9 Oktaven) +1 
    8 * dup constant ftab53-size   \ 8-byte-Zellen 
            create   ftab53 allot  \ 3824 bytes 

\ Aus dem Offset Adresse in "53er"-Tabelle berechnen. 
: fadr53  ( offs53 -- addr)  8 * ftab53 + ; 

\ Füllen der Tabelle für die "53er"-Temperatur 
: fill-ftab53  ( r-440Hz --) 
      base53 freq>step \ Anfangston 16,3 Hz 
      ftab53-items                 \ Anzahl Float-Werte 
      0 DO    fdup i fadr53 f!     \ Float-Wert laden 
              53root2 f*           \ 1/53 Oktave höher 
        LOOP  fdrop ; 

\ Per Tonnummer Phasenschritt aus Tabelle ftab53 holen 
: f53@  ( Ton# -- r-step)  1- fadr53 f@ ; 
\ ====================================================== 
\ Tabelle für die "12er"-Temperatur anlegen 
  109   dup constant ftab12-items  \ 9*12 (9 Oktaven) +1 
    8 * dup constant ftab12-size   \ 8-byte-Zellen 
            create   ftab12 allot  \ 872 bytes 

\ Aus dem Offset Adresse in "12er"-Tabelle berechnen. 
: fadr12  ( offs12 -- addr)  8 * ftab12 + ; 

\ Füllen der Tabelle für die "12er"-Temperatur 
: fill-ftab12  ( r-440Hz --) 
      base12 freq>step \ Anfangston 16,3 Hz 
      ftab12-items                 \ Anzahl Float-Werte 
      0 DO    fdup i fadr12 f!     \ Float-Wert laden 
              12root2 f*           \ 1/12 Oktave höher 
        LOOP  fdrop ; 

\ Per Tonnummer Phasenschritt aus Tabelle ftab12 holen 
: f12@  ( Ton# -- r-step)  1- shrink fadr12 f@ ; 
\ ====================================================== 
\ shrink reduziert die (durch die spezielle Syntax sich 
\ ergebenden) 53 Töne pro Oktave auf 12 Töne pro Oktave, 
\ zum Auslesen der kleineren "12er"-Tabelle. 
\ 
\ Syntax  C  B#  C\\ Db/ Db  C#  B## D// Ebb  D C## Eb\\ 
\ Ton#    1   2   3   4   5   6   7   8   9  10  11  12 
\ offs53  0   1   2   3   4   5   6   7   8   9  10  11 
\ offs12  0   0   1   1   1   1   2   2   2   2   2   3 
\ Piano   C ---  Cis ----------   D ---------------  Dis 
\ 
\             Oktave 0       Oktave 1        Oktave 9 
\          ("Subkontra")   ("Kontra")      ("6-gestr.") 
\           Ton#    Offs    Ton#   Offs     Ton#    Offs 
\ C         1-2  ->  0     52-55 -> 12    476-478 -> 108 
\ Cis/Des   3-6  ->  1     56-59 -> 13    -------------- 
\ D         7-11 ->  2     60-64 -> 14 
\ Dis/Es   12-15 ->  3     65-68 -> 15 
\ E        16-20 ->  4     69-73 -> 16 
\ F        21-24 ->  5    -------------- 
\ Fis/Ges  25-29 ->  6    449-453 -> 102 
\ G        30-33 ->  7    454-457 -> 103 
\ Gis/As   34-37 ->  8    458-461 -> 104 
\ A        38-42 ->  9    462-466 -> 105 
\ Ais/B    43-46 -> 10    467-470 -> 106 
\ H        47-51 -> 11    471-475 -> 107 
\ ====================================================== 
    440Hz f@ fill-ftab53
    440Hz f@ fill-ftab12
\ ====================================================== 
0 [if] \ Zum Testen mit "1" einschalten

cr ."   +---------------------------+" 
cr ."   | Die Tabellen sind geladen |" 
cr ."   +---------------------------+"
cr
cr ." Stacks: " .s f.s         \ must be zero
cr
cr ." Beispiele für die Konsole:" 
cr
cr ." 7 set-precision" 
cr
cr ." 440e     base53    f. => 16.29822  Basisfrequenz"
cr ." 440e   0 freq53    f. => 16.29822  Freq Ton #1"
cr ." 440e  53 freq53    f. => 32.59645  Freq Ton #54"
cr ." 440e 477 freq53    f. => 8344.690  Freq Ton #478"
cr ."          ftab53 f@ f. => 0.002322103  Step Ton #1"
cr ."        0 fadr53 f@ f. => 0.002322103  Step Ton #1"
cr ."        1 f53@      f. => 0.002322103  Step Ton #1"
cr ."      477 fadr53 f@ f. => 1.188917  Step Ton #478"
cr ."      478 f53@      f. => 1.188917  Step Ton #478"
cr
cr ." 440e     base12    f. => 16.35160  Basisfrequenz"
cr ." 440e   0 freq12    f. => 16.35160  Freq Ton #1"
cr ." 440e  12 freq12    f. => 32.70320  Freq Ton #13"
cr ." 440e 108 freq12    f. => 8372.018  Freq Ton #109"
cr ."          ftab12 f@ f. => 0.002329708  Step Ton #1"
cr ."        0 fadr53 f@ f. => 0.002329708  Step Ton #1"
cr ."        1 f53@      f. => 0.002329708  Step Ton #1"
cr ."      108 fadr12 f@ f. => 1.192810  Step Ton #478"
cr ."      478 f12@      f. => 1.192810  Step Ton #478"
cr cr

[endif]
\ ====================================================== 

tontabelle.fs

\ -------1---------2---------3---------4---------5-----|
\ Wave Engine: Tabelle der Frequenzen & Phasenschritte
\ Last edit: 07feb2013 13:35 jgt

  7 set-precision  ( kein Einfluss auf f.rdp)

  2e 1e 53e f/ f**  fconstant  2root53  ( "Komma")
  2e 1e 12e f/ f**  fconstant  2root12  ( "Halbton")
          pi 2e f*  fconstant  2pi
              440e  fconstant  440Hz    ( justierbar)

\ Exakt 10-spaltige Float-Ausgabe
\ z.B. 0.00232210 oder 8.344690E3
: fs._  ( r --)  10 8 5 f.rdp ;

\ Frequenz des tiefsten Tons der "53er"-Tabelle finden 
: base53  ( 440Hz -- freq)          \ von 440 Hz aus
       2root53 252e f** f/ ;        \ 252 Kommas tiefer

\ Frequenz des tiefsten Tons der "12er"-Tabelle finden 
: base12  ( 440Hz -- freq)          \ von 440 Hz aus
       2root12  57e f** f/ ;        \ 57 Halbtöne tiefer

\ Frequenz eines Tons aus der "53er"-Tabelle berechnen
: freq53  ( 440Hz offs53 -- freq)   \  (vom tiefsten
       base53 2root53 s>f f** f* ;  \  Ton ausgehend)

\ Frequenz eines Tons aus der "12er"-Tabelle berechnen
: freq12  ( 440Hz offs12 -- freq)   \  (vom tiefsten
       base12 2root12 s>f f** f* ;  \  Ton ausgehend)

\ Aus der Frequenz den Phasenschritt berechnen 
: freq>step  ( freq -- step)
       ( r) 2pi f* 44100e f/ ;

\ Offset für 53stel Oktave => Offset für 12tel Oktave
: shrink  ( n -- addr)  12 * 22 + 53 / ;

\ Wichtigste Tonbezeichnungen ausgeben
: names  ( n --)
        53 mod CASE
                  0 OF ." C   " ENDOF
                  1 OF ." B#  " ENDOF
                  4 OF ." Db  " ENDOF
                  5 OF ." C#  " ENDOF
                  9 OF ." D   " ENDOF
                 13 OF ." Eb  " ENDOF
                 14 OF ." D#  " ENDOF
                 17 OF ." Fb  " ENDOF
                 18 OF ." E   " ENDOF
                 22 OF ." F   " ENDOF
                 23 OF ." E#  " ENDOF
                 26 OF ." Gb  " ENDOF
                 27 OF ." F#  " ENDOF
                 31 OF ." G   " ENDOF
                 35 OF ." Ab  " ENDOF
                 36 OF ." G#  " ENDOF
                 40 OF ." A   " ENDOF
                 44 OF ." Bb  " ENDOF
                 45 OF ." A#  " ENDOF
                 48 OF ." Cb  " ENDOF
                 49 OF ." B   " ENDOF
                       ."     "
        ENDCASE ;

\ Überschrift ausgeben
: head  ( --)
           cr ." Wave Engine: Alle Tonfrequenzen "
              ." (bezogen auf " 440Hz f>s . ." Hz)"
        cr cr ." base53 = 16.29822 Hz  (tiefster Ton)"
           cr ." base12 = 16.35160 Hz  (tiefster Ton)"
        cr cr ." Okt Sym Ton# "
              ."  T53  Frequenz  Phasenschr "
              ."  T12  Frequenz  Phasenschr "
           cr ." ---------------------------------"
              ." ---------------------------------" ;

\ Frequenz und Phasenschritt für "53er" ausgeben
: freq-step-53  ( n --)
           dup    3 .r  space            \ Offset
           440Hz  freq53 fdup fs._       \ Frequenz
           space  freq>step   fs._ ;

\ Frequenz und Phasenschritt für "12er" ausgeben
: freq-step-12  ( n --)
           1+ shrink dup 3 .r  space     \ Offset
           440Hz  freq12 fdup fs._       \ Frequenz
           space  freq>step   fs._ ;

\ Anhalten nach jeder Oktave
: pause  ( n --)
           1+ 53 mod 0=
           IF   cr ." Eine beliebige Taste ..."
                key drop
                24 0 DO 8 ( BS) emit LOOP
                   ."                         "
           THEN ;

\ Programmstart
: go       head
           cr ."   Dauer  -1"
           cr ."   Pause   0"
 478 0 DO  cr
           i 53 /          2 spaces .
           i names                       \ Bezeichnung
           i 1+ 3 .r       3 spaces      \ Ton#

           i freq-step-53  2 spaces      \ 53er
           i freq-step-12                \ 12er

           i pause
       LOOP  cr cr ." Stacks: " .s f.s cr cr bye
; go
\ -----------------------------------------------------|