/************************************************************************** * midiOutOpen [WINMM.@] */ UINT WINAPI midiOutOpen(LPHMIDIOUT lphMidiOut, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags) { HMIDIOUT hMidiOut; LPWINE_MIDI lpwm; UINT dwRet; TRACE("(%p, %d, %08lX, %08lX, %08X);\n", lphMidiOut, uDeviceID, dwCallback, dwInstance, dwFlags); if (lphMidiOut != NULL) *lphMidiOut = 0; dwRet = WINMM_CheckCallback(dwCallback, dwFlags, FALSE); if (dwRet != MMSYSERR_NOERROR) return dwRet; lpwm = MIDI_OutAlloc(&hMidiOut, &dwCallback, &dwInstance, &dwFlags, 0, NULL); if (lpwm == NULL) return MMSYSERR_NOMEM; lpwm->mld.uDeviceID = uDeviceID; dwRet = MMDRV_Open((LPWINE_MLD)lpwm, MODM_OPEN, (DWORD_PTR)&lpwm->mod, dwFlags); if (dwRet != MMSYSERR_NOERROR) { MMDRV_Free(hMidiOut, (LPWINE_MLD)lpwm); hMidiOut = 0; } if (lphMidiOut) *lphMidiOut = hMidiOut; TRACE("=> %d hMidi=%p\n", dwRet, hMidiOut); return dwRet; }
/************************************************************************** * MMDRV_Open [internal] */ DWORD MMDRV_Open(LPWINE_MLD mld, UINT wMsg, DWORD dwParam1, DWORD dwFlags) { DWORD dwRet = MMSYSERR_BADDEVICEID; DWORD dwInstance; WINE_LLTYPE* llType = &llTypes[mld->type]; TRACE("(%p, %04x, 0x%08x, 0x%08x)\n", mld, wMsg, dwParam1, dwFlags); mld->dwDriverInstance = (DWORD)&dwInstance; if (mld->uDeviceID == (UINT)-1 || mld->uDeviceID == (UINT16)-1) { TRACE("MAPPER mode requested !\n"); /* check if mapper is supported by type */ if (llType->bSupportMapper) { if (llType->nMapper == -1) { /* no driver for mapper has been loaded, try a dumb implementation */ TRACE("No mapper loaded, doing it by hand\n"); for (mld->uDeviceID = 0; mld->uDeviceID < llType->wMaxId; mld->uDeviceID++) { if ((dwRet = MMDRV_Open(mld, wMsg, dwParam1, dwFlags)) == MMSYSERR_NOERROR) { /* to share this function epilog */ dwInstance = mld->dwDriverInstance; break; } } } else { mld->uDeviceID = (UINT16)-1; mld->mmdIndex = llType->lpMlds[-1].mmdIndex; TRACE("Setting mmdIndex to %u\n", mld->mmdIndex); dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags, TRUE); } } } else { if (mld->uDeviceID < llType->wMaxId) { mld->mmdIndex = llType->lpMlds[mld->uDeviceID].mmdIndex; TRACE("Setting mmdIndex to %u\n", mld->mmdIndex); dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags, TRUE); } } if (dwRet == MMSYSERR_NOERROR) mld->dwDriverInstance = dwInstance; return dwRet; }
/************************************************************************** * midiInOpen [WINMM.@] */ UINT WINAPI midiInOpen(HMIDIIN* lphMidiIn, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags) { HANDLE hMidiIn; LPWINE_MIDI lpwm; DWORD dwRet; TRACE("(%p, %d, %08lX, %08lX, %08X);\n", lphMidiIn, uDeviceID, dwCallback, dwInstance, dwFlags); if (lphMidiIn != NULL) *lphMidiIn = 0; dwRet = WINMM_CheckCallback(dwCallback, dwFlags, FALSE); if (dwRet != MMSYSERR_NOERROR) return dwRet; lpwm = (LPWINE_MIDI)MMDRV_Alloc(sizeof(WINE_MIDI), MMDRV_MIDIIN, &hMidiIn, &dwFlags, &dwCallback, &dwInstance); if (lpwm == NULL) return MMSYSERR_NOMEM; lpwm->mod.hMidi = hMidiIn; lpwm->mod.dwCallback = dwCallback; lpwm->mod.dwInstance = dwInstance; lpwm->mld.uDeviceID = uDeviceID; dwRet = MMDRV_Open(&lpwm->mld, MIDM_OPEN, (DWORD_PTR)&lpwm->mod, dwFlags); if (dwRet != MMSYSERR_NOERROR) { MMDRV_Free(hMidiIn, &lpwm->mld); hMidiIn = 0; } if (lphMidiIn != NULL) *lphMidiIn = hMidiIn; TRACE("=> %d hMidi=%p\n", dwRet, hMidiIn); return dwRet; }
/************************************************************************** * midiStreamOpen [WINMM.@] */ MMRESULT WINAPI midiStreamOpen(HMIDISTRM* lphMidiStrm, LPUINT lpuDeviceID, DWORD cMidi, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen) { WINE_MIDIStream* lpMidiStrm; MMRESULT ret; MIDIOPENSTRMID mosm; LPWINE_MIDI lpwm; HMIDIOUT hMidiOut; TRACE("(%p, %p, %d, 0x%08lx, 0x%08lx, 0x%08x)!\n", lphMidiStrm, lpuDeviceID, cMidi, dwCallback, dwInstance, fdwOpen); if (cMidi != 1 || lphMidiStrm == NULL || lpuDeviceID == NULL) return MMSYSERR_INVALPARAM; ret = WINMM_CheckCallback(dwCallback, fdwOpen, FALSE); if (ret != MMSYSERR_NOERROR) return ret; lpMidiStrm = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_MIDIStream)); if (!lpMidiStrm) return MMSYSERR_NOMEM; lpMidiStrm->dwTempo = 500000; lpMidiStrm->dwTimeDiv = 480; /* 480 is 120 quarter notes per minute *//* FIXME ??*/ lpMidiStrm->dwPositionMS = 0; mosm.dwStreamID = (DWORD)lpMidiStrm; /* FIXME: the correct value is not allocated yet for MAPPER */ mosm.wDeviceID = *lpuDeviceID; lpwm = MIDI_OutAlloc(&hMidiOut, &dwCallback, &dwInstance, &fdwOpen, 1, &mosm); if (!lpwm) { HeapFree(GetProcessHeap(), 0, lpMidiStrm); return MMSYSERR_NOMEM; } lpMidiStrm->hDevice = hMidiOut; *lphMidiStrm = (HMIDISTRM)hMidiOut; lpwm->mld.uDeviceID = *lpuDeviceID; ret = MMDRV_Open(&lpwm->mld, MODM_OPEN, (DWORD_PTR)&lpwm->mod, fdwOpen); if (ret != MMSYSERR_NOERROR) { MMDRV_Free(hMidiOut, &lpwm->mld); HeapFree(GetProcessHeap(), 0, lpMidiStrm); return ret; } lpMidiStrm->hEvent = CreateEventW(NULL, FALSE, FALSE, NULL); lpMidiStrm->wFlags = HIWORD(fdwOpen); lpMidiStrm->hThread = CreateThread(NULL, 0, MMSYSTEM_MidiStream_Player, lpMidiStrm, 0, &(lpMidiStrm->dwThreadID)); if (!lpMidiStrm->hThread) { midiStreamClose((HMIDISTRM)hMidiOut); return MMSYSERR_NOMEM; } SetThreadPriority(lpMidiStrm->hThread, THREAD_PRIORITY_TIME_CRITICAL); /* wait for thread to have started, and for its queue to be created */ WaitForSingleObject(lpMidiStrm->hEvent, INFINITE); PostThreadMessageA(lpMidiStrm->dwThreadID, WINE_MSM_PAUSE, 0, 0); TRACE("=> (%u/%d) hMidi=%p ret=%d lpMidiStrm=%p\n", *lpuDeviceID, lpwm->mld.uDeviceID, *lphMidiStrm, ret, lpMidiStrm); return ret; }