Programma di esempio PCTUNE.PRT |
; PCTUNE
;
; Programma per Proteus
;
; (C) 2003 Simone Zanella Productions
;
; Questo programma suona una melodia in formato RTTTL attraverso lo speaker del PC.
; Limitazioni:
; - non è supportato il volume.
#!proteus -z
IF LT(ARGC, 5)
CONSOLELN "Sintassi: " ARGV(1) " " ARGV(2) " [melodia_rtttl]"
CONSOLELN ""
CONSOLELN "Questo programma suona una melodia in formato RTTTL\n" \
"attraverso lo speaker del PC."
CONSOLELN ""
CONSOLELN "Limitazioni:"
CONSOLELN "- non e' supportato il volume.\n"
S = "ColonelBogeyf:d=4,o=5,b=140:8g,8e,p,8p,8e,8f,8g,e6,e6,2c6,8g,8e,p,8p,8e,8f,8e,g,g,2f,8f,8d,p,8p,8d,8e,8f,8g,8e,p,8p,8e,8f#,8e,8d,8g,8p,8e,8f#,8d,8p,8a,8g.,16f#,8g,8a,8g,8f#,8e,8d,8g,8e,p,8p,8e,8f,8g,e6,e6,2c6,8g,8e,p,8p,8e,8f,8e,g,g,2f,8f,8d,p,8p,8a,8b,8a,8c6,8g,p,8p,8g,8f,8e,8d,8a,8p,8c,8b4,8g,8p,8b4,2c.,p"
ELSE
S = ARGV(5)
FI
Note = VECCREATE(2, 3, 5, 7, 8, 10)
P = STRSTR(S, ":")
Titolo = LEFT(S, DEC(P))
S = RESTFROM(S, INC(P))
P = STRSTR(S, ":")
Defaults = LEFT(S, DEC(P))
S = RESTFROM(S, INC(P))
CONSOLELN "// RTTTL: " Titolo
DefDuration = 4
DefScale = "5"
DefBeatSpm = 63
; Non implementato
DefVolume = 7
; Implementato attraverso una leggera diminuzione del tempo nota
DefStyle = 1
; Volume
; 5 = scale
; 63 = beats-per-minute
; 7 = volume
; 1 = style
T2 = TOKNEW(Defaults, ",")
FOR X = 1 TO TOKNUM(T2)
SWITCH LEFT(TOKGET(T2, X), 1) STRIEQ
ON "D"
; Durata di default
DefDuration = RESTFROM(TOKGET(T2, X), 3)
ON "O"
; Ottava di default
DefScale = RESTFROM(TOKGET(T2, X), 3)
ON "B"
; Numero di note per minuto
DefBeatSpm = RESTFROM(TOKGET(T2, X), 3)
ON "V"
; Volume di default
DefVolume = RESTFROM(TOKGET(T2, X), 3)
ON "S"
; Stile di default
DefStyle = RESTFROM(TOKGET(T2, X), 3)
OFF
NEXT
; Durata di una battuta (in millisecondi)
Battuta = FDIV(60000, DefBeatSpm)
CONSOLELN "// DefDuration = " DefDuration
CONSOLELN "// DefScale = " DefScale
CONSOLELN "// DefBeatSpm = " DefBeatSpm
CONSOLELN "// DefVolume = " DefVolume
CONSOLELN "// DefStyle = " DefStyle
TOKFREE(T2)
T2 = TOKNEW(S, ",")
C = 1
FOR X = 1 TO TOKNUM(T2)
Nota = TOKGET(T2, X)
Durata = ""
Y = 0
WHILE ISDIGIT(SUBSTR(Nota, INC(Y), 1))
INC(@Y)
LOOP
IF Y
Durata = LEFT(Nota, Y)
ELSE
Durata = DefDuration
FI
Nota = RESTFROM(Nota, INC(Y))
PNota = LEFT(Nota, 1)
IF STREQ(SUBSTR(Nota, 2, 1), "#")
PNota = PNota "#"
Nota = RESTFROM(Nota, 3)
ELSE
Nota = RESTFROM(Nota, 2)
FI
PNota = UPPER(PNota)
IF ISNOTEMPTY(Nota)
C1 = LEFT(Nota, 1)
C2 = SUBSTR(Nota, 2, 1)
IF AND(ISNOTEMPTY(C1), ISDIGIT(C1))
Scala = C1
Special = C2
ELSE
IF AND(ISNOTEMPTY(C2), ISDIGIT(C2))
Scala = C2
Special = C1
ELSE
Special = Nota
Scala = DefScale
FI
FI
ELSE
Scala = DefScale
Special = ""
FI
SuonaNota(PNota, Durata, Scala, Special, Battuta, C)
INC(@C)
NEXT
TOKFREE(T2)
ABORT 0
FUNCTION SuonaNota(nota, durata, scala, special, battuta, c)
d = FDIV(1, durata)
SWITCH special STREQ
ON "."
d = ADD(d, FDIV(d, 2))
ON ","
d = ADD(d, FDIV(d, 2), FDIV(d, 4))
ON "&"
d = FDIV(MUL(d, 2), 3)
OFF
SWITCH _DefStyle EQ
ON 1
; Normale = 90%
d = FDIV(MUL(d, 100), 90)
ON 2
; Continuo = 100%
ON 3
; Staccato = 70%
d = FDIV(MUL(d, 100), 70)
OFF
d = INT(MUL(battuta, d))
IF STRNEQ(LEFT(nota, 1), "P")
; Note: A-G
; A4 = 440
; A5 = 880
; A6 = 1760
; A7 = 3520
IF IN(LEFT(nota, 1), "AB")
INC(@scala)
FI
SWITCH scala EQ
ON 4
basefreq = 440
ON 5
basefreq = 880
ON 6
basefreq = 1760
ON 7
basefreq = 3520
OFF
C3 = SUB(ASC(LEFT(nota, 1)), ASC("A"))
IF C3
basefreq = MUL(basefreq, POW(2, FDIV(VECGET(_Note, C3), 12)))
FI
IF STREQ(RIGHT(nota, 1), "#")
basefreq = MUL(basefreq, POW(2, FDIV(1, 12)))
FI
basefreq = INT(basefreq)
BEEP(basefreq, d)
SLEEP(FDIV(d, 1000))
FI
RETURN
!bdoc
Here it is, in theory, for modern tunings:
A above Middle C is 440 Hz
to get the note 1 halfstep above, multiply by 2 ^ 1/12 (that's
2 to the 1/12 power, also known as the "twelfth
root of two)
So A# would be 440 * 1.059463094 or about
466.153 Hz.
Octaves are easy, they're just double the frequency,
so the A the octave above A440 would be 880.
(This is the same as multiplying by 2 ^ 12/12).
I'll leave it as an exercise for you to do the math and come
up with all your frequencies.
An interesting aside: Pianos are tuned slightly off! Depending
on how short your piano is, the higher notes are tuned slightly
sharp and the lower notes are tuned slightly flat. This will make
it sound more in tune--because of physical characteristics of the
string and the harmonics it generates, than it would if it were
in perfect tune.
!edoc