Пример #1
0
MF_API void MFMidi_SendPacket(MFDevice *pDevice, const uint8 *pBytes, size_t len)
{
	MFMidiPC_MidiOutputDevice *pMidi = (MFMidiPC_MidiOutputDevice*)pDevice->pInternal;

	// TODO: get hdr from pool...
	MIDIHDR hdr;
	MFZeroMemory(&hdr, sizeof(hdr));
	hdr.lpData = (LPSTR)pBytes;
	hdr.dwBufferLength = (DWORD)len;
	hdr.dwBytesRecorded = (DWORD)len;
	hdr.dwUser = (DWORD_PTR)pDevice;

	MMRESULT r = midiOutPrepareHeader(pMidi->hMidiOut, &hdr, sizeof(hdr));
	if (r != MMSYSERR_NOERROR)
	{
		wchar_t errorBuffer[256];
		midiOutGetErrorText(r, errorBuffer, sizeof(errorBuffer));
		MFDebug_Warn(1, MFStr("Failed to send MIDI message: %s", MFString_WCharAsUTF8(errorBuffer)));
		return;
	}

	r = midiOutLongMsg(pMidi->hMidiOut, &hdr, sizeof(hdr));
	if (r != MMSYSERR_NOERROR)
	{
		wchar_t errorBuffer[256];
		midiOutGetErrorText(r, errorBuffer, sizeof(errorBuffer));
		MFDebug_Warn(1, MFStr("Failed to send MIDI message: %s", MFString_WCharAsUTF8(errorBuffer)));
	}
}
Пример #2
0
void MidiDriver_WIN::check_error(MMRESULT result) {
	char buf[200];
	if (result != MMSYSERR_NOERROR) {
		midiOutGetErrorText(result, buf, 200);
		warning("MM System Error '%s'", buf);
	}
}
Пример #3
0
static void winmm_get_host_error(PmInternal * midi, char * msg, UINT len)
{
    /* precondition: midi != NULL */
    midiwinmm_node * m = (midiwinmm_node *) midi->descriptor;
    char *hdr1 = "Host error: ";
    char *hdr2 = "Host callback error: ";

    msg[0] = 0; /* initialize result string to empty */

    if (descriptors[midi->device_id].pub.input) {
        /* input and output use different winmm API calls */
        if (m) { /* make sure there is an open device to examine */
            if (m->error != MMSYSERR_NOERROR) {
                int n = str_copy_len(msg, hdr1, len);
                /* read and record host error */
                int err = midiInGetErrorText(m->error, msg + n, len - n);
                assert(err == MMSYSERR_NOERROR);
                m->error = MMSYSERR_NOERROR;
            }
        }
    } else { /* output port */
        if (m) {
            if (m->error != MMSYSERR_NOERROR) {
                int n = str_copy_len(msg, hdr1, len);
                int err = midiOutGetErrorText(m->error, msg + n, len - n);
                assert(err == MMSYSERR_NOERROR);
                m->error = MMSYSERR_NOERROR;
            }
        }
    }
}
Пример #4
0
static void CALLBACK MidiOutProc(HMIDIOUT hMidiOut, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
	MFDevice *pDevice = (MFDevice*)dwInstance;
	MFMidiPC_MidiOutputDevice *pMidi = (MFMidiPC_MidiOutputDevice*)pDevice->pInternal;

	switch (wMsg)
	{
		case MOM_OPEN:
			MFDebug_Log(0, MFStr("Opened MIDI output device: %s", pDevice->strings[MFDS_ID]));
			break;
		case MOM_CLOSE:
			MFDebug_Log(0, MFStr("Opened MIDI output device: %s", pDevice->strings[MFDS_ID]));
			break;
		case MOM_DONE:
		{
			MIDIHDR *pHdr = (MIDIHDR*)dwParam1;
			MMRESULT r = midiOutUnprepareHeader(pMidi->hMidiOut, pHdr, sizeof(*pHdr));
			if (r != MMSYSERR_NOERROR)
			{
				wchar_t errorBuffer[256];
				midiOutGetErrorText(r, errorBuffer, sizeof(errorBuffer));
				MFDebug_Warn(1, MFStr("Failed to cleanup MIDI message: %s", MFString_WCharAsUTF8(errorBuffer)));
			}
			// TODO: return to pool...
			break;
		}
		case MOM_POSITIONCB:
			MFDebug_Log(0, "MIDI output device: Position CB");
			break;
	}
}
Пример #5
0
MF_API bool MFMidi_OpenOutput(MFDevice *pDevice)
{
	MFDebug_Assert(pDevice->type == MFDT_MidiOutput, "Not a MIDI device!");

	if (pDevice->state == MFDevState_Ready)
	{
		MFDebug_Warn(1, "Midi output device already opened!");
		return false;
	}
	if (pDevice->state != MFDevState_Available)
	{
		MFDebug_Warn(1, "Unable to open midi output device!");
		return false;
	}

	MFMidiPC_MidiOutputDevice *pMidi = (MFMidiPC_MidiOutputDevice*)pDevice->pInternal;

	// find and open the device
	// TODO: FIXME! this won't work if there are 2 instances of the same device attached to the PC!!!
	UINT numOutputDevices = midiOutGetNumDevs();
	UINT i = 0;
	for (; i < numOutputDevices; ++i)
	{
		MIDIOUTCAPS caps;
		MMRESULT r = midiOutGetDevCaps(i, &caps, sizeof(caps));
		if (r != MMSYSERR_NOERROR)
			continue;

		if (caps.wMid == pMidi->mid && caps.wPid == pMidi->pid)
			break;
	}
	if (i == numOutputDevices)
	{
		MFDebug_Log(0, MFStr("Midi output device '%s' not found!", pDevice->strings[MFDS_ID]));
		pDevice->state = MFDevState_Unknown; // set this flag?
		return false;
	}

	MMRESULT r = midiOutOpen(&pMidi->hMidiOut, i, (DWORD_PTR)MidiOutProc, (DWORD_PTR)pDevice, CALLBACK_FUNCTION);
	if (r != MMSYSERR_NOERROR)
	{
		pMidi->hMidiOut = NULL;
		pDevice->state = MFDevState_Unknown;

		wchar_t errorBuffer[256];
		midiOutGetErrorText(r, errorBuffer, sizeof(errorBuffer));
		MFDebug_Warn(1, MFStr("Failed to open MIDI output device: %s", MFString_WCharAsUTF8(errorBuffer)));

		return false;
	}

	pDevice->state = MFDevState_Ready;

	return true;
}
Пример #6
0
MF_API void MFMidi_SendShortMessage(MFDevice *pDevice, uint32 message)
{
	MFMidiPC_MidiOutputDevice *pMidi = (MFMidiPC_MidiOutputDevice*)pDevice->pInternal;

	MMRESULT r = midiOutShortMsg(pMidi->hMidiOut, (DWORD)message);
	if (r != MMSYSERR_NOERROR)
	{
		wchar_t errorBuffer[256];
		midiOutGetErrorText(r, errorBuffer, sizeof(errorBuffer));
		MFDebug_Warn(1, MFStr("Failed to send MIDI message: %s", MFString_WCharAsUTF8(errorBuffer)));
	}
}
Пример #7
0
     QString mmErrorString(MMRESULT err)
     {
         QString errstr;
 #ifdef UNICODE
         WCHAR buffer[1024];
         midiInGetErrorText(err, &buffer[0], sizeof(buffer));
         errstr = QString::fromUtf16((const ushort*)buffer);
 #else
         char buffer[1024];
         midiOutGetErrorText(err, &buffer[0], sizeof(buffer));
         errstr = QString::fromLocal8Bit(buffer);
 #endif
         return errstr;
     }
Пример #8
0
//_________________________________________________________
static char *makeShortString (char *s, SlotRefNum ref, int errCode, short in)
{
	static char out[1024];
	char buff[kGetErrorTextBuf];
	TSlotInfos infos;

	if(in)
		midiInGetErrorText(errCode, buff, kGetErrorTextBuf);
	else
		midiOutGetErrorText(errCode, buff, kGetErrorTextBuf);
	infos.name[0] = 0;
	MidiGetSlotInfos (ref, &infos);
	wsprintf (out, "%s : %s error\n%s", infos.name, s, buff);
	return out;
}
Пример #9
0
void MidiUartWinClass::midiSendLong(unsigned char *buf, unsigned long len) {
  MIDIHDR midiHdr;

  midiHdr.lpData = (CHAR *)buf;
  midiHdr.dwBufferLength = len;
  midiHdr.dwFlags = 0;

  UINT err = midiOutPrepareHeader(outHandle, &midiHdr, sizeof(MIDIHDR));
  if (err) {
    char errBuf[256];
    midiOutGetErrorText(err, errBuf, sizeof(errBuf));
    printf("error sending long message: %s\n", errBuf);
  }

  while (MIDIERR_STILLPLAYING == midiOutUnprepareHeader(outHandle, &midiHdr, sizeof(MIDIHDR)))
    ;
}
Пример #10
0
static void s_SetMidiError(const char *reason, UINT val) {
	UINT retVal;
	char errBuffer[MAXERRORLENGTH];

	retVal = midiOutGetErrorText(val, errBuffer, MAXERRORLENGTH);
	if(retVal == MMSYSERR_NOERROR) {
	/* Returned OK.  Do nothing. */

	} else if(retVal == MMSYSERR_BADERRNUM) {
	sprintf(errBuffer, "Unrecognized MIDI error occurred (%d).", val);

	} else if(retVal == MMSYSERR_INVALPARAM) {
	sprintf(errBuffer, "Invalid error parameter found while retrieving error %d.", val);

	} else {
	sprintf(errBuffer, "Unknown error occurred while retrieving error %d.", val);
	}

	(void)PyErr_Format(PyExc_RuntimeError, "MIDI error encountered while %s: %s", reason, errBuffer);
}
Пример #11
0
void midiSendLong(unsigned char *buf, unsigned long len) {
  MIDIHDR midiHdr;
  HANDLE hBuffer;

  hBuffer = GlobalAlloc(GHND, len);
  if (!hBuffer) {
    logPrintf(LOG_ERROR, "error allocating buffer for sysex\n");
    return;
  } 

  midiHdr.lpData = (LPBYTE)GlobalLock(hBuffer);
  if (midiHdr.lpData) {
    midiHdr.dwBufferLength = len;
    midiHdr.dwFlags = 0;
    
    debugPrintf(2, "midiSendLong: \n");
    debugHexdump(2, buf, len);
    
    UINT err = midiOutPrepareHeader(outHandle, &midiHdr, sizeof(MIDIHDR));
    if (!err) {
      memcpy(midiHdr.lpData, buf, len);
      err = midiOutLongMsg(outHandle, &midiHdr, sizeof(MIDIHDR));
      if (err) {
	char errBuf[256];
	midiOutGetErrorText(err, errBuf, sizeof(errBuf));
	logPrintf(LOG_ERROR, "error sending long message: %s\n", errBuf);
	
      }
      while (MIDIERR_STILLPLAYING == midiOutUnprepareHeader(outHandle, &midiHdr, sizeof(MIDIHDR))) {
	;
	
      }
      debugPrintf(2, "midiSendLong finished\n");
    }
  }

  GlobalUnlock(hBuffer);
  GlobalFree(hBuffer);
    
}
Пример #12
0
/* see comments for winmm_in_close */
static PmError winmm_out_close(PmInternal *midi)
{
    midiwinmm_type m = (midiwinmm_type) midi->descriptor;
    if (m->handle.out) {
        /* device to close */
        if (midi->latency == 0) {
            pm_hosterror = midiOutClose(m->handle.out);
        } else {
            pm_hosterror = midiStreamClose(m->handle.stream);
        }
        /* regardless of outcome, free memory */
        winmm_out_delete(midi);
    }
    if (pm_hosterror) {
        int err = midiOutGetErrorText(pm_hosterror,
                                      (char *) pm_hosterror_text,
                                      PM_HOST_ERROR_MSG_LEN);
        assert(err == MMSYSERR_NOERROR);
        return pmHostError;
    }
    return pmNoError;
}
/* ------------------------- MIDI output -------------------------- */
static void msw_midiouterror(char *s, int err)
{
    char t[256];
    midiOutGetErrorText(err, t, 256);
    fprintf(stderr, s, t);
}
Пример #14
0
static PmError winmm_out_open(PmInternal *midi, void *driverInfo)
{
    DWORD dwDevice;
    int i = midi->device_id;
    midiwinmm_type m;
    MIDIPROPTEMPO propdata;
    MIDIPROPTIMEDIV divdata;
    int max_sysex_len = midi->buffer_len * 4;
    int output_buffer_len;
    int num_buffers;
    dwDevice = (DWORD) descriptors[i].descriptor;

    /* create system dependent device data */
    m = (midiwinmm_type) pm_alloc(sizeof(midiwinmm_node)); /* create */
    midi->descriptor = m;
    if (!m) goto no_memory;
    m->handle.out = NULL;
    m->buffers = NULL;
    m->num_buffers = 0;
    m->max_buffers = 0;
    m->buffers_expanded = FALSE;
    m->next_buffer = 0;
    m->last_time = 0;
    m->first_message = TRUE; /* we treat first message as special case */
    m->sysex_mode = FALSE;
    m->sysex_word = 0;
    m->sysex_byte_count = 0;
    m->hdr = NULL;
    m->sync_time = 0;
    m->delta = 0;
    m->error = MMSYSERR_NOERROR;

    /* create a signal */
    m->buffer_signal = CreateEvent(NULL, FALSE, FALSE, NULL);

    /* this should only fail when there are very serious problems */
    assert(m->buffer_signal);

    /* open device */
    if (midi->latency == 0) {
        /* use simple midi out calls */
        pm_hosterror = midiOutOpen(
                (LPHMIDIOUT) & m->handle.out,  /* device Handle */
		dwDevice,  /* device ID  */
		/* note: same callback fn as for StreamOpen: */
		(DWORD_PTR) winmm_streamout_callback, /* callback fn */
		(DWORD_PTR) midi,  /* callback instance data */
		CALLBACK_FUNCTION); /* callback type */
    } else {
        /* use stream-based midi output (schedulable in future) */
        pm_hosterror = midiStreamOpen(
	        &m->handle.stream,  /* device Handle */
		(LPUINT) & dwDevice,  /* device ID pointer */
		1,  /* reserved, must be 1 */
		(DWORD_PTR) winmm_streamout_callback,
		(DWORD_PTR) midi,  /* callback instance data */
		CALLBACK_FUNCTION);
    }
    if (pm_hosterror != MMSYSERR_NOERROR) {
        goto free_descriptor;
    }

    if (midi->latency == 0) {
        num_buffers = NUM_SIMPLE_SYSEX_BUFFERS;
        output_buffer_len = max_sysex_len / num_buffers;
        if (output_buffer_len < MIN_SIMPLE_SYSEX_LEN)
            output_buffer_len = MIN_SIMPLE_SYSEX_LEN;
    } else {
        long dur = 0;
        num_buffers = max(midi->buffer_len, midi->latency / 2);
        if (num_buffers < MIN_STREAM_BUFFERS)
            num_buffers = MIN_STREAM_BUFFERS;
        output_buffer_len = STREAM_BUFFER_LEN;

        propdata.cbStruct = sizeof(MIDIPROPTEMPO);
        propdata.dwTempo = 480000; /* microseconds per quarter */
        pm_hosterror = midiStreamProperty(m->handle.stream,
                                          (LPBYTE) & propdata,
                                          MIDIPROP_SET | MIDIPROP_TEMPO);
        if (pm_hosterror) goto close_device;

        divdata.cbStruct = sizeof(MIDIPROPTEMPO);
        divdata.dwTimeDiv = 480;   /* divisions per quarter */
        pm_hosterror = midiStreamProperty(m->handle.stream,
                                          (LPBYTE) & divdata,
                                          MIDIPROP_SET | MIDIPROP_TIMEDIV);
        if (pm_hosterror) goto close_device;
    }
    /* allocate buffers */
    if (allocate_buffers(m, output_buffer_len, num_buffers)) 
        goto free_buffers;
    /* start device */
    if (midi->latency != 0) {
        pm_hosterror = midiStreamRestart(m->handle.stream);
        if (pm_hosterror != MMSYSERR_NOERROR) goto free_buffers;
    }
    return pmNoError;

free_buffers:
    /* buffers are freed below by winmm_out_delete */
close_device:
    midiOutClose(m->handle.out);
free_descriptor:
    midi->descriptor = NULL;
    winmm_out_delete(midi); /* frees buffers and m */
no_memory:
    if (pm_hosterror) {
        int err = midiOutGetErrorText(pm_hosterror, (char *) pm_hosterror_text,
                                      PM_HOST_ERROR_MSG_LEN);
        assert(err == MMSYSERR_NOERROR);
        return pmHostError;
    }
    return pmInsufficientMemory;
}
Пример #15
0
static void
logMidiOutError (MMRESULT error, int errorLevel, const char *action) {
  char text[MAXERRORLENGTH];
  midiOutGetErrorText(error, text, sizeof(text));
  logMessage(errorLevel, "%s error %d: %s", action, error, text);
}
Пример #16
0
void MFMidi_InitModulePlatformSpecific()
{
	UINT numInputDevices = midiInGetNumDevs();
	for (UINT i = 0; i < numInputDevices; ++i)
	{
		MIDIINCAPS caps;
		MMRESULT r = midiInGetDevCaps(i, &caps, sizeof(caps));
		if (r != MMSYSERR_NOERROR)
		{
			wchar_t errorBuffer[256];
			midiOutGetErrorText(r, errorBuffer, sizeof(errorBuffer));
			MFDebug_Warn(1, MFStr("Failed to query midi input device: %s", MFString_WCharAsUTF8(errorBuffer)));
			continue;
		}

		MFDevice *pDevice = MFDevice_AllocDevice(MFDT_MidiInput, &DestroyInputDevice);
		pDevice->pInternal = MFHeap_AllocAndZero(sizeof(MFMidiPC_MidiInputDevice));
		pDevice->state = MFDevState_Available;

		MFMidiPC_MidiOutputDevice *pDev = (MFMidiPC_MidiOutputDevice*)pDevice->pInternal;
		pDev->mid = caps.wMid;
		pDev->pid = caps.wPid;

		MFString_CopyUTF16ToUTF8(pDevice->strings[MFDS_ID], caps.szPname);
		MFString_CopyUTF16ToUTF8(pDevice->strings[MFDS_DeviceName], caps.szPname);
		MFString_CopyUTF16ToUTF8(pDevice->strings[MFDS_Description], caps.szPname);
		MFString_CopyUTF16ToUTF8(pDevice->strings[MFDS_InterfaceName], caps.szPname);
//		MFDS_Manufacturer

		MFDebug_Log(0, MFStr("Found midi input device: %s (%04X:%04X) - state: %d", pDevice->strings[MFDS_ID], caps.wMid, caps.wPid, pDevice->state));
	}

	UINT numOutputDevices = midiOutGetNumDevs();
	for (UINT i = 0; i < numOutputDevices; ++i)
	{
		MIDIOUTCAPS caps;
		MMRESULT r = midiOutGetDevCaps(i, &caps, sizeof(caps));
		if (r != MMSYSERR_NOERROR)
		{
			wchar_t errorBuffer[256];
			midiOutGetErrorText(r, errorBuffer, sizeof(errorBuffer));
			MFDebug_Warn(1, MFStr("Failed to query midi output device: %s", MFString_WCharAsUTF8(errorBuffer)));
			continue;
		}

		MFDevice *pDevice = MFDevice_AllocDevice(MFDT_MidiOutput, &DestroyOutputDevice);
		pDevice->pInternal = MFHeap_AllocAndZero(sizeof(MFMidiPC_MidiOutputDevice));
		pDevice->state = MFDevState_Available;

		MFMidiPC_MidiOutputDevice *pDev = (MFMidiPC_MidiOutputDevice*)pDevice->pInternal;
		pDev->mid = caps.wMid;
		pDev->pid = caps.wPid;

		MFString_CopyUTF16ToUTF8(pDevice->strings[MFDS_ID], caps.szPname);
		MFString_CopyUTF16ToUTF8(pDevice->strings[MFDS_DeviceName], caps.szPname);
		MFString_CopyUTF16ToUTF8(pDevice->strings[MFDS_Description], caps.szPname);
		MFString_CopyUTF16ToUTF8(pDevice->strings[MFDS_InterfaceName], caps.szPname);
//		MFDS_Manufacturer

		MFDebug_Log(0, MFStr("Found midi output device: %s (%04X:%04X) - state: %d", pDevice->strings[MFDS_ID], caps.wMid, caps.wPid, pDevice->state));
	}
}