| |
|
|
Jörg Sellmeyer | Da mir die Profan-Syntax des Play-Befehls zu unflexibel ist, habe ich nach Alternativen gesucht. Nach ausführlichem Studium verschiedener Webseiten und dem Code von Sebastian Sprengers Piano-Trainer [...] habe ich es endlich rausbekommen, wie die Midi-Api funktioniert. Da es erst ab XProfan11 läuft, habe ich auch eine EXE beigefügt. (in der Zip-Datei ist eine aktualisiert Exe, mit ein paar (rudimentären) grafischen Ausgaben der Töne) Hier ist das Resultat. Ich bitte um Tests und Rückmeldungen. KompilierenMarkierenSeparierenCode von Jörg Sellmeyer für die Profangemeinschaft
Proc MidiPlayInstrument
Parameters hMidiDevice&,Instrument%,Channel%,Ton%,Volume%
Declare b#
Dim b#,8
MidiOutShortMsg(hMidiDevice&,Instrument% * 256 + $C * 16 + Channel%)
$C = Statusbyte zum Einstellen des Kanals
Byte b#,0=$9 * 16 + Channel%,Ton%,Volume%,0
$9 = Statusbyte zum Einschalten des Tones
MidiOutShortMsg(hMidiDevice&,Long(b#,0))
Dispose b#
EndProc
Proc MidiChannelVolume
EndProc
Proc PlayAccord
Parameters hMidiDevice&,Instrument%,GrundTon%,Volume%
MidiPlayInstrument(hMidiDevice&,Instrument%,5,GrundTon%,Volume%)
MidiPlayInstrument(hMidiDevice&,Instrument%,6,GrundTon% + 5,Volume%)
MidiPlayInstrument(hMidiDevice&,Instrument%,7,GrundTon% + 7,Volume%)
EndProc
WindowTitle "Virtual Keith Jarrett"
Cls
Set("Decimals",0)
Var hWinMMDll& = ImportDll("WINMM","")
Declare Dev#,lpHMidiOut#,shMsg#,Tick&
Dim lpHMidiOut#,16
Dim Dev#,52
print MidiOutGetNumDevs(0,Dev#,52),"Gerät(e) vorhanden"
If MidiOutGetNumDevs(0,Dev#,52) > 0
ClearList
WhileLoop MidiOutGetNumDevs(0,Dev#,52)
MidiOutGetDevCapsA(0,Dev#,52)
AddString Char$(Dev#,8,31)
Print "Taste",&Loop,"für: q";Char$(Dev#,8,31);"q drücken"
Wend
Else
Print "Kein Midifähiges Gerät gefunden :("
Print "Beliebige Eingabe beendet das Programm"
WaitInput
End
EndIf
Print "Welche Nummer?"
Declare Nr%
Input Nr%
Print "Device",Nr% - 1,"gewählt"
CaseNot Nr%:End
Case Nr% > MidiOutGetNumDevs(0,Dev#,52):End
MidiOutOpen(lpHMidiOut#,Nr% - 1,0,0,0)
Var Midi& = Long(lpHMidiOut#,0)
Randomize
Print "ESC zum Beenden drücken"
Declare n1%,n2%,n1alt%,n2alt%
Locate 8,1
Declare Takt&,Takte&
WhileLoop 1000
Case IsKey(27):Break
If &Loop Mod (1 + Rnd(6))
n1% = 40 + Rnd(60)
Case n1alt%:MidiPlayInstrument(Midi&,0,0,n1%,0)
n1alt% = n1%
MidiPlayInstrument(Midi&,Rnd(4),0,n1%,40 + Rnd(88))
ElseIf &Loop Mod (1 + Rnd(6))
n2% = 40 + Rnd(60)
Case n2alt%:MidiPlayInstrument(Midi&,Rnd(4),1,n2alt%,40 + Rnd(88))
n2alt% = n2%
MidiPlayInstrument(Midi&,0,1,n2%,0)
EndIf
midiOutSetVolume(Midi&,MakeLong((78 + Rnd(50)) * 256,(78 + Rnd(50)) * 256))
Tick& = &GetTickcount
Sleep 125 + (Rnd(141) - 70)
Tick& = &GetTickcount - Tick&
Case Rnd(20) = 4:PlayAccord(Midi&,3,Rnd(40) + 30,80 + Rnd(48))
If Takt& >= 1000
Locate %CsrLin,1
Print " "
Print " "
Print " "
Locate 8,1
Clear Takt&
midiOutSetVolume(Midi&,$7F007F00)
EndIf
Add Takt&,Tick&
Print Format$(" 000",Tick&),Format$(" 000%",Tick& / 125 * 100),Format$(" 0000",Takt&)
Wend
MidiOutReset(Midi&)
Locate 25,1
Print "Das war eine vom Computer qimprovisierteq Suite"
waitinput
FreeDll hWinMMDll&
MidiOutClose(Midi&)
End
Ach ja: Bitte auch mal das hier testen: [...] |
|
|
| Windows XP SP2 XProfan X4... und hier mal was ganz anderes als Profan ... | 01.09.2008 ▲ |
|
|
|
|
Dieter Zornow | Bei mir hats ohne Probleme funktioniert, habe nur den Code getestet |
|
|
| Er ist ein Mann wie ein Baum. Sie nennen ihn Bonsai., Win 7 32 bit und Win 7 64 bit, mit XProfan X2 | 01.09.2008 ▲ |
|
|
|
|
| Funktioniert (furchtbar!) schön! Vielleicht sollte manchmal noch zwischen Moll und Dur umhergeschalten werden - und mancher Multiseptimakkord (ab und zu) würde das ganze etwas abrunden. |
|
|
| |
|
|
|
Jörg Sellmeyer | iF
Funktioniert (furchtbar!) schön! Vielleicht sollte manchmal noch zwischen Moll und Dur umhergeschalten werden - und mancher Multiseptimakkord (ab und zu) würde das ganze etwas abrunden.
Wenn mein aktuelles Programm, für welches ich das mit der WINMM.DLL erst mal ausgetüftelt habe, fertig ist, werde ich mal einen virtuellen Klavierspieler erstellen, der Musik nach Wunsch spielt. Mit Reglern für:
Klassik---------------------------+------------------------Pop
Straight-----------------------------------------+---------Jazzy
Rhythmisch-------------+-------------------------------Frei
|
|
|
| Windows XP SP2 XProfan X4... und hier mal was ganz anderes als Profan ... | 01.09.2008 ▲ |
|
|
|
|
| Einfach nur eine schöne Drum-Machine (welche sich über einen Midi-Temporegler in der Geschwindigkeit ändern lässt) wäre wohl einmalig! Habe das mit den Knobs am Synth rausbekommen und deshalb auch das Knob-Control programmiert gehabt. Das Control zeigt mir die genaue Drehung - die Werte hierfür kann ich also ansagen. |
|
|
| |
|
|
|
Jörg Sellmeyer | An sowas Ähnlichem arbeite ich gerade. |
|
|
| Windows XP SP2 XProfan X4... und hier mal was ganz anderes als Profan ... | 01.09.2008 ▲ |
|
|
|
|
Sebastian Sprenger | Hi Jörg, scheint zu funktionieren, aber ehrlich gesagt kann ich mit den Harmonien selbst (was fürn Jazz ist das?? ) und den Ausgaben nicht viel anfangen.
Ein paar Tipps will ich dir mal geben:
midiOutGetNumDevs hat die falsche Parameterzahl (3 statt 0; wird das bei ImportDLL nicht überprüft? Nachtrag: Wenn ichs recht überlege, kann es wohl kaum...) Du kannst für einen Akkord ruhig denselben Kanal angeben (in einem MIDI-Kanal können mehrere verschiedene Töne gleichzeitig klingen). Bitte nicht die Lautstärkeregelung meines Systems ändern!! Vielleicht wusstest du aber einfach nur noch nicht, wie man die Lautstärke eines Kanals ändert: KompilierenMarkierenSeparieren $B = ControlChange
$07 = ChannelVolume
midiOutShortMsg(hMidiDevice&, $07B0 | Channel% | Volume% << 16)
Gruß, Sebastian |
|
|
| Profan² 7.0e, XProfan 9, 11.2a, FreeProfan32 Windows Vista Home Premium 32-Bit, 2.8 Ghz, 4 GB RAM Windows Me, 1.8 Ghz, 256 MB RAM | 01.09.2008 ▲ |
|
|
|
|
Jörg Sellmeyer | Hallo SSebastian,
midiOutGetNumDevs Hm - aber da habe ich doch drei Parameter... Das habe ich übrigens aus Deinem Piano Trainer und es war die erste Funktion, die ich verwendet habe, um überhaupt mal ein bischen was von dem zu verstehen, was da abläuft
Ich bin da immer noch schwer am rumexperimentieren. Diese ganzen Statusbits und Messages sind schon etwas undurchschaubar, finde ich. Wie kann man denn ein Instrument im Stereobild verschieben? Oder ist das Midikanal-Volume genauso geregelt, wie bei midiOutSetVolume? Auf jeden Fall Danke für die Tips. Kann gut sein, daß ich noch ein paarmal nachhake, wenns recht ist.
Gruß Jörg
Ach so: die Zahlenausgaben sind unerheblich, aber die Striche, (die allerdings nur in der Exe vorkommen), kann man als Noten(positionen) im Takt ansehen. |
|
|
| Windows XP SP2 XProfan X4... und hier mal was ganz anderes als Profan ... | 02.09.2008 ▲ |
|
|
|
|
Sebastian Sprenger | Jörg Sellmeyer
aber da habe ich doch drei Parameter... Die drei Parameter bei midiOutGetDevCaps sind richtig. Du übergibst aber an midiOutGetNumDevs ebenfalls drei Parameter, obwohl dafür keine vorgesehen sind. Jörg Sellmeyer
Wie kann man denn ein Instrument im Stereobild verschieben? Ähnlich wie die ChannelVolume, nur mit $0A statt der $07: KompilierenMarkierenSeparieren $B = ControlChange
$0A = PanPot
midiOutShortMsg(hMidiDevice&, $0AB0 | Channel% | PanPot% << 16)
Beispielwerte: 0 = ganz links 64 = mittig 127 = ganz rechts
Jörg Sellmeyer
Kann gut sein, daß ich noch ein paarmal nachhake, wenns recht ist. Nur zu - eigentlich werde ich ganz gerne mit Fragen gelöchert - zumindest, wenn ich nicht gerade in der Schule bin... Gruß, Sebastian |
|
|
| Profan² 7.0e, XProfan 9, 11.2a, FreeProfan32 Windows Vista Home Premium 32-Bit, 2.8 Ghz, 4 GB RAM Windows Me, 1.8 Ghz, 256 MB RAM | 02.09.2008 ▲ |
|
|
|
|
Frank Abbing | Huch, grad erst entdeckt, sorry. Man, mein Computer ist völlig unmusikalisch, hätte mehr von ihm erwartet... |
|
|
| |
|
|