Esempio n. 1
0
MF_API bool MFMidi_Start(MFDevice *pDevice)
{
	MFMidiPC_MidiInputDevice *pMidi = (MFMidiPC_MidiInputDevice*)pDevice->pInternal;

	if (pDevice->state == MFDevState_Active)
	{
		MFDebug_Warn(1, "Midi input device already started!");
		return false;
	}
	if (pDevice->state != MFDevState_Ready)
	{
		MFDebug_Warn(1, "Midi input device not ready!");
		return false;
	}

	pMidi->numEvents = pMidi->numEventsRead = 0;

	MMRESULT r = midiInStart(pMidi->hMidiIn);
	if (r != MMSYSERR_NOERROR)
	{
		pDevice->state = MFDevState_Unknown;

		wchar_t errorBuffer[256];
		midiInGetErrorText(r, errorBuffer, sizeof(errorBuffer));
		MFDebug_Warn(1, MFStr("Couldn't start MIDI device: %s", MFString_WCharAsUTF8(errorBuffer)));
		return false;
	}

	pDevice->state = MFDevState_Active;
	return true;
}
Esempio n. 2
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;
            }
        }
    }
}
Esempio n. 3
0
		bool _error( MMRESULT res ) 
		{
			if ( ! res )
				return 1;
			midiInGetErrorText( res, _err, 1024 );
			printf( "Midi Error: %s\n", _err );
			return 0; //MessageBox( NULL, _err, "midi in", MB_OK );     
		}
Esempio n. 4
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;
     }
Esempio n. 5
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;
}
Esempio n. 6
0
/*
 * assume midi is non-null (checked by caller)
 */
static PmError winmm_in_close(PmInternal *midi)
{
    midiwinmm_type m = (midiwinmm_type) midi->descriptor;
    if (!m) return pmBadPtr;
    /* device to close */
    if (pm_hosterror = midiInStop(m->handle.in)) {
        midiInReset(m->handle.in); /* try to reset and close port */
        midiInClose(m->handle.in);
    } else if (pm_hosterror = midiInReset(m->handle.in)) {
        midiInClose(m->handle.in); /* best effort to close midi port */
    } else {
        pm_hosterror = midiInClose(m->handle.in);
    }
    midi->descriptor = NULL;
    pm_free(m); /* delete */
    if (pm_hosterror) {
        int err = midiInGetErrorText(pm_hosterror, (char *) pm_hosterror_text, 
                                     PM_HOST_ERROR_MSG_LEN);
        assert(err == MMSYSERR_NOERROR);
        return pmHostError;
    }
    return pmNoError;
}
Esempio n. 7
0
void moMidiDevice::PrintMidiInErrorMsg(unsigned long err)
{
#ifdef WIN32
#define BUFFERSIZE 200
	char	buffer[BUFFERSIZE];

	if (!(err = midiInGetErrorText(err, &buffer[0], BUFFERSIZE)))
	{
		printf("%s\r\n", &buffer[0]);
	}
	else if (err == MMSYSERR_BADERRNUM)
	{
		printf("Strange error number returned!\r\n");
	}
	else if (err == MMSYSERR_INVALPARAM)
	{
		printf("Specified pointer is invalid!\r\n");
	}
	else
	{
		printf("Unable to allocate/lock memory!\r\n");
	}
#endif
}
static void msw_midiinerror(char *s, int err)
{
    char t[256];
    midiInGetErrorText(err, t, 256);
    fprintf(stderr, s, t);
}
Esempio n. 9
0
static PmError winmm_in_open(PmInternal *midi, void *driverInfo)
{
    DWORD dwDevice;
    int i = midi->device_id;
    midiwinmm_type m;
    LPMIDIHDR hdr;
    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.in = NULL;
    m->buffers = NULL;
    m->num_buffers = 0;
    m->next_buffer = 0;
    m->last_time = 0;
    m->first_message = TRUE; /* not used for input */
    m->sysex_mode = FALSE;
    m->sysex_word = 0;
    m->sysex_byte_count = 0;
    m->sync_time = 0;
    m->delta = 0;
    m->error = MMSYSERR_NOERROR;
    m->callback_error = MMSYSERR_NOERROR;

    /* open device */
    pm_hosterror = midiInOpen(&(m->handle.in), /* input device handle */
                      dwDevice, /* device ID */
                      (DWORD) winmm_in_callback, /* callback address */
                      (DWORD) midi, /* callback instance data */
                      CALLBACK_FUNCTION); /* callback is a procedure */
    if (pm_hosterror) goto free_descriptor;

    /* allocate first buffer for sysex data */
    hdr = allocate_buffer(PM_DEFAULT_SYSEX_BUFFER_SIZE);
    if (!hdr) goto close_device;
    pm_hosterror = midiInPrepareHeader(m->handle.in, hdr, sizeof(MIDIHDR));
    if (pm_hosterror) {
        pm_free(hdr);
        goto close_device;
    }
    pm_hosterror = midiInAddBuffer(m->handle.in, hdr, sizeof(MIDIHDR));
    if (pm_hosterror) goto close_device;

    /* allocate second buffer */
    hdr = allocate_buffer(PM_DEFAULT_SYSEX_BUFFER_SIZE);
    if (!hdr) goto close_device;
    pm_hosterror = midiInPrepareHeader(m->handle.in, hdr, sizeof(MIDIHDR));
    if (pm_hosterror) {
        pm_free(hdr);
        goto reset_device; /* because first buffer was added */
    }
    pm_hosterror = midiInAddBuffer(m->handle.in, hdr, sizeof(MIDIHDR));
    if (pm_hosterror) goto reset_device;

    /* start device */
    pm_hosterror = midiInStart(m->handle.in);
    if (pm_hosterror) goto reset_device;
    return pmNoError;

    /* undo steps leading up to the detected error */
reset_device:
    /* ignore return code (we already have an error to report) */
    midiInReset(m->handle.in); 
close_device:
    midiInClose(m->handle.in); /* ignore return code */
free_descriptor:
    midi->descriptor = NULL;
    pm_free(m);
no_memory:
    if (pm_hosterror) {
        int err = midiInGetErrorText(pm_hosterror, (char *) pm_hosterror_text, 
                                     PM_HOST_ERROR_MSG_LEN);
        assert(err == MMSYSERR_NOERROR);
        return pmHostError;
    }
    /* if !pm_hosterror, then the error must be pmInsufficientMemory */
    return pmInsufficientMemory;
    /* note: if we return an error code, the device will be
       closed and memory will be freed. It's up to the caller
       to free the parameter midi */
}
Esempio n. 10
0
static PmError winmm_in_open(PmInternal *midi, void *driverInfo)
{
    DWORD dwDevice;
    int i = midi->device_id;
    int max_sysex_len = midi->buffer_len * 4;
    int num_input_buffers = max_sysex_len / INPUT_SYSEX_LEN;
    midiwinmm_type m;

    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.in = NULL;
    m->buffers = NULL; /* not used for input */
    m->num_buffers = 0; /* not used for input */
    m->max_buffers = FALSE; /* not used for input */
    m->buffers_expanded = 0; /* not used for input */
    m->next_buffer = 0; /* not used for input */
    m->buffer_signal = 0; /* not used for input */
    m->last_time = 0;
    m->first_message = TRUE; /* not used for input */
    m->sysex_mode = FALSE;
    m->sysex_word = 0;
    m->sysex_byte_count = 0;
    m->hdr = NULL; /* not used for input */
    m->sync_time = 0;
    m->delta = 0;
    m->error = MMSYSERR_NOERROR;
    /* 4000 is based on Windows documentation -- that's the value used in the
       memory manager. It's small enough that it should not hurt performance even
       if it's not optimal.
     */
    InitializeCriticalSectionAndSpinCount(&m->lock, 4000);
    /* open device */
    pm_hosterror = midiInOpen(
	    &(m->handle.in),  /* input device handle */
	    dwDevice,  /* device ID */
	    (DWORD_PTR) winmm_in_callback,  /* callback address */
	    (DWORD_PTR) midi,  /* callback instance data */
	    CALLBACK_FUNCTION); /* callback is a procedure */
    if (pm_hosterror) goto free_descriptor;

    if (num_input_buffers < MIN_INPUT_BUFFERS)
        num_input_buffers = MIN_INPUT_BUFFERS;
    for (i = 0; i < num_input_buffers; i++) {
        if (allocate_input_buffer(m->handle.in, INPUT_SYSEX_LEN)) {
            /* either pm_hosterror was set, or the proper return code
               is pmInsufficientMemory */
            goto close_device;
        }
    }
    /* start device */
    pm_hosterror = midiInStart(m->handle.in);
    if (pm_hosterror) goto reset_device;
    return pmNoError;

    /* undo steps leading up to the detected error */
reset_device:
    /* ignore return code (we already have an error to report) */
    midiInReset(m->handle.in);
close_device:
    midiInClose(m->handle.in); /* ignore return code */
free_descriptor:
    midi->descriptor = NULL;
    pm_free(m);
no_memory:
    if (pm_hosterror) {
        int err = midiInGetErrorText(pm_hosterror, (char *) pm_hosterror_text,
                                     PM_HOST_ERROR_MSG_LEN);
        assert(err == MMSYSERR_NOERROR);
        return pmHostError;
    }
    /* if !pm_hosterror, then the error must be pmInsufficientMemory */
    return pmInsufficientMemory;
    /* note: if we return an error code, the device will be
       closed and memory will be freed. It's up to the caller
       to free the parameter midi */
}
char* MIDI_IN_GetErrorStr(INT32 err) {
    winMidiInErrMsg[0] = 0;
    midiInGetErrorText((MMRESULT) err, winMidiInErrMsg, WIN_MAX_ERROR_LEN);
    return winMidiInErrMsg;
}
Esempio n. 12
0
static char*
fluid_winmidi_input_error(int no)
{
  midiInGetErrorText(no, fluid_winmidi_error_buffer, 256);
  return fluid_winmidi_error_buffer;
}
Esempio n. 13
0
static void CALLBACK MidiInProc(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
	MFDevice *pDevice = (MFDevice*)dwInstance;
	MFMidiPC_MidiInputDevice *pMidi = (MFMidiPC_MidiInputDevice*)pDevice->pInternal;

	switch(wMsg)
	{
		case MIM_OPEN:
			MFDebug_Log(0, MFStr("Opened MIDI input device: %s", pDevice->strings[MFDS_ID]));
			break;
		case MIM_CLOSE:
			MFDebug_Log(0, MFStr("Closed MIDI input device: %s", pDevice->strings[MFDS_ID]));
			break;
		case MIM_MOREDATA:
			MFDebug_Log(0, "MIDI message: MIM_MOREDATA");
			break;
		case MIM_DATA:
		{
			MFMidiEvent ev;
			MFMidi_DecodeShortMessage((uint32)dwParam1, &ev, (uint32)dwParam2);

			switch(ev.ev)
			{
				case MFMET_NoteOff:
					pMidi->channels[ev.channel].notes[ev.noteOff.note] = 0;
					break;
				case MFMET_NoteOn:
				case MFMET_NoteAftertouch:
					pMidi->channels[ev.channel].notes[ev.noteOn.note] = ev.noteOn.velocity;
					break;
				case MFMET_ControlChange:
					pMidi->channels[ev.channel].control[ev.controlChange.control] = ev.controlChange.value;
					break;
				case MFMET_ProgramChange:
					pMidi->channels[ev.channel].program = ev.programChange.program;
					break;
				case MFMET_ChannelAftertouch:
					// TODO: ... what is this?
					break;
				case MFMET_PitchBend:
					pMidi->channels[ev.channel].pitch = ev.pitchBend.value;
					break;
				default:
					MFDebug_Assert(false, "Why are we getting sys events?");
					break;
			}

			if (pMidi->bBuffered || pMidi->pEventCallback)
			{
				if (pMidi->bBuffered)
				{
					if (pMidi->numEvents >= pMidi->numAllocated)
					{
						pMidi->numAllocated *= 2;
						pMidi->pEvents = (MFMidiEvent*)MFHeap_Realloc(pMidi->pEvents, sizeof(MFMidiEvent)*pMidi->numAllocated);
					}

					pMidi->pEvents[pMidi->numEvents++] = ev;
				}
				if (pMidi->pEventCallback)
				{
					pMidi->pEventCallback(pDevice, &ev);
				}
			}
			break;
		}
		case MIM_LONGDATA:
		{
			MIDIHDR *pHdr = (MIDIHDR*)dwParam1;

			MFMidiEvent ev;
			MFMidi_DecodePacket((const uint8*)pHdr->lpData, pHdr->dwBytesRecorded, &ev, (uint32)dwParam2);

			if (pMidi->bBuffered || pMidi->pEventCallback)
			{
				if (pMidi->bBuffered)
				{
					if (pMidi->numEvents >= pMidi->numAllocated)
					{
						pMidi->numAllocated *= 2;
						pMidi->pEvents = (MFMidiEvent*)MFHeap_Realloc(pMidi->pEvents, sizeof(MFMidiEvent)*pMidi->numAllocated);
					}

					pMidi->pEvents[pMidi->numEvents++] = ev;
				}
				if (pMidi->pEventCallback)
				{
					pMidi->pEventCallback(pDevice, &ev);
				}
			}

			MMRESULT r = midiInAddBuffer(pMidi->hMidiIn, pHdr, sizeof(*pHdr));
			if (r != MMSYSERR_NOERROR)
			{
				wchar_t errorBuffer[256];
				midiInGetErrorText(r, errorBuffer, sizeof(errorBuffer));
				MFDebug_Warn(1, MFStr("Failed to open MIDI input device: %s", MFString_WCharAsUTF8(errorBuffer)));
			}
			break;
		}
		case MIM_ERROR:
		case MIM_LONGERROR:
		{
			MFDebug_Log(0, MFStr("MIDI input error: %d, 0x%08X : 0x%08X", wMsg, dwParam1, dwParam2));
			break;
		}
	}
}
Esempio n. 14
0
MF_API bool MFMidi_OpenInput(MFDevice *pDevice, bool bBuffered, MFMidiEventCallback *pEventCallback)
{
	MFDebug_Assert(pDevice->type == MFDT_MidiInput, "Not a MIDI device!");

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

	MFMidiPC_MidiInputDevice *pMidi = (MFMidiPC_MidiInputDevice*)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 numInputDevices = midiInGetNumDevs();
	UINT i = 0;
	for (; i < numInputDevices; ++i)
	{
		MIDIINCAPS caps;
		MMRESULT r = midiInGetDevCaps(i, &caps, sizeof(caps));
		if (r != MMSYSERR_NOERROR)
			continue;

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

	MMRESULT r = midiInOpen(&pMidi->hMidiIn, i, (DWORD_PTR)MidiInProc, (DWORD_PTR)pDevice, CALLBACK_FUNCTION | MIDI_IO_STATUS);
	if (r != MMSYSERR_NOERROR)
	{
		pMidi->hMidiIn = NULL;
		pDevice->state = MFDevState_Unknown;

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

		return false;
	}

	MFZeroMemory(&pMidi->sysexRecv, sizeof(pMidi->sysexRecv));
	pMidi->sysexRecv.lpData = (LPSTR)pMidi->sysexRecvBuffer;
	pMidi->sysexRecv.dwBufferLength = sizeof(pMidi->sysexRecvBuffer);
	r = midiInPrepareHeader(pMidi->hMidiIn, &pMidi->sysexRecv, sizeof(pMidi->sysexRecv));
	if (r != MMSYSERR_NOERROR)
	{
		wchar_t errorBuffer[256];
		midiInGetErrorText(r, errorBuffer, sizeof(errorBuffer));
		MFDebug_Warn(1, MFStr("Failed to open MIDI input device: %s", MFString_WCharAsUTF8(errorBuffer)));
	}
	r = midiInAddBuffer(pMidi->hMidiIn, &pMidi->sysexRecv, sizeof(pMidi->sysexRecv));
	if (r != MMSYSERR_NOERROR)
	{
		wchar_t errorBuffer[256];
		midiInGetErrorText(r, errorBuffer, sizeof(errorBuffer));
		MFDebug_Warn(1, MFStr("Failed to open MIDI input device: %s", MFString_WCharAsUTF8(errorBuffer)));
	}

	pMidi->bBuffered = bBuffered;
	pMidi->pEventCallback = pEventCallback;

	pMidi->numAllocated = 256;
	pMidi->pEvents = (MFMidiEvent*)MFHeap_Alloc(sizeof(MFMidiEvent) * pMidi->numAllocated);

	pDevice->state = MFDevState_Ready;

	if (!bBuffered && !pEventCallback)
		MFMidi_Start(pDevice);

	return true;
}