MIDI ins Clipboard und CALLBACK

Anfängerfragen zum Programmieren mit PureBasic.
Sorn
Beiträge: 17
Registriert: 13.02.2008 17:30

MIDI ins Clipboard und CALLBACK

Beitrag von Sorn »

Hallo, Ich bin zwar neu hier, aber habe hier gleich mal ein Problem,
bei dem ich nicht sicher war, ob es überhaupt in die Anfängerecke soll.

Ich möchte MIDI-Input-Daten per Clipboard an andere Programme schicken.
Das klappt eigentlich schon ganz gut.
D.h. wenn ich auf einem Keyboard Tasten drücke, kann ich diese
Daten an ein anderes Programm, das das Clipboard ausliest, ausgeben.

Wenn ich nun aber einen Sequencer laufen lasse. also viele Daten
hintereinander schicke, dann stürzt das PB-Programm ab.

Ich habe den Verdacht, dass es daran liegt, dass das Schicken an das
Clipboard laufend vom CALLBACK unterbrochen wird.

Hat jemand eine Idee, was ich tun könnte, oder an was es liegt?

ps. Falls Ihr noch andere Auffälligkeiten in diesem Programm entdeckt,
sagt es ruhig. :oops: Habe bisher eher mal VBA programmiert.

Code: Alles auswählen

Global hMidiIn.l
Global MyInstance.l
Global miflags.l
Global offen.b
Global done.b

Global errortext.s
Global Mhandle.l
Global wert.l
Global anzahl.l
Global String.s
Global String_alt.s

Global handle.l

Global HB.l
Global MB.l
Global LB.l

Global Dim noten.s(12)

noten(0)= "C  "
noten(1)= "Cis"
noten(2)= "D  "
noten(3)= "Dis"
noten(4)= "E  "
noten(5)= "F  "
noten(6)= "Fis"
noten(7)= "G  "
noten(8)= "Gis"
noten(9)= "A  "
noten(10)= "Ais"
noten(11)= "B  "

Global Dim action.s(1)

action(0)="NoteOff"
action(1)="NoteOn "

errortext="__________________________________________________"
mnum.l=0
Mhandle.l=0
MyInstance.l = 0
miflags.l = #CALLBACK_FUNCTION + #MIDI_IO_STATUS

Global NewList daten1.l()
Global NewList daten2.l()

Declare midizu(handle)
Declare aufteilen(wert)
Declare verwerten(hMidiIn.l , wMsg.l,wert.l, dwParam1.l, dwParam2.l)



Procedure Open_window()
  If OpenWindow(0, 256, 211, 315, 100, "MIDI Server",  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar )
 ;
  EndIf
EndProcedure

 Open_window()
   
 If MIDnummer >= 0 
	adresse.l=@verwerten()
	If midiInOpen_(@Mhandle, MIDnummer, adresse, MyInstance, miflags) = 0 		; API Function: MIDI-Device öffnen
		If midiInStart_(Mhandle) = 0 																		; API Function: MIDI Input starten
			offen = 1         
			Repeat
				
				While CountList(daten1())>0								; so oft durchführen bis keine Elemente mehr in der Liste sind				
					SelectElement(daten1(), 0)							; Erstes Element anwählen												
					aufteilen(daten1())											; Daten aus einander schneiden						
					String=(action(HB/88 ) + " " + noten(MB % 12) + Str(Int(MB/12))  + " " + Str(LB)	)	; wieder zusammen stellen
					
					If String<>String_alt 										; Falls neue Daten vorlagen
						SetClipboardText(String	)						; Diese ins Clipboard schreiben
					EndIf
					
					String_alt= String											; alte Daten merken
					
					DeleteElement(daten1(),0)								; Das erste Element der Listen wird jetzt gelöscht					
					DeleteElement(daten2(),0)									
							
				Wend	
				
				Until   Event = #PB_Event_CloseWindow	; RawKey()     
				     	
			midizu(Mhandle)           
			Else
				MessageRequester("Error","Error while calling for a handle")
			EndIf
		Else
			MessageRequester("Error","Error while opening a device")	           		
	EndIf
Else   	
	MessageRequester("Error","Not a possible device number")	           		
EndIf
 
 

Procedure verwerten(hMidiIn.l , wMsg.l,wert.l, dwParam1.l, dwParam2.l)

; Active sensing und time ausblenden
 If dwParam1 <> 248 And dwParam1 <> 254 


	If	AddElement(Daten1()) <>0 
		  Daten1() = dwParam1
		  
	Else
		  MessageRequester("Error","Error while storing value")  
		 
	EndIf
	
	If	AddElement(Daten2())<>0
		  Daten2() = dwParam2
		  
	Else
		MessageRequester("Error","Error while storing value")
		
	EndIf
 
 EndIf



 EndProcedure

Procedure midizu(handle)

If handle >= 0 
    If Not (done)
        If offen=1
            If midiInReset_(handle) = 0 
                If midiInStop_(handle) = 0 
                    If midiInClose_(handle) = 0
                        offen = 0
                        done = 1
                        ClearList(daten1()) 
                        ClearList(daten2()) 					                        
                        	Delay(500)
					CloseConsole()
					MessageRequester("INFO","MIDI is closed")										
					End                      
                        handle = -1
                    Else
				MessageRequester("Error","Error while closing MIDI")
                    EndIf
                Else
				MessageRequester("Error","Error while calling for a handle")
                EndIf
            Else
     		MessageRequester("Error","Error while reseting MIDI")
            EndIf
        Else
     		MessageRequester("Error","MIDI while closing MIDI")
        EndIf
    Else
    EndIf
Else
EndIf

EndProcedure

Procedure aufteilen(wert )

	HB= wert >> 16
	MB= ( wert & 65280) >> 8
	LB= wert & 255

EndProcedure




End 
Benutzeravatar
Xaby
Beiträge: 2144
Registriert: 12.11.2005 11:29
Wohnort: Berlin + Zehdenick
Kontaktdaten:

Beitrag von Xaby »

@Sorn
Ich möchte MIDI-Input-Daten per Clipboard an andere Programme schicken.
Das klappt eigentlich schon ganz gut.
Das Clipboard ist Tabu.
Es sollte nur für den Anwender als Zwischenablage genutzt werden.

Folgende Vorschläge:
- OLE Anbindung
- Midi in Datei Speichern
- String in ein Editorgadget schreiben und nach dem gesamten Lied kopieren

bzw. erstmal in einen Editor die Daten schreiben und dann kannst du immer noch mit den aufgefangenen Daten weiter arbeiten.

Würde natürlich nicht mehr "OnTheFly" sein.

>> Welches Programm unterstützt denn die Eingabe von Noten über die Zwischenablage? :allright:

Schau mal hier
http://www.purebasic.fr/german/viewtopi ... e&start=10

Vielleicht hilft dir das weiter. :allright:
Kinder an die Macht http://scratch.mit.edu/
Sorn
Beiträge: 17
Registriert: 13.02.2008 17:30

Beitrag von Sorn »

Danke für die Antwort. <)


Ich verstehe Deine Bedenken wegen dem Clipboard.
Ich hatte zuvor tatsächlich auch schon mit UDP experimentiert
allerdings hatte ich da eher mehr Probleme mit dem Empfangsprogramm.
Das Empfangsprogramm ist TrueSpace7.51. Dieses ermöglicht
auch diverse Simulationen ablaufen zu lassen. Und als Steuerungsmöglichkeit
kam mir da der Gedanke MIDI zu verwenden. Leider ist TrueSpace
nur in der Lage VBScript sowie JScript zu verarbeiten, die leider nicht
in der Lage sind Callbacks zu ermöglichen. Darum suchte ich nach einer
simplen Möglichkeit mittels einer Zeitschleife die Daten irgendwo
heraus zu lesen.
In ein File zu schreiben, oder eine Art RAM-Disc zu verwenden wären
noch weitere Alternativen.

Nun inzwischen hat es geklappt, es war nur ein Timingproblem, das ich
durch Einfügen eines Delays anpassen konnte. Auch fehlte im Programm
noch eine Windows Message Abfrage.

Nebenbei tritt nun allerdings ein eigenartiger Effekt auf.
Nach Beenden des Programms lässt es sich nicht von der Festplatte löschen.
Windows behauptet, dass noch Zugriffe von anderen Programmen
bestehen. MIDI habe ich schön brav zu gemacht und es existiert auch
ein END im Programm. Seltsam.
Antworten