[WINEALSA] Timer -> Thread (Resent)
Christian Costa
titan.costa at wanadoo.fr
Mon Feb 16 16:15:26 CST 2004
Hi,
I did not have any news from this patch, I guess it has been lost somewhere.
So here it is again.
Bye.
Changelog :
Replaced the timer and its callback by a thread for receiving midi in
events.
Fixed time of MIM_LONGDATA notification.
Handled DRVM_EXIT in ALSA_midMessage.
Christian Costa titan.costa at wanadoo.fr
-------------- next part --------------
Index: midi.c
===================================================================
RCS file: /home/wine/wine/dlls/winmm/winealsa/midi.c,v
retrieving revision 1.7
diff -u -r1.7 midi.c
--- midi.c 5 Feb 2004 01:24:28 -0000 1.7
+++ midi.c 11 Feb 2004 22:46:13 -0000
@@ -93,12 +93,14 @@
static snd_seq_t* midiSeq = NULL;
static int numOpenMidiSeq = 0;
-static UINT midiInTimerID = 0;
static int numStartedMidiIn = 0;
static int port_in;
static int port_out;
+static int end_thread;
+static HANDLE hThread;
+
/*======================================================================*
* Low level MIDI implementation *
*======================================================================*/
@@ -270,46 +272,50 @@
return 0;
}
-static VOID WINAPI midTimeCallback(HWND hwnd, UINT msg, UINT id, DWORD dwTime)
+static DWORD WINAPI midRecThread(LPVOID arg)
{
int npfd;
struct pollfd *pfd;
- TRACE("(%p, %d, %d, %lu)\n", hwnd, msg, id, dwTime);
+ TRACE("Thread startup\n");
- npfd = snd_seq_poll_descriptors_count(midiSeq, POLLIN);
- pfd = (struct pollfd *)HeapAlloc(GetProcessHeap(), 0, npfd * sizeof(struct pollfd));
- snd_seq_poll_descriptors(midiSeq, pfd, npfd, POLLIN);
-
- /* Check if a event is present */
- if (poll(pfd, npfd, 0) <= 0) {
- HeapFree(GetProcessHeap(), 0, pfd);
- return;
- }
+ while(!end_thread) {
+ TRACE("Thread loop\n");
+ npfd = snd_seq_poll_descriptors_count(midiSeq, POLLIN);
+ pfd = (struct pollfd *)HeapAlloc(GetProcessHeap(), 0, npfd * sizeof(struct pollfd));
+ snd_seq_poll_descriptors(midiSeq, pfd, npfd, POLLIN);
+
+ /* Check if a event is present */
+ if (poll(pfd, npfd, 250) < 0) {
+ HeapFree(GetProcessHeap(), 0, pfd);
+ continue;
+ }
- /* Note: This definitely does not work.
- * while(snd_seq_event_input_pending(midiSeq, 0) > 0) {
- snd_seq_event_t* ev;
- snd_seq_event_input(midiSeq, &ev);
- ....................
- snd_seq_free_event(ev);
- }*/
-
- do {
- WORD wDevID;
- snd_seq_event_t* ev;
- snd_seq_event_input(midiSeq, &ev);
- /* Find the target device */
- for (wDevID = 0; wDevID < MIDM_NumDevs; wDevID++)
- if ( (ev->source.client == MidiInDev[wDevID].addr.client) && (ev->source.port == MidiInDev[wDevID].addr.port) )
- break;
- if (wDevID == MIDM_NumDevs)
- FIXME("Unexpected event received, type = %x from %d:%d\n", ev->type, ev->source.client, ev->source.port);
- else {
- DWORD toSend = 0;
- TRACE("Event received, type = %x, device = %d\n", ev->type, wDevID);
- switch(ev->type)
- {
+ /* Note: This definitely does not work.
+ * while(snd_seq_event_input_pending(midiSeq, 0) > 0) {
+ snd_seq_event_t* ev;
+ snd_seq_event_input(midiSeq, &ev);
+ ....................
+ snd_seq_free_event(ev);
+ }*/
+
+ do {
+ WORD wDevID;
+ snd_seq_event_t* ev;
+ snd_seq_event_input(midiSeq, &ev);
+ /* Find the target device */
+ for (wDevID = 0; wDevID < MIDM_NumDevs; wDevID++)
+ if ( (ev->source.client == MidiInDev[wDevID].addr.client) && (ev->source.port == MidiInDev[wDevID].addr.port) )
+ break;
+ if (wDevID == MIDM_NumDevs)
+ FIXME("Unexpected event received, type = %x from %d:%d\n", ev->type, ev->source.client, ev->source.port);
+ else {
+ DWORD dwTime, toSend = 0;
+ /* FIXME: Should use ev->time instead for better accuracy */
+ dwTime = GetTickCount() - MidiInDev[wDevID].startTime;
+ TRACE("Event received, type = %x, device = %d\n", ev->type, wDevID);
+ switch(ev->type)
+ {
case SND_SEQ_EVENT_NOTEOFF:
toSend = (ev->data.note.velocity << 16) | (ev->data.note.note << 8) | MIDI_CMD_NOTE_OFF | ev->data.control.channel;
break;
@@ -361,19 +367,20 @@
default:
FIXME("Unhandled event received, type = %x\n", ev->type);
break;
- }
- if (toSend != 0) {
- TRACE("Sending event %08lx (from %d %d)\n", toSend, ev->source.client, ev->source.port);
- /* FIXME: Should use ev->time instead for better accuracy */
- if (MIDI_NotifyClient(wDevID, MIM_DATA, toSend, dwTime-MidiInDev[wDevID].startTime) != MMSYSERR_NOERROR) {
- WARN("Couldn't notify client\n");
+ }
+ if (toSend != 0) {
+ TRACE("Sending event %08lx (from %d %d)\n", toSend, ev->source.client, ev->source.port);
+ if (MIDI_NotifyClient(wDevID, MIM_DATA, toSend, dwTime) != MMSYSERR_NOERROR) {
+ WARN("Couldn't notify client\n");
+ }
}
}
- }
- snd_seq_free_event(ev);
- } while(snd_seq_event_input_pending(midiSeq, 0) > 0);
+ snd_seq_free_event(ev);
+ } while(snd_seq_event_input_pending(midiSeq, 0) > 0);
- HeapFree(GetProcessHeap(), 0, pfd);
+ HeapFree(GetProcessHeap(), 0, pfd);
+ }
+ return 0;
}
/**************************************************************************
@@ -439,14 +446,15 @@
TRACE("input port connected %d %d %d\n",port_in,MidiInDev[wDevID].addr.client,MidiInDev[wDevID].addr.port);
if (numStartedMidiIn++ == 0) {
- midiInTimerID = SetTimer(0, 0, 250, midTimeCallback);
- if (!midiInTimerID) {
+ end_thread = 0;
+ hThread = CreateThread(NULL, 0, midRecThread, NULL, 0, NULL);
+ if (!hThread) {
numStartedMidiIn = 0;
- WARN("Couldn't start timer for midi-in\n");
+ WARN("Couldn't create thread for midi-in\n");
midiCloseSeq();
return MMSYSERR_ERROR;
}
- TRACE("Starting timer (%u) for midi-in\n", midiInTimerID);
+ TRACE("Created thread for midi-in\n");
}
MidiInDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
@@ -492,11 +500,13 @@
return MMSYSERR_ERROR;
}
if (--numStartedMidiIn == 0) {
- TRACE("Stopping timer for midi-in\n");
- if (!KillTimer(0, midiInTimerID)) {
- WARN("Couldn't stop timer for midi-in\n");
+ TRACE("Stopping thread for midi-in\n");
+ end_thread = 1;
+ if (WaitForSingleObject(hThread, 5000) != WAIT_OBJECT_0) {
+ WARN("Thread end not signaled, force termination\n");
+ TerminateThread(hThread, 0);
}
- midiInTimerID = 0;
+ TRACE("Stopped thread for midi-in\n");
}
snd_seq_disconnect_from(midiSeq, port_in, MidiInDev[wDevID].addr.client, MidiInDev[wDevID].addr.port);
@@ -1240,6 +1250,7 @@
switch (wMsg) {
#if defined(HAVE_ALSA) && ((SND_LIB_MAJOR == 0 && SND_LIB_MINOR >= 9) || SND_LIB_MAJOR >= 1)
case DRVM_INIT:
+ case DRVM_EXIT:
case DRVM_ENABLE:
case DRVM_DISABLE:
/* FIXME: Pretend this is supported */
More information about the wine-patches
mailing list