2017-05-18 14:03:43 -04:00
|
|
|
#include <windows.h>
|
|
|
|
|
#include <mmsystem.h>
|
2017-09-25 04:31:20 -04:00
|
|
|
#include <stdint.h>
|
2018-05-21 19:04:05 +02:00
|
|
|
#include <stdio.h>
|
2017-09-25 04:31:20 -04:00
|
|
|
#include <string.h>
|
|
|
|
|
#include <wchar.h>
|
2017-10-17 01:59:09 -04:00
|
|
|
#include "../86box.h"
|
2017-05-18 14:03:43 -04:00
|
|
|
#include "../config.h"
|
2017-08-27 04:33:47 +01:00
|
|
|
#include "../sound/midi.h"
|
2017-10-11 05:40:44 -04:00
|
|
|
#include "../plat.h"
|
|
|
|
|
#include "../plat_midi.h"
|
2017-05-18 14:03:43 -04:00
|
|
|
|
2017-07-15 20:07:38 +02:00
|
|
|
|
2018-09-11 22:41:14 +02:00
|
|
|
typedef struct
|
2017-07-15 20:07:38 +02:00
|
|
|
{
|
2018-09-11 22:41:14 +02:00
|
|
|
int midi_id;
|
|
|
|
|
|
|
|
|
|
HANDLE m_event;
|
|
|
|
|
|
|
|
|
|
HMIDIOUT midi_out_device;
|
|
|
|
|
|
|
|
|
|
MIDIHDR m_hdr;
|
|
|
|
|
} plat_midi_t;
|
|
|
|
|
|
|
|
|
|
plat_midi_t *pm = NULL;
|
2017-06-19 06:46:08 +02:00
|
|
|
|
2017-05-18 14:03:43 -04:00
|
|
|
|
2018-09-11 22:41:14 +02:00
|
|
|
void
|
|
|
|
|
plat_midi_init(void)
|
|
|
|
|
{
|
|
|
|
|
MMRESULT hr;
|
|
|
|
|
|
|
|
|
|
pm = (plat_midi_t *) malloc(sizeof(plat_midi_t));
|
|
|
|
|
memset(pm, 0, sizeof(plat_midi_t));
|
2017-07-15 20:07:38 +02:00
|
|
|
|
2018-09-11 22:41:14 +02:00
|
|
|
pm->midi_id = config_get_int(SYSTEM_MIDI_NAME, "midi", 0);
|
2017-07-15 20:07:38 +02:00
|
|
|
|
2018-09-11 22:41:14 +02:00
|
|
|
hr = MMSYSERR_NOERROR;
|
2017-05-18 14:03:43 -04:00
|
|
|
|
2018-09-11 22:41:14 +02:00
|
|
|
pm->m_event = CreateEvent(NULL, TRUE, TRUE, NULL);
|
2017-07-15 20:07:38 +02:00
|
|
|
|
2018-09-11 22:41:14 +02:00
|
|
|
hr = midiOutOpen(&pm->midi_out_device, pm->midi_id,
|
|
|
|
|
(uintptr_t) pm->m_event, 0, CALLBACK_EVENT);
|
|
|
|
|
if (hr != MMSYSERR_NOERROR) {
|
|
|
|
|
printf("midiOutOpen error - %08X\n", hr);
|
|
|
|
|
pm->midi_id = 0;
|
|
|
|
|
hr = midiOutOpen(&pm->midi_out_device, pm->midi_id,
|
|
|
|
|
(uintptr_t) pm->m_event, 0, CALLBACK_EVENT);
|
|
|
|
|
if (hr != MMSYSERR_NOERROR) {
|
|
|
|
|
printf("midiOutOpen error - %08X\n", hr);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-06-19 06:46:08 +02:00
|
|
|
|
2018-09-11 22:41:14 +02:00
|
|
|
midiOutReset(pm->midi_out_device);
|
2017-05-18 14:03:43 -04:00
|
|
|
}
|
|
|
|
|
|
2018-09-11 22:41:14 +02:00
|
|
|
|
|
|
|
|
void
|
|
|
|
|
plat_midi_close(void)
|
2017-05-18 14:03:43 -04:00
|
|
|
{
|
2018-09-11 22:41:14 +02:00
|
|
|
if (pm) {
|
|
|
|
|
if (pm->midi_out_device != NULL) {
|
|
|
|
|
midiOutReset(pm->midi_out_device);
|
|
|
|
|
midiOutClose(pm->midi_out_device);
|
|
|
|
|
CloseHandle(pm->m_event);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(pm);
|
|
|
|
|
pm = NULL;
|
|
|
|
|
}
|
2017-05-18 14:03:43 -04:00
|
|
|
}
|
|
|
|
|
|
2018-09-11 22:41:14 +02:00
|
|
|
|
|
|
|
|
int
|
|
|
|
|
plat_midi_get_num_devs(void)
|
2017-05-18 14:03:43 -04:00
|
|
|
{
|
2018-09-11 22:41:14 +02:00
|
|
|
return midiOutGetNumDevs();
|
2017-05-18 14:03:43 -04:00
|
|
|
}
|
2018-09-11 22:41:14 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
plat_midi_get_dev_name(int num, char *s)
|
2017-05-18 14:03:43 -04:00
|
|
|
{
|
2018-09-11 22:41:14 +02:00
|
|
|
MIDIOUTCAPS caps;
|
2017-05-18 14:03:43 -04:00
|
|
|
|
2018-09-11 22:41:14 +02:00
|
|
|
midiOutGetDevCaps(num, &caps, sizeof(caps));
|
|
|
|
|
strcpy(s, caps.szPname);
|
2017-05-18 14:03:43 -04:00
|
|
|
}
|
|
|
|
|
|
2018-09-11 22:41:14 +02:00
|
|
|
|
|
|
|
|
void
|
|
|
|
|
plat_midi_play_msg(uint8_t *msg)
|
2017-05-18 14:03:43 -04:00
|
|
|
{
|
2018-09-11 22:41:14 +02:00
|
|
|
if (!pm)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
midiOutShortMsg(pm->midi_out_device, *(uint32_t *) msg);
|
2017-05-18 14:03:43 -04:00
|
|
|
}
|
|
|
|
|
|
2017-07-15 20:07:38 +02:00
|
|
|
|
2018-09-11 22:41:14 +02:00
|
|
|
void
|
|
|
|
|
plat_midi_play_sysex(uint8_t *sysex, unsigned int len)
|
2017-05-18 14:03:43 -04:00
|
|
|
{
|
2018-09-11 22:41:14 +02:00
|
|
|
MMRESULT result;
|
2017-05-18 14:03:43 -04:00
|
|
|
|
2018-09-11 22:41:14 +02:00
|
|
|
if (!pm)
|
|
|
|
|
return;
|
2017-05-18 14:03:43 -04:00
|
|
|
|
2018-09-11 22:41:14 +02:00
|
|
|
if (WaitForSingleObject(pm->m_event, 2000) == WAIT_TIMEOUT)
|
|
|
|
|
return;
|
2017-05-18 14:03:43 -04:00
|
|
|
|
2018-09-11 22:41:14 +02:00
|
|
|
midiOutUnprepareHeader(pm->midi_out_device, &pm->m_hdr, sizeof(pm->m_hdr));
|
2017-05-18 14:03:43 -04:00
|
|
|
|
2018-09-11 22:41:14 +02:00
|
|
|
pm->m_hdr.lpData = (char *) sysex;
|
|
|
|
|
pm->m_hdr.dwBufferLength = len;
|
|
|
|
|
pm->m_hdr.dwBytesRecorded = len;
|
|
|
|
|
pm->m_hdr.dwUser = 0;
|
2017-05-18 14:03:43 -04:00
|
|
|
|
2018-09-11 22:41:14 +02:00
|
|
|
result = midiOutPrepareHeader(pm->midi_out_device, &pm->m_hdr, sizeof(pm->m_hdr));
|
|
|
|
|
|
|
|
|
|
if (result != MMSYSERR_NOERROR)
|
|
|
|
|
return;
|
|
|
|
|
ResetEvent(pm->m_event);
|
|
|
|
|
result = midiOutLongMsg(pm->midi_out_device, &pm->m_hdr, sizeof(pm->m_hdr));
|
|
|
|
|
if (result != MMSYSERR_NOERROR) {
|
|
|
|
|
SetEvent(pm->m_event);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-05-18 14:03:43 -04:00
|
|
|
}
|
|
|
|
|
|
2018-09-11 22:41:14 +02:00
|
|
|
|
|
|
|
|
int
|
|
|
|
|
plat_midi_write(uint8_t val)
|
2017-05-18 14:03:43 -04:00
|
|
|
{
|
2018-09-11 22:41:14 +02:00
|
|
|
return 0;
|
2017-05-18 14:03:43 -04:00
|
|
|
}
|