static PmError winmm_write_short(PmInternal *midi, PmEvent *event) { midiwinmm_type m = (midiwinmm_type) midi->descriptor; PmError rslt = pmNoError; assert(m); if (midi->latency == 0) { /* use midiOut interface, ignore timestamps */ m->error = midiOutShortMsg(m->handle.out, event->message); if (m->error) rslt = pmHostError; } else { /* use midiStream interface -- pass data through buffers */ unsigned long when = event->timestamp; unsigned long delta; int full; if (when == 0) when = midi->now; /* when is in real_time; translate to intended stream time */ when = when + m->delta + midi->latency; /* make sure we don't go backward in time */ if (when < m->last_time) when = m->last_time; delta = when - m->last_time; m->last_time = when; /* before we insert any data, we must have a buffer */ if (m->hdr == NULL) { /* stream interface: buffers allocated when stream is opened */ m->hdr = get_free_output_buffer(midi); } full = add_to_buffer(m, m->hdr, delta, event->message); if (full) rslt = winmm_write_flush(midi, when); } return rslt; }
static PmError winmm_write_byte(PmInternal *midi, unsigned char byte, PmTimestamp timestamp) { /* write a sysex byte */ PmError rslt = pmNoError; midiwinmm_type m = (midiwinmm_type) midi->descriptor; LPMIDIHDR hdr = m->hdr; unsigned char *msg_buffer; assert(m); if (!hdr) { m->hdr = hdr = get_free_output_buffer(midi); assert(hdr); midi->fill_base = (unsigned char *)(FPTR) m->hdr->lpData; midi->fill_offset_ptr = (uint32_t *)&(hdr->dwBytesRecorded); /* when buffer fills, Pm_WriteSysEx will revert to calling * pmwin_write_byte, which expect to have space, so leave * one byte free for pmwin_write_byte. Leave another byte * of space for zero after message to make early version of * MIDI YOKE driver happy -- therefore dwBufferLength - 2 */ midi->fill_length = hdr->dwBufferLength - 2; if (midi->latency != 0) { unsigned long when = (unsigned long) timestamp; unsigned long delta; unsigned long *ptr; if (when == 0) when = midi->now; /* when is in real_time; translate to intended stream time */ when = when + m->delta + midi->latency; /* make sure we don't go backward in time */ if (when < m->last_time) when = m->last_time; delta = when - m->last_time; m->last_time = when; ptr = (unsigned long *) hdr->lpData; *ptr++ = delta; *ptr++ = 0; *ptr = MEVT_F_LONG; hdr->dwBytesRecorded = 3 * sizeof(long); /* data will be added at an offset of dwBytesRecorded ... */ } } /* add the data byte */ msg_buffer = (unsigned char *) (hdr->lpData); msg_buffer[hdr->dwBytesRecorded++] = byte; /* see if buffer is full, leave one byte extra for pad */ if (hdr->dwBytesRecorded >= hdr->dwBufferLength - 1) { /* write what we've got and continue */ rslt = winmm_end_sysex(midi, timestamp); } return rslt; }
static PmError winmm_write_sysex_byte(PmInternal *midi, unsigned char byte) { midiwinmm_type m = (midiwinmm_type) midi->descriptor; unsigned char *msg_buffer; /* at the beginning of sysex, m->hdr is NULL */ if (!m->hdr) { /* allocate a buffer if none allocated yet */ m->hdr = get_free_output_buffer(midi); if (!m->hdr) return pmInsufficientMemory; m->sysex_byte_count = 0; } /* figure out where to write byte */ msg_buffer = (unsigned char *) (m->hdr->lpData); assert(m->hdr->lpData == (char *) (m->hdr + 1)); /* check for overflow */ if (m->sysex_byte_count >= m->hdr->dwBufferLength) { /* allocate a bigger message -- double it every time */ LPMIDIHDR big = allocate_buffer(m->sysex_byte_count * 2); /* printf("expand to %d bytes\n", m->sysex_byte_count * 2); */ if (!big) return pmInsufficientMemory; m->error = midiOutPrepareHeader(m->handle.out, big, sizeof(MIDIHDR)); if (m->error) { m->hdr = NULL; return pmHostError; } memcpy(big->lpData, msg_buffer, m->sysex_byte_count); msg_buffer = (unsigned char *) (big->lpData); if (m->buffers[0] == m->hdr) { m->buffers[0] = big; pm_free(m->hdr); /* printf("freed m->hdr\n"); */ } else if (m->buffers[1] == m->hdr) { m->buffers[1] = big; pm_free(m->hdr); /* printf("freed m->hdr\n"); */ } m->hdr = big; } /* append byte to message */ msg_buffer[m->sysex_byte_count++] = byte; /* see if we have a complete message */ if (byte == MIDI_EOX) { m->hdr->dwBytesRecorded = m->sysex_byte_count; /* { int i; int len = m->hdr->dwBytesRecorded; printf("OutLongMsg %d ", len); for (i = 0; i < len; i++) { printf("%2x ", msg_buffer[i]); } } */ m->error = midiOutLongMsg(m->handle.out, m->hdr, sizeof(MIDIHDR)); m->hdr = NULL; /* stop using this message buffer */ if (m->error) return pmHostError; } return pmNoError; }