INT CMidiDevice::GetDevOutID() { UINT uDeviceOutID; MMRESULT Result = midiOutGetID(m_hMidiOut, &uDeviceOutID); if(Result != MMSYSERR_NOERROR) { return -1; } return uDeviceOutID; }
static void test_midiOut_device(UINT udev, HWND hwnd) { HMIDIOUT hm; MMRESULT rc; MIDIOUTCAPSA capsA; DWORD ovolume; UINT udevid; MIDIHDR mhdr; rc = midiOutGetDevCapsA(udev, &capsA, sizeof(capsA)); ok(!rc, "midiOutGetDevCaps(dev=%d) rc=%s\n", udev, mmsys_error(rc)); if (!rc) { trace("* %s: manufacturer=%d, product=%d, tech=%d, support=%X: %d voices, %d notes\n", capsA.szPname, capsA.wMid, capsA.wPid, capsA.wTechnology, capsA.dwSupport, capsA.wVoices, capsA.wNotes); ok(!((MIDIMAPPER==udev) ^ (MOD_MAPPER==capsA.wTechnology)), "technology %d on device %d\n", capsA.wTechnology, udev); if (MOD_MIDIPORT == capsA.wTechnology) { ok(capsA.wVoices == 0 && capsA.wNotes == 0, "external device with notes or voices\n"); ok(capsA.wChannelMask == 0xFFFF, "external device channel mask %x\n", capsA.wChannelMask); ok(!(capsA.dwSupport & (MIDICAPS_VOLUME|MIDICAPS_LRVOLUME|MIDICAPS_CACHE)), "external device support=%X\n", capsA.dwSupport); } } if (hwnd) rc = midiOutOpen(&hm, udev, (DWORD_PTR)hwnd, (DWORD_PTR)MYCBINST, CALLBACK_WINDOW); else rc = midiOutOpen(&hm, udev, (DWORD_PTR)callback_func, (DWORD_PTR)MYCBINST, CALLBACK_FUNCTION); if (rc == MMSYSERR_NOTSUPPORTED) { skip( "MIDI out not supported\n" ); return; } ok(!rc, "midiOutOpen(dev=%d) rc=%s\n", udev, mmsys_error(rc)); if (rc) return; test_notification(hwnd, "midiOutOpen", MOM_OPEN, 0); rc = midiOutGetVolume(hm, &ovolume); ok((capsA.dwSupport & MIDICAPS_VOLUME) ? rc==MMSYSERR_NOERROR : rc==MMSYSERR_NOTSUPPORTED, "midiOutGetVolume rc=%s\n", mmsys_error(rc)); /* The native mapper responds with FFFFFFFF initially, * real devices with the volume GUI SW-synth settings. */ if (!rc) trace("Current volume %x on device %d\n", ovolume, udev); /* The W95 ESFM Synthesis device reports NOTENABLED although * GetVolume by handle works and music plays. */ rc = midiOutGetVolume(UlongToHandle(udev), &ovolume); ok((capsA.dwSupport & MIDICAPS_VOLUME) ? rc==MMSYSERR_NOERROR || broken(rc==MMSYSERR_NOTENABLED) : rc==MMSYSERR_NOTSUPPORTED, "midiOutGetVolume(dev=%d) rc=%s\n", udev, mmsys_error(rc)); rc = midiOutGetVolume(hm, NULL); ok(rc==MMSYSERR_INVALPARAM, "midiOutGetVolume NULL rc=%s\n", mmsys_error(rc)); /* Tests with midiOutSetvolume show that the midi mapper forwards * the value to the real device, but Get initially always reports * FFFFFFFF. Therefore, a Get+SetVolume pair with the mapper is * not adequate to restore the value prior to tests. */ if (winetest_interactive && (capsA.dwSupport & MIDICAPS_VOLUME)) { DWORD volume2 = (ovolume < 0x80000000) ? 0xC000C000 : 0x40004000; rc = midiOutSetVolume(hm, volume2); ok(!rc, "midiOutSetVolume rc=%s\n", mmsys_error(rc)); if (!rc) { DWORD volume3; rc = midiOutGetVolume(hm, &volume3); ok(!rc, "midiOutGetVolume new rc=%s\n", mmsys_error(rc)); if (!rc) trace("New volume %x on device %d\n", volume3, udev); todo_wine ok(volume2==volume3, "volume Set %x = Get %x\n", volume2, volume3); rc = midiOutSetVolume(hm, ovolume); ok(!rc, "midiOutSetVolume restore rc=%s\n", mmsys_error(rc)); } } rc = midiOutGetDevCapsA((UINT_PTR)hm, &capsA, sizeof(capsA)); ok(!rc, "midiOutGetDevCaps(dev=%d) by handle rc=%s\n", udev, mmsys_error(rc)); rc = midiInGetDevCapsA((UINT_PTR)hm, (LPMIDIINCAPSA)&capsA, sizeof(DWORD)); ok(rc==MMSYSERR_BADDEVICEID, "midiInGetDevCaps(dev=%d) by out handle rc=%s\n", udev, mmsys_error(rc)); { DWORD e = 0x006F4893; /* velocity, note (#69 would be 440Hz) channel */ trace("ShortMsg type %x\n", LOBYTE(LOWORD(e))); rc = midiOutShortMsg(hm, e); ok(!rc, "midiOutShortMsg rc=%s\n", mmsys_error(rc)); if (!rc) Sleep(400); /* Hear note */ } memset(&mhdr, 0, sizeof(mhdr)); mhdr.dwFlags = 0; mhdr.dwUser = 0x56FA552C; mhdr.dwOffset = 0xDEADBEEF; mhdr.dwBufferLength = 70000; /* > 64KB! */ mhdr.lpData = HeapAlloc(GetProcessHeap(), 0 , mhdr.dwBufferLength); ok(mhdr.lpData!=NULL, "No %d bytes of memory!\n", mhdr.dwBufferLength); if (mhdr.lpData) { rc = midiOutLongMsg(hm, &mhdr, sizeof(mhdr)); ok(rc==MIDIERR_UNPREPARED, "midiOutLongMsg unprepared rc=%s\n", mmsys_error(rc)); test_notification(hwnd, "midiOutLong unprepared", 0, WHATEVER); rc = midiOutPrepareHeader(hm, &mhdr, offsetof(MIDIHDR,dwOffset)-1); ok(rc==MMSYSERR_INVALPARAM, "midiOutPrepare tiny rc=%s\n", mmsys_error(rc)); rc = midiOutPrepareHeader(hm, &mhdr, offsetof(MIDIHDR,dwOffset)); ok(!rc, "midiOutPrepare old size rc=%s\n", mmsys_error(rc)); rc = midiOutPrepareHeader(hm, &mhdr, sizeof(mhdr)); ok(!rc, "midiOutPrepare rc=%s\n", mmsys_error(rc)); rc = midiOutUnprepareHeader(hm, &mhdr, sizeof(mhdr)); ok(!rc, "midiOutUnprepare rc=%s\n", mmsys_error(rc)); trace("MIDIHDR flags=%x when unsent\n", mhdr.dwFlags); HeapFree(GetProcessHeap(), 0, mhdr.lpData); } ok(mhdr.dwUser==0x56FA552C, "MIDIHDR.dwUser changed to %lx\n", mhdr.dwUser); ok(mhdr.dwOffset==0xDEADBEEF, "MIDIHDR.dwOffset changed to %x\n", mhdr.dwOffset); rc = midiOutGetID(hm, &udevid); ok(!rc, "midiOutGetID rc=%s\n", mmsys_error(rc)); if(!rc) ok(udevid==udev, "midiOutGetID gives %d, expect %d\n", udevid, udev); rc = midiOutReset(hm); /* Quiet everything */ ok(!rc, "midiOutReset rc=%s\n", mmsys_error(rc)); rc = midiOutClose(hm); ok(!rc, "midiOutClose rc=%s\n", mmsys_error(rc)); test_notification(hwnd, "midiOutClose", MOM_CLOSE, 0); test_notification(hwnd, "midiOut over", 0, WHATEVER); }