Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Musikprojekt

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu QBasic.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
monster_beep



Anmeldungsdatum: 08.05.2005
Beiträge: 11

BeitragVerfasst am: 01.06.2005, 20:21    Titel: Musikprojekt Antworten mit Zitat

Hallo Leute! Ich arbeite immer noch an meinem Synthesizerprojekt und hab mal wieder ein paar knifflige Fragen. Hier erstmal der aktuelle Quelltext:

DECLARE FUNCTION converter$ (x$)
CLS
SLEEP 1
PRINT ":MONSTER BEEP:"
PRINT " < digital synth >"
PRINT
PRINT "version 1.0"
PRINT "m. s. 2005"
PRINT
PRINT
PRINT "CONTROLS"
PRINT "play: < a y s x c f v g b h n m"
PRINT "quit: q"
PRINT
SLEEP 1
PRINT "--------------------------------------------------------------------------------"
PRINT "messages:"
DO WHILE i$ <> "q"
i$ = INPUT$(1)
i$ = LCASE$(i$)
IF i$ <> "q" THEN
IF INSTR("<aysxcfvgbhnm", i$) THEN
i$ = converter$(i$)
PLAY "l 16"
PLAY i$
ELSE
PRINT "error: unknown key"
END IF
END IF
LOOP
PRINT "monster beep has been killed..."
SLEEP 2
CLS
SYSTEM

FUNCTION converter$ (x$)
SELECT CASE x$
CASE IS = "<"
converter$ = "c"
CASE IS = "a"
converter$ = "c+"
CASE IS = "y"
converter$ = "d"
CASE IS = "s"
converter$ = "d+"
CASE IS = "x"
converter$ = "e"
CASE IS = "c"
converter$ = "f"
CASE IS = "f"
converter$ = "f+"
CASE IS = "v"
converter$ = "g"
CASE IS = "g"
converter$ = "g+"
CASE IS = "b"
converter$ = "a"
CASE IS = "h"
converter$ = "a+"
CASE IS = "n"
converter$ = "b"
CASE IS = "m"
converter$ = "o5 c o4"
END SELECT
END FUNCTION

Nun zu den Fragen:

1.
Also momentan ist es so, dass wen man eine Taste im Bereichder möglichen Töne drückt, der Ton in einer bestimmten, von mir festgelegten Länge gespielt wird. Dabei ist es egal, ob ich in der Zwischezeit schon einen anderen drücke. Der wird dann nachgeschoben.
Ich hätte es aber gerne so, dass die PLAY – Anweisung abgebrochen wird und die DO - WHILE - Schleife von neuem beginnt, wenn man eine andere Taste drückt. Das Problem dabei ist, dass es momentan so aussieht, dass in der Schleife immer erst gewartet wird, bis der nächste Ton eingegeben wird. Man müsste die Taste also zweimal drücken.
Würde ich die Warteanweiung auf die nächste Eingabe außerhalb der Schleife setzen, würde das ganze in einer Endlosschleife münden, weil die Abbruchbedingung nie erfüllt wird.
Wie könnte man das also anstellen?

2.
In der Funktion converter habe ich momentan noch die Bezeichnungen der Töne für die einzelnen Tasten verwendet. Ich würde aber anstatt der PLAY – Anweisung gerne die Anweisung SOUND benutzen. Da gibt man dann Frequenzen ein. Das Problem ist jetzt: Welche Frequenz ist welche Tonbezeichnung. Wenn ich zum Beispiel das C in der ersten Oktave bei der PLAY – Anweisung spielen will, dann geb ich PLAY „o1 c“ ein. Aber welcher Soundfrequenz entspricht das? Gibt es da eine Aufschlüsselung von PLAY zu SOUND oder andersrum?
Jetz mag man sich fragen, warum ich denn das mit SOUND mache möchte. Nun ja, das ist nicht so statisch und festgelegt wie PLAY. Da kann man zum Beispiel auch mit kleineren Tonschrittenals mit Halbtönen arbeiten und so.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
jb



Anmeldungsdatum: 14.01.2005
Beiträge: 2010

BeitragVerfasst am: 01.06.2005, 20:43    Titel: Antworten mit Zitat

Zu deiner ersten Frage: Da müsste man wissen, wie lange ein Schleifendurchlauf dauert,
und dann die Tonabspielzeit mit SOUND halt so lange machen.

Da die Abspieldauer bei SOUND aber nicht in ms angegeben wird, würde ich dir
DIRSOUND.BAS aus der MonsterFAQ empfehlen, bei der das der Fall ist.

Zu deiner 2. Frage:

C: ~261 Hz
D: ~294 Hz
E: ~330 Hz
F: ~349 Hz
G: ~393 Hz
A: ~440 Hz
H: ~494 Hz
C: ~523 Hz

jb
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
MisterD



Anmeldungsdatum: 10.09.2004
Beiträge: 3071
Wohnort: bei Darmstadt

BeitragVerfasst am: 01.06.2005, 20:53    Titel: Antworten mit Zitat

Frequenzen bestimmen geht einfacher so:

ausgangston a = 440 hz
dann kann man die frequenz so berechnen:

440*2^(halbtonschritte/12)

ein C wäre zB dann a -> c = 3 hts -> 440*2^(3/12) =~532,25
_________________
"It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
monster_beep



Anmeldungsdatum: 08.05.2005
Beiträge: 11

BeitragVerfasst am: 04.06.2005, 14:18    Titel: Antworten mit Zitat

jb hat Folgendes geschrieben:
Zu deiner ersten Frage: Da müsste man wissen, wie lange ein Schleifendurchlauf dauert,
und dann die Tonabspielzeit mit SOUND halt so lange machen.

Da die Abspieldauer bei SOUND aber nicht in ms angegeben wird, würde ich dir
DIRSOUND.BAS aus der MonsterFAQ empfehlen, bei der das der Fall ist.


Aber was nützt es zu wissen, wie lange ein Schleifendurchlauf dauert und dann die Soundanweisung so einzustellen? Es geht ja darum, dass die Schleife unterbrochen werden muss, wenn ich während des Spielens eines Tones einen anderen drücke. Und dann darf das Programm eben nicht wie es im Quelltext steht noch warten, bis die nächste Taste eingegeben wird, sondern muss gleich mit dem Wert weiterarbeiten.
Das Programm muss also während ein Ton gespielt wird immer noch registrieren, ob eine neue Taste gedrückt wurde, oder nicht.
Wenn eine neue Taste gedrückt wird, muss dann der Wert der Taste in i$ geschrieben werden, die Schleife unterbrochen werden, und die entsprechende Aktion stattfinden (erneuter Schleifendurchlauf mit neuem Wert).
Aber wie könnte man das anstellen?
Vielleicht kann man ja die Zeile, in der gewartet wird, bis man die nächste Taste eingibt einfach damit umgehen, dass man eine GOTO - Anweisung benutzt und in der Schleife eine Zeile weiter unten anfängt. Na ja, wohl eher nicht, wenn ich mir den Quelltext so anschaue...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
monster_beep



Anmeldungsdatum: 08.05.2005
Beiträge: 11

BeitragVerfasst am: 05.06.2005, 12:52    Titel: Antworten mit Zitat

Während ich hier so an meinem Klavierchen bastel, stellt sich mir eine grundlegende Frage zu QBasic: Ist es überhaupt möglich eine Anwendung so zu konstruieren, dass man sie, wenn sie gerade ausgeführt wird durch einen Tastendruck unterbricht bzw. abbricht?

Dazu mal das konkrete Beispiel:

Bei meinem Klavierprogramm ist der Hauptprogrammteil folgende Schleife:

DO WHILE i$ <> „q“
i$ = INPUT$(1)
i$ = LCASE$(i$)
IF i$ <> „q“ THEN
IF INSTR („<aysxcfvgbhnmw3e4rt6z7u8io“, i$) THEN
SELECT CASE
CASE IS = „<“
SOUND 261.63, l // l ist die vom Nutzer festgelegte Tonlänge
.
.
.
CASE IS = „o“
SOUND 1046.5, l
END SELECT
ELSE
PRINT „error: unknown key“
END IF
END IF
LOOP

Es ist also momentan so, dass, wenn eine bestimmt Taste gedrückt wurde, wein bestimmter Ton einfach mit der vom Nutzer festgelegten Länge gespielt wird (wie ich wahrscheinlich schon mehrmals erklärt habe lächeln ).
Ich hätte das aber gern so, dass sofort, wenn während des Spielens des SOUND eine neue Taste gedrückt wird, auch ein neuer Ton, oder der entsprechende Error ausgegeben wird.
Es müsste also so sein, dass das Programm während des SOUNDS registriert, ob was eigegeben wird, das dann mit i$ abgleicht und sofort für den neue Wert ausführt, ohne zu warten, bis der Ton zu Ende ist. Die Frage ist: Geht das überhaupt? Wenn ich so eine Anweisung in jeden CASE unter die SOUND – Anweisung schreibe, geht das meiner Meinung nach nicht, weil QBasic dann erstmal den Befehl zu Ende ausführt und sich dann Gedanken über den Rest macht. Kann man das nun trotzdem irgendwie realisieren? Vielleicht klemmts bei mir im Kopf nur ein wenig.
durchgeknallt
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Devilkevin
aka Kerstin


Anmeldungsdatum: 11.11.2004
Beiträge: 2532
Wohnort: nähe Mannheim

BeitragVerfasst am: 05.06.2005, 13:12    Titel: Antworten mit Zitat

Ähm in die entsprechende Schleife schreibst du einfach:

Code:

DO

.... Dein Programm .....

LOOP UNTIL INKEY$=CHR$(27)


Du kannst natürlich auch ne andere Taste nehmen (diese wäre z.B. die ESC Taste).
_________________
www.piratenpartei.de
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
monster_beep



Anmeldungsdatum: 08.05.2005
Beiträge: 11

BeitragVerfasst am: 05.06.2005, 17:48    Titel: Antworten mit Zitat

da würde der ja einfach die schleife abbrechen, wenn ich ESC drücke. Naja, das ist ja schon so (nur dass es hier halt mit q steht).
Ich will aber, dass er die Schleife an der stelle, wo er ist abbricht und sie von neuem anfängt und sie nicht verlässt.
Ich würde ja gerne mal den neuen kompletten Quelltext posten, aber irgendwie kann ich die BAS - Datei nicht wie bei der Version oben einfach ins Notpad ziehen. Also das heißt, ich kann das schon. Nur bekomme ich da keinen vernünftigen Quelltext sondern Gehacktes.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
jb



Anmeldungsdatum: 14.01.2005
Beiträge: 2010

BeitragVerfasst am: 05.06.2005, 17:57    Titel: Antworten mit Zitat

Dann speichere die .BAS-Datei halt im Textmodus ab zwinkern

jb
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
monster_beep



Anmeldungsdatum: 08.05.2005
Beiträge: 11

BeitragVerfasst am: 05.06.2005, 18:14    Titel: Antworten mit Zitat

danke für den tipp. ganz schön blöd, dass ich da nicht selbst drauf gekommen bin. hier ist also nochmal der aktuelle programmtext:

COLOR 14, 0
CLS
SLEEP 1
PRINT ":MONSTER BEEP:"
PRINT " < digital piano >"
PRINT
COLOR 7, 0
PRINT "Version 2.1"
PRINT "M.S. 2005"
PRINT
PRINT
INPUT"Tonlaenge festlegen => ENTER (18.2 entspricht einer Sekunde):", l
PRINT
PRINT
COLOR 0, 7
PRINT "Tasten:"
COLOR 7, 0
PRINT "Oktave 1: < a y s x c f v g b h n m"
PRINT " c cis d dis e f fis g gis a ais h c"
PRINT
PRINT "Oktave 2: w 3 e 4 r t 6 z 7 u 8 i o"
PRINT " c cis d dis e f fis g gis a ais h c"
PRINT
COLOR 0, 7
PRINT "Beenden:"
COLOR 7, 0
PRINT "ESC"
PRINT
COLOR 7, 0
PRINT "--------------------------------------------------------------------------------"
COLOR 3, 0
PRINT "Messages:"
DO WHILE i$ <> CHR$(27)
i$ = INPUT$(1)
i$ = LCASE$(i$)
IF i$ <> CHR$(27) THEN
IF INSTR("<aysxcfvgbhnmw3e4rt6z7u8io", i$) THEN

SELECT CASE i$
CASE IS = "<"
SOUND 261.63, l
CASE IS = "a"
SOUND 277.18, l
CASE IS = "y"
SOUND 293.66, l
CASE IS = "s"
SOUND 311.12, l
CASE IS = "x"
SOUND 329.62, l
CASE IS = "c"
SOUND 349.23, l
CASE IS = "f"
SOUND 369.99, l
CASE IS = "v"
SOUND 391.99, l
CASE IS = "g"
SOUND 415.3, l
CASE IS = "b"
SOUND 440, l
CASE IS = "h"
SOUND 466.16, l
CASE IS = "n"
SOUND 493.88, l
CASE IS = "m"
SOUND 523.25, l
CASE IS = "w"
SOUND 523.25, l
CASE IS = "3"
SOUND 554.37, l
CASE IS = "e"
SOUND 587.33, l
CASE IS = "4"
SOUND 622.25, l
CASE IS = "r"
SOUND 659.26, l
CASE IS = "t"
SOUND 698.45, l
CASE IS = "6"
SOUND 739.99, l
CASE IS = "z"
SOUND 783.99, l
CASE IS = "7"
SOUND 830.61, l
CASE IS = "u"
SOUND 880, l
CASE IS = "8"
SOUND 932.33, l
CASE IS = "i"
SOUND 987.77, l
CASE IS = "o"
SOUND 1046.5, l
END SELECT


ELSE
PRINT "Error: invalid key"
END IF
END IF
LOOP
PRINT "Monster Beep wird beendet..."
COLOR 7, 0
SLEEP 2
CLS
SYSTEM

ja, das Problem hatte ich ja oben schon beschrieben...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Skilltronic



Anmeldungsdatum: 10.09.2004
Beiträge: 1148
Wohnort: Köln

BeitragVerfasst am: 06.06.2005, 13:07    Titel: Antworten mit Zitat

Hallo

Ich habe mir mal einen anderen Ansatz überlegt. Mit der untersten Tastenreihe von Y bis zum , kann man damit die Tonleiter vom c' bis zum c'' spielen, die Töne werden gehalten, bis die Taste losgelassen oder eine andere gedrückt wird. Am besten funkioniert es aber, wenn man immer nur eine Taste gleichzeitig drückt...

Code:
FOR a = 0 TO 7
READ tf(a)
NEXT
DO
IF f > 0 THEN SOUND f, .04
t = INP(96)
t$ = INKEY$ 'Leert den Tastaturpuffer. Ausprobieren ob noetig.
IF t < 44 OR t > 51 THEN f = 0 ELSE f = tf(t - 44)
LOOP UNTIL t = 1                  'Ende mit ESC
END

DATA 262,293,330,349,392,440,494,523


Man könnte es z.B. dahingehend ausbauen, dass man in der darüberliegenden Reihe die schwarzen Tasten passend anordnet.

Gruss
Skilltronic
_________________
Elektronik und QB? www.skilltronics.de !
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
monster_beep



Anmeldungsdatum: 08.05.2005
Beiträge: 11

BeitragVerfasst am: 06.06.2005, 21:43    Titel: super! aber wie funktioniert's? Antworten mit Zitat

Das geht ja richtig ab. Schönes Ding. Mein Problem ist jetzt nur, wie man vielleicht schon an meinen Beiträgen in diesen Topic ablesen kann, dass ich nicht besonders gut logisch denken kann. weinen
Das heißt im Klartext: Ich kapier deinen Algorithmus überhaupt nicht. Also ich seh, dass da Schleifen und Alternativen und ne SOUND - Anweisung sind, aber mehr auch nicht. Kannst du (oder jemand anderes, der Zeit hat) das für mich vielleicht nochmal idiotensicher aufschlüsseln und mir sagen, wo genau das dann im Programm hingehört (ersetzt ja sicherlich die "Hauptschleife", die ich oben gepostet hab)??
Was ich mich zum Besipiel Frage, ist: Wieso benutzt du eine FOR – Schleife, die 8 Mal durchlaufen wird? Was ist READ tf (a)... Kopf schütteln
Ich würd halt gerne verstehen, wie das funktioniert, damit ich es benutzen und ausbauen kann.

Ach da fällt mir nochwas ein: Du scheinst dich ja auch mit Elektronik auszukennen. Da hab ich mal ne Frage: Kann ich an meinen PC – Speaker einen Verstärker und eine BOX anlöten, damit der mein „Monster Beep“ richtig Wums kriegt? Nun könnte man vielleicht meinen, dass ich da doch lieber auf eine Ausgabemöglichkeit über die Soundkarte zurückgreifen sollte, aber das will ich nicht. Mir gefällt nämlich der Sound des PC – Speakers ziemlich gut. Ist so spielzeugartig, wie so ein Kinderroboter. Wenn ich das ganze dann noch durch mein Boss Overdrive/Distortion – Pedal jage, hört sich das bestimmt krass an. durchgeknallt

Ja, soweit erstmal vielen Dank für die neue Idee!!!grinsen grinsen grinsen
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
dreael
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 2529
Wohnort: Hofen SH (Schweiz)

BeitragVerfasst am: 06.06.2005, 22:08    Titel: Antworten mit Zitat

Unter

http://www.dreael.ch/Deutsch/BASIC-Knowhow-Ecke/SOUND_Toene.html

hätte ich sonst auch ein sehr einfaches Tastaturklavier-Beispiel. Mit Hilfe der von MisterD gegebenen Formel der temperierten Tonleiter sowie der Tastenabfrage über INSTR (die Position des Zeichens entspricht indirekt dem Argument der Formel) konnte der Code extrem kompakt gehalten werden.
_________________
Teste die PC-Sicherheit mit www.sec-check.net
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Skilltronic



Anmeldungsdatum: 10.09.2004
Beiträge: 1148
Wohnort: Köln

BeitragVerfasst am: 06.06.2005, 22:29    Titel: Antworten mit Zitat

Hallo

Also: Die Schleife liest mit READ die acht Frequenzen die ganz unten unter DATA stehen ein und speichert sie im Array tf() ab. Sieh' dir am besten einfach mal den Eintrag in der QB-Onlinehilfe zu READ und DATA an.

Dann beginnt die Schleife. Wenn f = 0 ist, bedeutet das, das keine Taste gedrückt ist (siehe weiter unten), folglich wird auch kein Ton ausgegeben. Ist f > 0, dann wird für kurze Zeit (hab' mich auch nur durch ausprobieren an die .2 rangetastet) ein Ton mit der Frequenz f ausgegeben.

t = INP(96) ist einfach nur eine andere Art der Tastaturabfrage. Dazu findest du was in der Monster-FAQ auf qbasic.de . Mit diesem Befehl wird eine Zahl ausgelesen, die für die letzte Tastenaktivität steht. Liegt t zwischen 0 und 127, dann wurde die entsprechende Taste gedrückt, ist t>127 dan wurde die Taste (t-128) losgelassen. Mit

Code:
DO
LOCATE 1,1
PRINT INP(96)
LOOP


kannst du's ausprobieren.

Das mit dem Tastaturpuffer leeren ist dazu da, damit es nicht anfängt zu piepsen, wie wenn du zu lang auf der falschen Taste bleibst.

Die Tasten von Y bis , haben die Werte 44 - 51, wenn man davon 44 abzieht bekommt man die 0-7 unter denen im Array tf() die entsprechenden Werte für f abgelegt sind. Wird eine andere Taste gedrückt oder irgendeine logelassen wird f auf 0 gesetzt (siehe oben).

1 ist der Code für die ESC Taste. Die DO-LOOP-Schleife wird solange durchlaufen, bis diese Taste gedrückt wird.

Fertig.

Also an einen hochwertigen Verstärker würde ich das nicht so direkt anschliessen, ein Vorwiderstand kann nie schaden. Was du gerade zur Hand hast - ob 100 oder 10.000 Ohm ist nicht so wichtig. Aber wenn du gerne bastelst - schon mal daran gedacht, dir eine Klaviatur selbst zu bauen (Hoz,Draht, Alufolie etc.) ? Das mit der Tastatur und dem SOUND-Befehl ist nämlich nicht so das Wahre.

Gruss
Skilltronic
_________________
Elektronik und QB? www.skilltronics.de !
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
MisterD



Anmeldungsdatum: 10.09.2004
Beiträge: 3071
Wohnort: bei Darmstadt

BeitragVerfasst am: 06.06.2005, 22:51    Titel: Antworten mit Zitat

ey dreael, die instr-variante is ja ma sehr genial! Das mach ich bei meinem nächsten ich-hab-4-freistunden-und-weiß-nicht-was-ich-an-diesen-müll-pc's-machen-kann-außer-schwachsinn-zu-programmieren-und-damit-andere-leute-zu-nerven-Projekt grinsen
_________________
"It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
monster_beep



Anmeldungsdatum: 08.05.2005
Beiträge: 11

BeitragVerfasst am: 12.06.2005, 00:45    Titel: Antworten mit Zitat

Also ich hab mich jetzt mal hartnäckig damit auseinandergesetzt, wie das funtionieren soll, aber ich durchschau es immer noch nicht.

Also ich kapier folgendes:
Die FOR – Schleife muss 8mal durchlaufen werden, weil es 8 Werte einzulesen gibt. Beim ersten Schleifendurchlauf liest der den Wert 1 (also 262) aus dem tf – Array ein, beim zweiten den Wert 2...

So, dann beginnt die DO – Schleife. Da ist schon erstmal die Frage, wieso ich für f einfachso Buchstaben eingeben kann. Ein Buchstabe kann ja nicht größer 0 sein.

Dann frag ich mich noch, wie das Programm wissen kann, welche Frequenz f hat. Die Frequenzen sind doch im Array tf und nicht in f gespeichert.

So, die 0.04 Takte Abspieltzeit sind dann wohl sicher die Zeit für einen Schleifendurchlauf...

Na ja, ich hoffe ich kapier das noch. Ich brauch nen Kaffee...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
monster_beep



Anmeldungsdatum: 08.05.2005
Beiträge: 11

BeitragVerfasst am: 14.06.2005, 18:39    Titel: Antworten mit Zitat

dreael hat Folgendes geschrieben:
Unter

http://www.dreael.ch/Deutsch/BASIC-Knowhow-Ecke/SOUND_Toene.html

hätte ich sonst auch ein sehr einfaches Tastaturklavier-Beispiel. Mit Hilfe der von MisterD gegebenen Formel der temperierten Tonleiter sowie der Tastenabfrage über INSTR (die Position des Zeichens entspricht indirekt dem Argument der Formel) konnte der Code extrem kompakt gehalten werden.


Das ist ja ne ziemlich kluge sache! geschockt
Ich hab den algorithmus meines programms jetzt folgender Maßen umgebastelt

COLOR 14, 0
CLS
SLEEP 1
PRINT ":MONSTER BEEP:"
PRINT " < digital piano >"
PRINT
COLOR 7, 0
PRINT "Version 2.1"
PRINT "M.S. 2005"
PRINT
PRINT
INPUT "Tonlaenge festlegen => ENTER (18.2 entspricht einer Sekunde):", l
PRINT
PRINT
COLOR 0, 7
PRINT "Tasten:"
COLOR 7, 0
PRINT "Oktave 1: < a y s x c f v g b h n m"
PRINT " c cis d dis e f fis g gis a ais h c"
PRINT
PRINT "Oktave 2: w 3 e 4 r t 6 z 7 u 8 i o"
PRINT " c cis d dis e f fis g gis a ais h c"
PRINT
COLOR 0, 7
PRINT "Beenden:"
COLOR 7, 0
PRINT "ESC"
PRINT
COLOR 7, 0
PRINT "--------------------------------------------------------------------------------"
COLOR 3, 0
PRINT "Messages:"
DO WHILE i$ <> CHR$(27)
i$ = INPUT$(1)
i$ = LCASE$(i$)
IF i$ <> CHR$(27) THEN
IF INSTR("<aysxcfvgbhnmw3e4rt6z7u8io", i$) THEN
h% = INSTR("<aysxcfvgbhnmw3e4rt6z7u8io", i$)
SOUND 440! * 2! ^ ((h% + 2) / 12), l
ELSE
PRINT "Error: invalid key"
END IF
END IF
LOOP
PRINT "Monster Beep wird beendet..."
COLOR 7, 0
SLEEP 2
CLS
SYSTEM


hab nur noch paar kelien fragen zu folgenden zeilen:

IF INSTR("<aysxcfvgbhnmw3e4rt6z7u8io", i$) THEN
h% = INSTR("<aysxcfvgbhnmw3e4rt6z7u8io", i$)
SOUND 440! * 2! ^ ((h% + 2) / 12), l

Also, ich wollte nur mal wissen, ob ich das richtig verstanden habe. h% ist sozusagen die positionsvariable für das array INSTR, richtig?
Ist es denn in QBasic so, dass mit der Position „1“ zu zählen begonnen wird? Müsste schon so sein, denn sonst würde das Programm, wohl andere Tonhöhen liefern, aber das tut es nicht – ich hab's verglichen.
Drücke ich als die Taste „<“ ist das die Positon „1“. Folglich ist h% = 1. So, in der Formel rechnet man dann h% + 2. Das ist 3. Und so muss es auch sein, denn von 440 Hz, also a sind es 3 Halbtonschritte zu c, richtig?
Letzte Frage: Ich hab das bei der Fromel für das Berechnen das CSNG weggelassen. Das ist doch eine Funktion, die einen numerischen Ausdruck in eine Ganzzahl verwandelt, richtig?
Warum bestimmst du denn CSNG von (h% + 2)?
Oder bedeutet der Syntax, wie du ihn gemacht hast, dass CSNG (was heißt das eigentlich ausgeschrieben?) von ((h%+2)/12) gebildet wird. Würde dann eher Sinn machen.
Aber warum mit Ganzzahlen arbeiten? Wenn ich die Tonhöhe einfach so berechnen lasse, ist das doch viel genauer.
Achso, dann noch ne Frage: Wenn ich Teile des Codes von anderen Leuten übernehme (was ich zu vermeiden versuche), wie ich das hier doch irgendwie getan hab, kann ich dann trotzdem meinen Namen einfach so da oben hinsetzen? Ich meine, ich will ja mit meinen Programmen kein Geld verdienen, und will auch, dass die open source sind. Wenn jetzt die Firma RedHat an den Quelldateien von Linux Veränderunegn durchführt, heißt das ganze ja dann auch gleich RedHat Linux, oder hab ich da was verpeilt?ugly!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
jb



Anmeldungsdatum: 14.01.2005
Beiträge: 2010

BeitragVerfasst am: 14.06.2005, 18:49    Titel: Antworten mit Zitat

monster_beep hat Folgendes geschrieben:

das array INSTR

INSTR ist kein Array, sondern eine Funktion.

Code:

CSNG

wird oft verwendet, um einen Zahlenüberlauf zu verhindern.

jb
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
monster_beep



Anmeldungsdatum: 08.05.2005
Beiträge: 11

BeitragVerfasst am: 14.06.2005, 21:04    Titel: Antworten mit Zitat

Hab mich mal noch ein bisschen mit dem Problem Tonlänge beschäftigt:

COLOR 14, 0
CLS
SLEEP 1
PRINT ":MONSTER BEEP:"
PRINT " < digital piano >"
PRINT
COLOR 7, 0
PRINT "Version 3.0"
PRINT "m s 2005"
PRINT "ms@x.yz"
SLEEP 1
PRINT
PRINT
PRINT
PRINT
COLOR 0, 7
PRINT "Tasten:"
COLOR 7, 0
PRINT "Oktave 1: < a y s x c f v g b h n m"
PRINT " c cis d dis e f fis g gis a ais h c"
PRINT
PRINT "Oktave 2: w 3 e 4 r t 6 z 7 u 8 i o"
PRINT " c cis d dis e f fis g gis a ais h c"
PRINT
COLOR 0, 7
PRINT "Beenden:"
COLOR 7, 0
PRINT "ESC"
PRINT
COLOR 12, 0
PRINT "----------------------------------Nachrichten-----------------------------------"


DO WHILE i$ <> CHR$(27)
i$ = INPUT$(1)
i$ = LCASE$(i$)
IF i$ <> CHR$(27) THEN
IF INSTR("<aysxcfvgbhnmw3e4rt6z7u8io", i$) THEN
h% = INSTR("<aysxcfvgbhnmw3e4rt6z7u8io", i$)


i$ = INKEY$
DO UNTIL i$ <> INKEY$
SOUND 440! * 2! ^ ((h% + 2) / 12), .04
LOOP


ELSE
PRINT "Fehler: Ung?ltige Taste"
END IF
END IF
LOOP
PRINT "Monster Beep wird beendet..."
COLOR 7, 0
SLEEP 2
CLS
SYSTEM




Die SOUND-Schleife wird jetzt ausgeführt, bis sich der Tastaturpuffer ändert. Kann man das so ralisieren?
Problem wieder: Am Anfang der Schleife wartet er auf die nächste Eingabe. Das wurde hier ja schonmal auf andere Weise gelöst. Kann ich dass jetzt auch hier einbauen?

Achso: Was ist eigentlich der Tastaturpuffer so richtig?


Ich brauch nen Kaffee... => mit dem Kopf durch die Mauer wollen => R.I.P.??
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
MisterD



Anmeldungsdatum: 10.09.2004
Beiträge: 3071
Wohnort: bei Darmstadt

BeitragVerfasst am: 14.06.2005, 21:45    Titel: Antworten mit Zitat

nein. Der Tastaturpuffer ist sofort wenn du ihn abfragst ein zeichen kürzer, wenn nur eins drin ist isser dann leer. Das müsstest du dann mit Scancodes machen.
ich schreib da grad ma was..

/edit: Mist, geht ned, mein TV-Programm macht stress peinlich
also sowas:

mit
Code:
DO
t=INP(&H60)
PRINT t
LOOP UNTIL INKEY$ = CHR$(27)

kannst du die Scancodes für die entsprechenden Tasten rausfinden. Die musst du dir dann merken. Dann nimmst du das hier:
Code:
DIM ton(128) AS INTEGER
'den Tasten Werte zuweisen in Halbtonschritten, 0 entspricht a,
'für den Ton a aber bitte 100 nehmen, damit man a von unbelegten
'tasten unterscheiden kann, die haben den Wert 0
ton(scancode)=halbtonschritt 'für jede Taste die einen Ton bekommt.

DO
t = INP(&H60)
IF t=100 THEN 'a
 SOUND 440,.1
ELSEIF t<>0 THEN 'anderer Ton
 SOUND 440*2^(ton(t)/12),.1
ELSE 'ungültige Taste
 PRINT "invalid Key"
END IF
LOOP UNTIL INKEY$ = CHR$(27)

Ungetestet, hoffe es funktioniert.
_________________
"It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu QBasic. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz