int WinMIDIDevice::Open(MidiCallback callback, void *userdata) { MMRESULT err; Callback = callback; CallbackData = userdata; if (MidiOut == nullptr) { err = midiStreamOpen(&MidiOut, &DeviceID, 1, (DWORD_PTR)CallbackFunc, (DWORD_PTR)this, CALLBACK_FUNCTION); if (err == MMSYSERR_NOERROR) { if (IgnoreMIDIVolume(DeviceID)) { VolumeWorks = false; } else { // Set master volume to full, if the device allows it on this interface. VolumeWorks = (MMSYSERR_NOERROR == midiOutGetVolume((HMIDIOUT)MidiOut, &SavedVolume)); if (VolumeWorks) { VolumeWorks &= (MMSYSERR_NOERROR == midiOutSetVolume((HMIDIOUT)MidiOut, 0xffffffff)); } } } else { return 1; } } return 0; }
int CMidi::SetVolume (int nVolume) { #if (defined (_WIN32) || USE_SDL_MIXER) int nLastVolume = m_nVolume; if (nVolume < 0) m_nVolume = 0; else if (nVolume > 127) m_nVolume = 127; else m_nVolume = nVolume; # if USE_SDL_MIXER if (gameOpts->sound.bUseSDLMixer) Mix_VolumeMusic (m_nVolume); # endif # if defined (_WIN32) # if USE_SDL_MIXER else # endif if (m_hmp) { int mmVolume; // scale up from 0-127 to 0-0xffff mmVolume = (m_nVolume << 1) | (m_nVolume & 1); mmVolume |= (mmVolume << 8); nVolume = midiOutSetVolume ((HMIDIOUT)m_hmp->hmidi, mmVolume | (mmVolume << 16)); } # endif return nLastVolume; #else return 0; #endif }
void DigiSetMidiVolume(int n) { if (n < 0) midi_volume = 0; else if (n > 127) midi_volume = 127; else midi_volume = n; #if USE_SDL_MIXER if (gameOpts->sound.bUseSDLMixer) Mix_VolumeMusic (midi_volume); #endif #if defined (_WIN32) # if USE_SDL_MIXER else # endif if (hmp) { int mm_volume; // scale up from 0-127 to 0-0xffff mm_volume = (midi_volume << 1) | (midi_volume & 1); mm_volume |= (mm_volume << 8); n = midiOutSetVolume((HMIDIOUT)hmp->hmidi, mm_volume | (mm_volume << 16)); } #endif }
void native_midi_setvolume(int volume) //maks { //maks: //Some devices use 16 bit to represend left and right channel //So, using only MAKEWORD(calcVolume , calcVolume) results on a 0x0000VVVV //format, thats causes midi pan set to left, always. //To solve this problem, copy the low WORD to high word make the format 0xVVVVVVVV int calcVolume = volume << 1; unsigned long i = 0; DWORD dwVolume, longVolume; if(calcVolume > 255) { calcVolume = 255; } else if (calcVolume < 0) { calcVolume = 0; } dwVolume = MAKEWORD(calcVolume , calcVolume); longVolume = MAKELONG(dwVolume , dwVolume); midiOutSetVolume((HMIDIOUT)hMidiStream, longVolume); }
void I_midiOutSetVolumes(int volume) { // NSM changed to work on the 0-15 volume scale, // and to check mus_extend_volume itself. MMRESULT result; int calcVolume; MIDIOUTCAPS capabilities; unsigned int i; if (volume > 15) volume = 15; if (volume < 0) volume = 0; calcVolume = (65535 * volume / 15); //SDL_LockAudio(); // this function doesn't touch anything the audio callback touches //Device loop for (i = 0; i < midiOutGetNumDevs(); i++) { //Get device capabilities result = midiOutGetDevCaps(i, &capabilities, sizeof(capabilities)); if (result == MMSYSERR_NOERROR) { //Adjust volume on this candidate if ((capabilities.dwSupport & MIDICAPS_VOLUME)) { midiOutSetVolume((HMIDIOUT)i, MAKELONG(calcVolume, calcVolume)); } } } //SDL_UnlockAudio(); }
void native_midi_setvolume(int volume) { int calcVolume; if (volume > 128) volume = 128; if (volume < 0) volume = 0; calcVolume = (65535 * volume / 128); midiOutSetVolume((HMIDIOUT)hMidiStream, MAKELONG(calcVolume , calcVolume)); }
void WinMIDIDevice::Stop() { if (PlayerThread != nullptr) { SetEvent(ExitEvent); WaitForSingleObject(PlayerThread, INFINITE); CloseHandle(PlayerThread); PlayerThread = nullptr; } midiStreamStop(MidiOut); midiOutReset((HMIDIOUT)MidiOut); if (VolumeWorks) { midiOutSetVolume((HMIDIOUT)MidiOut, SavedVolume); } }
void digi_set_midi_volume( int n ) { int mm_volume; if (n < 0) midi_volume = 0; else if (n > 127) midi_volume = 127; else midi_volume = n; // scale up from 0-127 to 0-0xffff mm_volume = (midi_volume << 1) | (midi_volume & 1); mm_volume |= (mm_volume << 8); if (hmp) midiOutSetVolume((HMIDIOUT)hmp->hmidi, mm_volume | mm_volume << 16); }
void MIDISong2::Stop () { if (PlayerThread) { SetEvent (ExitEvent); WaitForSingleObject (PlayerThread, INFINITE); CloseHandle (PlayerThread); PlayerThread = NULL; } if (MidiOut) { midiOutReset (MidiOut); if (VolumeWorks) { midiOutSetVolume (MidiOut, SavedVolume); } midiOutClose (MidiOut); MidiOut = NULL; } }
void archMidiOutDestroy(ArchMidi* archMidi) { if (archMidi->devInfo == NULL) { free(archMidi); return; } if (--archMidi->devInfo->refCount > 0) { free(archMidi); return; } midiOutSetVolume((HMIDIOUT)archMidi->devInfo->handle, archMidi->devInfo->origVolume); midiOutClose((HMIDIOUT)archMidi->devInfo->handle); if (archMidi->devInfo == midi.out.current[0]) midi.out.current[0] = NULL; if (archMidi->devInfo == midi.out.current[1]) midi.out.current[1] = NULL; free(archMidi); }
// MIDI stuff follows. void digi_audio_set_midi_volume( int mvolume ) { #ifdef _WIN32 int mm_volume; if (mvolume < 0) midi_volume = 0; else if (mvolume > 127) midi_volume = 127; else midi_volume = mvolume; // scale up from 0-127 to 0-0xffff mm_volume = (midi_volume << 1) | (midi_volume & 1); mm_volume |= (mm_volume << 8); if (hmp) midiOutSetVolume((HMIDIOUT)hmp->hmidi, mm_volume | mm_volume << 16); #endif }
// // I_ResetMidiVolume() // // [SL] 2011-12-31 - Set all midi devices' output volume to maximum in the OS. // This function is used to work around shortcomings of the SDL_Mixer library // on the Windows Vista/7 platform, where PCM and MIDI volumes are linked // together in the OS's audio mixer. Because SDL_Mixer sets the volume of // midi output devices to 0 when not playing music, all sound // output (PCM & MIDI) becomes muted in Odamex (see Odamex bug 443). // void I_ResetMidiVolume() { #if defined(_WIN32) && !defined(_XBOX) SDL_LockAudio(); for (UINT device = MIDI_MAPPER; device != midiOutGetNumDevs(); device++) { MIDIOUTCAPS caps; // Can this midi device change volume? MMRESULT result = midiOutGetDevCaps(device, &caps, sizeof(caps)); // Set the midi device's volume static const DWORD volume = 0xFFFFFFFF; // maximum volume if (result == MMSYSERR_NOERROR && (caps.dwSupport & MIDICAPS_VOLUME)) midiOutSetVolume((HMIDIOUT)device, volume); } SDL_UnlockAudio(); #endif // _WIN32 }
void archMidiEnable(int enable) { int i; midi.enabled = enable; if (midi.out.current[0] != NULL) { midiOutSetVolume((HMIDIOUT)midi.out.current[0]->handle, midi.out.volume * midi.enabled); } for (i = 0; i < 2; i++) { if (midi.in.current[i] != NULL) { if (enable && !midi.in.current[i]->recording) { midiInStart((HMIDIIN)midi.in.current[i]->handle); midi.in.current[i]->recording = 1; } else if (!enable && midi.in.current[i]->recording) { midiInStop((HMIDIIN)midi.in.current[i]->handle); midi.in.current[i]->recording = 0; } } } }
void digi_mixer_set_midi_volume( int mvolume ) { #ifdef _WIN32 int mm_volume; if (mvolume < 0) midi_volume = 0; else if (mvolume > 127) midi_volume = 127; else midi_volume = mvolume; // scale up from 0-127 to 0-0xffff mm_volume = (midi_volume << 1) | (midi_volume & 1); mm_volume |= (mm_volume << 8); if (hmp) midiOutSetVolume((HMIDIOUT)hmp->hmidi, mm_volume | mm_volume << 16); #endif midi_volume = mvolume; if (!digi_initialised) return; mix_set_music_volume(mvolume); }
static void MidiIntSetVolume(int vol) { DWORD v = (vol * 65535 / 127); midiOutSetVolume((HMIDIOUT)_midi.devid, v + (v << 16)); }
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); }
/* midi_win32_set_mixer_volume: */ int midi_win32_set_mixer_volume(int volume) { unsigned long win32_midi_vol = (volume << 8) + (volume << 24); midiOutSetVolume(midi_device, win32_midi_vol); return 1; }
void MIDISong2::Play (bool looping) { MIDIOUTCAPS caps; DWORD tid; m_Status = STATE_Stopped; m_Looping = looping; // Find out if this an FM synth or not for EMIDI DesignationMask = 0xFF0F; if (MMSYSERR_NOERROR == midiOutGetDevCaps (mididevice, &caps, sizeof(caps))) { if (caps.wTechnology == MOD_FMSYNTH) { DesignationMask = 0x00F0; } else if (caps.wTechnology == MOD_MIDIPORT) { DesignationMask = 0x0001; } } if (MMSYSERR_NOERROR != midiOutOpen (&MidiOut, mididevice, 0, 0, CALLBACK_NULL)) { Printf (PRINT_BOLD, "Could not open MIDI out device\n"); return; } // Try two different methods for setting the stream to full volume. // Unfortunately, this isn't as reliable as it once was, which is a pity. // The real volume selection is done by setting the volume controller for // each channel. Because every General MIDI-compliant device must support // this controller, it is the most reliable means of setting the volume. VolumeWorks = (MMSYSERR_NOERROR == midiOutGetVolume (MidiOut, &SavedVolume)); if (VolumeWorks) { VolumeWorks &= (MMSYSERR_NOERROR == midiOutSetVolume (MidiOut, 0xffffffff)); } else { // Send the standard SysEx message for full master volume BYTE volmess[] = { 0xf0, 0x7f, 0x7f, 0x04, 0x01, 0x7f, 0x7f, 0xf7 }; MIDIHDR hdr = { (LPSTR)volmess, sizeof(volmess), }; if (MMSYSERR_NOERROR == midiOutPrepareHeader (MidiOut, &hdr, sizeof(hdr))) { midiOutLongMsg (MidiOut, &hdr, sizeof(hdr)); while (MIDIERR_STILLPLAYING == midiOutUnprepareHeader (MidiOut, &hdr, sizeof(hdr))) { Sleep (10); } } } snd_midivolume.Callback(); // set volume to current music's properties PlayerThread = CreateThread (NULL, 0, PlayerProc, this, 0, &tid); if (PlayerThread == NULL) { if (VolumeWorks) { midiOutSetVolume (MidiOut, SavedVolume); } midiOutClose (MidiOut); MidiOut = NULL; } m_Status = STATE_Playing; }