Files
86Box/src/WIN/win_midi.c

131 lines
3.3 KiB
C
Raw Normal View History

2017-05-18 14:03:43 -04:00
#include <windows.h>
#include <mmsystem.h>
#include "../ibm.h"
#include "../config.h"
#include "../SOUND/midi.h"
2017-05-18 14:03:43 -04:00
#include "plat_midi.h"
typedef struct plat_midi_t
{
int id;
char name[512];
HMIDIOUT midi_out_device;
HANDLE event;
MIDIHDR hdr;
} plat_midi_t;
void* plat_midi_init()
2017-05-18 14:03:43 -04:00
{
plat_midi_t* data = malloc(sizeof(plat_midi_t));
memset(data, 0, sizeof(plat_midi_t));
/* This is for compatibility with old configuration files. */
data->id = config_get_int("Sound", "midi_host_device", -1);
if (data->id == -1)
{
data->id = config_get_int(SYSTEM_MIDI_NAME, "midi", 0);
}
else
{
config_delete_var("Sound", "midi_host_device");
config_set_int(SYSTEM_MIDI_NAME, "midi", data->id);
}
2017-05-18 14:03:43 -04:00
MMRESULT hr = MMSYSERR_NOERROR;
data->event = CreateEvent(NULL, TRUE, TRUE, NULL);
2017-05-18 14:03:43 -04:00
hr = midiOutOpen(&data->midi_out_device, data->id, (DWORD) data->event,
2017-05-18 14:03:43 -04:00
0, CALLBACK_EVENT);
if (hr != MMSYSERR_NOERROR) {
printf("midiOutOpen error - %08X\n",hr);
data->id = 0;
hr = midiOutOpen(&data->midi_out_device, data->id, (DWORD) data->event,
2017-05-18 14:03:43 -04:00
0, CALLBACK_EVENT);
if (hr != MMSYSERR_NOERROR) {
printf("midiOutOpen error - %08X\n",hr);
free(data);
return 0;
2017-05-18 14:03:43 -04:00
}
}
plat_midi_get_dev_name(data->id, data->name);
midiOutReset(data->midi_out_device);
return data;
2017-05-18 14:03:43 -04:00
}
void plat_midi_close(void* p)
2017-05-18 14:03:43 -04:00
{
plat_midi_t* data = (plat_midi_t*)p;
if (data->midi_out_device != NULL)
2017-05-18 14:03:43 -04:00
{
midiOutReset(data->midi_out_device);
midiOutClose(data->midi_out_device);
/* midi_out_device = NULL; */
CloseHandle(data->event);
2017-05-18 14:03:43 -04:00
}
free(data);
2017-05-18 14:03:43 -04:00
}
int plat_midi_get_num_devs()
2017-05-18 14:03:43 -04:00
{
return midiOutGetNumDevs();
}
void plat_midi_get_dev_name(int num, char *s)
2017-05-18 14:03:43 -04:00
{
MIDIOUTCAPS caps;
midiOutGetDevCaps(num, &caps, sizeof(caps));
strcpy(s, caps.szPname);
}
void plat_midi_play_msg(midi_device_t* device, uint8_t *msg)
2017-05-18 14:03:43 -04:00
{
plat_midi_t* data = (plat_midi_t*)device->data;
midiOutShortMsg(data->midi_out_device, *(uint32_t *) msg);
2017-05-18 14:03:43 -04:00
}
void plat_midi_play_sysex(midi_device_t* device, uint8_t *sysex, unsigned int len)
2017-05-18 14:03:43 -04:00
{
plat_midi_t* data = (plat_midi_t*)device->data;
2017-05-18 14:03:43 -04:00
MMRESULT result;
if (WaitForSingleObject(data->event, 2000) == WAIT_TIMEOUT)
2017-05-18 14:03:43 -04:00
{
pclog("Can't send MIDI message\n");
return;
}
midiOutUnprepareHeader(data->midi_out_device, &data->hdr, sizeof(data->hdr));
2017-05-18 14:03:43 -04:00
data->hdr.lpData = (char *) sysex;
data->hdr.dwBufferLength = len;
data->hdr.dwBytesRecorded = len;
data->hdr.dwUser = 0;
2017-05-18 14:03:43 -04:00
result = midiOutPrepareHeader(data->midi_out_device, &data->hdr, sizeof(data->hdr));
2017-05-18 14:03:43 -04:00
if (result != MMSYSERR_NOERROR) return;
ResetEvent(data->event);
result = midiOutLongMsg(data->midi_out_device, &data->hdr, sizeof(data->hdr));
2017-05-18 14:03:43 -04:00
if (result != MMSYSERR_NOERROR)
{
SetEvent(data->event);
2017-05-18 14:03:43 -04:00
return;
}
}
int plat_midi_write(midi_device_t* device, uint8_t val)
2017-05-18 14:03:43 -04:00
{
return 0;
2017-05-18 14:03:43 -04:00
}
void plat_midi_add_status_info(char *s, int max_len, struct midi_device_t* device)
{
char temps[512];
sprintf(temps, "MIDI out device: %s\n\n", ((plat_midi_t*)device->data)->name);
strncat(s, temps, max_len);
}