Hi,
I have some code that contains PLAY statements. I was wondering what the best way is to replace these play statements with similar functionality within FB?
Thanks,
Dave.
Converting QBasic Code with PLAY statements into FreeBasic?
Re: Converting QBasic Code with PLAY statements into FreeBas
Thanks! When I include that code in my application though I get the following error:
Any idea why?SOUND.bas(11) error 56: Illegal specification, at parameter 1 (freq) of Sound()
DECLARE SUB Sound(ByVal freq As Uinteger, dur As Uinteger)
Re: Converting QBasic Code with PLAY statements into FreeBas
it seems that your code uses the symbol name 'freq' anywhere above that declaration. (Check it by a #PRINT TYPEOF(freq) and watch the compiler output; try NAMESPACE to solve the conflict.)
-
- Site Admin
- Posts: 6323
- Joined: Jul 05, 2005 17:32
- Location: Manchester, Lancs
Re: Converting QBasic Code with PLAY statements into FreeBas
Variable names can be reused as parameter names, especially in Declares. I think more likely it's been #defined as something. Doing just '#print freq' might tell you what it is.
One workaround is to simply rename the parameter (e.g. freq_), or to remove it entirely (byval as uinteger), or - equivalently - to multi-line-comment it out (byval /'freq'/ as integer).
Note: if you compile with fbc -w pedantic|-w param, you'll be warned that dur doesn't have an explicit byval/byref. It should probably be 'byval dur as uinteger', unless it was written in an old dialect of FB.
One workaround is to simply rename the parameter (e.g. freq_), or to remove it entirely (byval as uinteger), or - equivalently - to multi-line-comment it out (byval /'freq'/ as integer).
Note: if you compile with fbc -w pedantic|-w param, you'll be warned that dur doesn't have an explicit byval/byref. It should probably be 'byval dur as uinteger', unless it was written in an old dialect of FB.
Re: Converting QBasic Code with PLAY statements into FreeBas
Here's the PLAY sub from JTF link, but with a differend sound sub.
The Sound sub here is only alias "Beep" (one line at top)
It sounds ok though, maybe you'll be able to debug your code more easily.
The Sound sub here is only alias "Beep" (one line at top)
It sounds ok though, maybe you'll be able to debug your code more easily.
Code: Select all
declare sub sound alias "Beep"(freq as uinteger,dur as integer)
SUB Play (Melodie AS STRING)
' Spielen einer Melodie. Subset aus dem PLAY-Befehls von QBASIC.
' Melodie ist ein String aus folgenden Kommandos (Gross- oder Kleinbuchstaben):
' - Tn = Tempo = Anzahl von Viertelnoten pro Minute (n = 32 bis 255,
' Default 120). Beispiel: "T180"
' - On = aktuelle Oktave (n = 0 bis 5). Beispiel: "O3"
' - < = eine Oktave tiefer
' - > eine Oktave hoeher
' - C, D, E, F, G, A, B: Noten in der aktuellen Oktave. Moegliche Suffixe:
' + oder # Erhoehung um einen halben Ton. Beispiel: "C#"
' - Erniedrigung um einen halben Ton. Beispiel: "D-"
' - . = Eineinhalbfache Notenlaenge. Beispiele: "C.", "C+." oder "D-."
' - Ln = Laenge einer Note (n = 1 bis 64, 1 = ganze Note, 2 = halbe Note,
' 4 = Viertelnote usw). Beispiel: "L4". (Individuelle Notenlaengen (Beispiel "C4")
' werden nicht unterstuetzt.)
' - Pn = Laenge einer Pause (n = 1 bis 64, 1 = ganze Pause, 2 = halbe Pause,
' 4 = Viertelpause usw). Beispiel: "P4"
' Beispiel: Alle meine Entchen schwimmen auf dem See
' Play("O3 L8 CDEF L4 GG O3 L8 AAAA L2 G")
'Tonfrequenzen in Hertz:
DIM AS INTEGER C(5) = { 65, 131, 262, 523, 1046, 2093}, _
Cis(5) = { 69, 139, 277, 554, 1109, 2217}, _
D(5) = { 73, 147, 294, 587, 1175, 2349}, _
Dis(5) = { 78, 155, 311, 622, 1244, 2489}, _
E(5) = { 82, 165, 330, 659, 1328, 2637}, _
F(5) = { 87, 175, 349, 698, 1397, 2794}, _
Fis(5) = { 92, 185, 370, 740, 1480, 2960}, _
G(5) = { 98, 196, 392, 784, 1568, 3136}, _
Gis(5) = {104, 208, 415, 831, 1661, 3322}, _
A(5) = {110, 220, 440, 880, 1760, 3520}, _
Ais(5) = {116, 233, 466, 932, 1865, 3729}, _
B(5) = {123, 245, 494, 988, 1975, 3951}
DIM AS STRING s, s1, s2
DIM AS INTEGER k, Wert, Okt, LWert, Tempo, Pause, freq, dur1, dur2, dur
'Default-Werte:
Okt = 3
LWert = 4
Tempo = 120
dur = 60000 / (LWert * Tempo)
dur1 = (7 / 8) * dur
dur2 = dur - dur1
s = TRIM(Melodie)
'Alle Leerzeichen entfernen (repariert Fehleingaben wie "L 16" oder "O 3"):
DO
k = INSTR(s, " ")
s = LEFT(s, k - 1) + RIGHT(s, LEN(s) - k)
LOOP UNTIL k = 0
DO
k = INSTR(s, ANY "OCDEFGABLPTocdefgablpt<>")
'Eventuellen Schrott vorn entfernen (kann durch Formatfehler entstehen,
'z.B. "C32", oder ungueltige Zeichen)
IF k > 1 THEN s = RIGHT(s, LEN(s) - k + 1)
s1 = UCASE(LEFT(s, 1))
s2 = ""
SELECT CASE s1
CASE "T", "L", "P"
k = 0
DO
k = k + 1
s2 = MID(s, 1 + k, 1)
'Wenn s2 eine Ziffer 0 bis 9 ist, an "T" dranhaengen:
IF ASC(s2) >=48 AND ASC(s2) <=57 THEN s1 = s1 + s2
LOOP UNTIL ASC(s2) < 48 OR ASC(s2) > 57
IF LEN(s1) > 1 THEN
Wert = VAL(RIGHT(s1, LEN(s1) - 1))
IF LEFT(s1, 1) = "T" THEN
Tempo = Wert
IF Tempo < 32 THEN Tempo = 32
IF Tempo > 255 THEN Tempo = 255
dur = 4 * 60000 / (LWert * Tempo)
dur1 = (7 / 8) * dur
dur2 = dur - dur1
ELSEIF LEFT(s1, 1) = "L" THEN
LWert = Wert
IF LWert > 64 THEN LWert = 64
IF LWert < 1 THEN LWert = 1
dur = 4 * 60000 / (LWert * Tempo)
dur1 = (7 / 8) * dur
dur2 = dur - dur1
ELSEIF LEFT(s1, 1) = "P" THEN
Pause = Wert
IF Pause > 64 THEN Pause = 64
IF Pause < 1 THEN Pause = 1
'Pause spielen:
SLEEP 4 * 60000 / (Pause * Tempo)
END IF
END IF
CASE "O"
s2 = MID(s, 2, 1)
IF ASC(s2) >=48 AND ASC(s2) <=57 THEN
s1 = s1 + s2
Okt = VAL(s2)
IF Okt < 0 THEN Okt = 0
IF Okt > 5 THEN Okt = 5
END IF
CASE ">"
IF Okt < 5 THEN Okt = Okt + 1
CASE "<"
IF Okt > 0 THEN Okt = Okt - 1
CASE "C", "D", "E", "F", "G", "A", "B"
s2 = MID(s, 2, 1)
IF s2 = "+" OR s2 = "#" THEN
SELECT CASE s1
CASE "C": freq = Cis(Okt)
CASE "D": freq = Dis(Okt)
CASE "E": freq = F(Okt)
CASE "F": freq = Fis(Okt)
CASE "G": freq = Gis(Okt)
CASE "A": freq = Ais(Okt)
CASE "B": IF Okt < 5 THEN freq = C(Okt + 1)
END SELECT
s1 = s1 + s2
ELSEIF s2 = "-" THEN
SELECT CASE s1
CASE "C": IF Okt > 0 THEN freq = B(Okt - 1)
CASE "D": freq = Cis(Okt)
CASE "E": freq = Dis(Okt)
CASE "G": freq = Fis(Okt)
CASE "A": freq = Gis(Okt)
CASE "B": freq = Ais(Okt)
END SELECT
s1 = s1 + s2
ELSE
SELECT CASE s1
CASE "C": freq = C(Okt)
CASE "D": freq = D(Okt)
CASE "E": freq = E(Okt)
CASE "F": freq = F(Okt)
CASE "G": freq = G(Okt)
CASE "A": freq = A(Okt)
CASE "B": freq = B(Okt)
END SELECT
END IF
IF s2 = "." OR MID(s, 3, 1) = "." THEN
'Ton spielen:
Sound(freq, 1.5 * dur1)
SLEEP 1.5 * dur2
s1 = s1 + "."
ELSE
'Ton spielen:
Sound(freq, dur1)
SLEEP dur2
END IF
END SELECT
'Ausgewerteten Teil des Strings s vorn abtrennen:
s = TRIM(s)
s = RIGHT(s, LEN(s) - LEN(s1))
LOOP UNTIL LEN(s) = 0
END SUB
'+++++++++++++++++++++++++++++++++++++++++++++++++++++
'TEST
dim as single t1, t2
dim as integer i
PRINT "Test der Sound-Funktion: Langsame Tonleiter, C3 bis C4"
t1 = timer
Sound(523, 500) 'C3
Sound(587, 500) 'D3
Sound(659, 500) 'E3
Sound(698, 500) 'F3
Sound(784, 500) 'G3
Sound(880, 500) 'A3
Sound(988, 500) 'B3
Sound(1046, 500) 'C4
t2 = timer
PRINT "Dauer (Soll: 4 Sekunden): "; t2 - t1
PRINT
PRINT "Test der PLAY-Funktion, Tonleiter C4 bis C5:"
Play("T130 L4 O4 CDEFG AB O5 C")
PRINT
PRINT "Und nun ein kleines Liedchen:"
PRINT "Alle meine Entchen"
Play("O3 L8 CDEF L4 GG")
FOR i = 1 TO 2
PRINT "schwimmen auf dem See"
Play("O3 L8 AAAA L2 G")
NEXT i
PRINT "Koepfchen in das Wasser, Schwaenzchen in die Hoeh"
Play("O3 L8 FFFF L4 EE L8 DDDDC")
sleep