Ejemplo n.º 1
0
void main_test_both()
{
    int i = 0;
    int in, out;
    PmStream * midi, * midiOut;
    PmEvent buffer[1];
    PmError status, length;
    int num = 10;
    
    in = get_number("Type input number: ");
    out = get_number("Type output number: ");

    /* In is recommended to start timer before PortMidi */
    TIME_START;

    Pm_OpenOutput(&midiOut, 
                  out, 
                  DRIVER_INFO,
                  OUTPUT_BUFFER_SIZE, 
                  TIME_PROC,
                  TIME_INFO, 
                  latency);
    printf("Midi Output opened with %ld ms latency.\n", (long) latency);
    /* open input device */
    Pm_OpenInput(&midi, 
                 in,
                 DRIVER_INFO, 
                 INPUT_BUFFER_SIZE, 
                 TIME_PROC, 
                 TIME_INFO);
    printf("Midi Input opened. Reading %d Midi messages...\n",num);
    Pm_SetFilter(midi, PM_FILT_ACTIVE | PM_FILT_CLOCK);
    /* empty the buffer after setting filter, just in case anything
       got through */
    while (Pm_Poll(midi)) {
        Pm_Read(midi, buffer, 1);
    }
    i = 0;
    while (i < num) {
        status = Pm_Poll(midi);
        if (status == TRUE) {
            length = Pm_Read(midi,buffer,1);
            if (length > 0) {
                Pm_Write(midiOut, buffer, 1);
                printf("Got message %d: time %ld, %2lx %2lx %2lx\n",
                       i,
                       (long) buffer[0].timestamp,
                       (long) Pm_MessageStatus(buffer[0].message),
                       (long) Pm_MessageData1(buffer[0].message),
                       (long) Pm_MessageData2(buffer[0].message));
                i++;
            } else {
                assert(0);
            }
        }
    }

    /* close midi devices */
    Pm_Close(midi);
    Pm_Close(midiOut);
    Pm_Terminate(); 
}
Ejemplo n.º 2
0
int osd_midi_device_pm::read(UINT8 *pOut)
{
	int msgsRead = Pm_Read(pmStream, rx_evBuf, RX_EVENT_BUF_SIZE);
	int bytesOut = 0;

	if (msgsRead <= 0)
	{
		return 0;
	}

	for (int msg = 0; msg < msgsRead; msg++)
	{
		UINT8 status = Pm_MessageStatus(rx_evBuf[msg].message);

		if (rx_sysex)
		{
			if (status & 0x80)  // sys real-time imposing on us?
			{
				if ((status == 0xf2) || (status == 0xf3))
				{
					*pOut++ = status;
					*pOut++ = Pm_MessageData1(rx_evBuf[msg].message);
					*pOut++ = Pm_MessageData2(rx_evBuf[msg].message);
					bytesOut += 3;
				}
				else
				{
					*pOut++ = status;
					bytesOut++;
					if (status == MIDI_EOX)
					{
						rx_sysex = false;
					}
				}
			}
			else    // shift out the sysex bytes
			{
				for (int i = 0; i < 4; i++)
				{
					UINT8 byte = rx_evBuf[msg].message & 0xff;
					*pOut++ = byte;
					bytesOut++;
					if (byte == MIDI_EOX)
					{
						rx_sysex = false;
						break;
					}
					rx_evBuf[msg].message >>= 8;
				}
			}
		}
		else
		{
			switch ((status>>4) & 0xf)
			{
				case 0xc:   // 2-byte messages
				case 0xd:
					*pOut++ = status;
					*pOut++ = Pm_MessageData1(rx_evBuf[msg].message);
					bytesOut += 2;
					break;

				case 0xf:   // system common
					switch (status & 0xf)
					{
						case 0: // System Exclusive
						{
							*pOut++ = status;   // this should be OK: the shortest legal sysex is F0 tt dd F7, I believe
							*pOut++ = (rx_evBuf[msg].message>>8) & 0xff;
							*pOut++ = (rx_evBuf[msg].message>>16) & 0xff;
							UINT8 last = *pOut++ = (rx_evBuf[msg].message>>24) & 0xff;
							bytesOut += 4;
							rx_sysex = (last != MIDI_EOX);
							break;
						}

						case 7: // End of System Exclusive
							*pOut++ = status;
							bytesOut += 1;
							rx_sysex = false;
							break;

						case 2: // song pos
						case 3: // song select
							*pOut++ = status;
							*pOut++ = Pm_MessageData1(rx_evBuf[msg].message);
							*pOut++ = Pm_MessageData2(rx_evBuf[msg].message);
							bytesOut += 3;
							break;

						default:    // all other defined Fx messages are 1 byte
							break;
					}
					break;

				default:
					*pOut++ = status;
					*pOut++ = Pm_MessageData1(rx_evBuf[msg].message);
					*pOut++ = Pm_MessageData2(rx_evBuf[msg].message);
					bytesOut += 3;
					break;
			}
		}
	}
Ejemplo n.º 3
0
int main(int argc, const char * argv[])
{
    int i, numDevices, selectedDeviceIndex = 3;
    long channel;
    const PmDeviceInfo *info;
    PortMidiStream *stream;
    PmEvent event;

    Pm_Initialize();

    numDevices = Pm_CountDevices();
    if (numDevices == 0) {
        return 0;
    }
    for (i = 0; i < numDevices; i++) {
        info = Pm_GetDeviceInfo(i);
        if (info->input) {
        }
    }

    info = Pm_GetDeviceInfo(selectedDeviceIndex);

    channel = 1;
    channel--;

    Pm_OpenInput(&stream,
                 selectedDeviceIndex,
                 NULL,
                 8192,
                 NULL,
                 NULL);

    printf("Setup complete! Waiting for MIDI data...\n");
    system("setterm -blank force");//kills all display.  to bring back call: setterm -blank poke
    while (1) {

        long status, data1, data2;
        int length, person, audioFile;

        length = Pm_Read(stream, &event, sizeof(long));
        if (length > 0) {

            status = Pm_MessageStatus(event.message);
            data1 = Pm_MessageData1(event.message);
            data2 = Pm_MessageData2(event.message);

            if (status == (0x80 + channel)) {
                printf("Note off: %ld, %ld\n", data1, data2);
            } else if (status == (0x90 + channel)) {
                printf("Note on: %ld, %ld\n", data1, data2);
            } else if (status == (0xB0 + channel)) {
                printf("CC: %ld, %ld\n", data1, data2);


            }

        }



        if (data1 == 25) {
            if (data2 == 127) {
                system("clear");
                system("playMovie");
            }
        }
        if(data1 == 26) {
            if(data2 == 127) {
                system("setterm -blank force");
            }
            if(data2 == 0) {
                system("setterm -blank poke");
            }
        }
    }
    Pm_Close(stream);

    Pm_Terminate();

    return 0;
}
Ejemplo n.º 4
0
static int ReadMidiData_(CSOUND *csound, void *userData,
                         unsigned char *mbuf, int nbytes)
{
    int             n, retval, st, d1, d2;
    PmEvent         mev;
    pmall_data *data;
    /*
     * Reads from MIDI input device linked list.
     */
    n = 0;
    data = (pmall_data *)userData;
    while (data) {
      retval = Pm_Poll(data->midistream);
      if (retval != FALSE) {
        if (UNLIKELY(retval < 0))
          return portMidiErrMsg(csound, Str("error polling input device"));
        while ((retval = Pm_Read(data->midistream, &mev, 1L)) > 0) {
          st = (int)Pm_MessageStatus(mev.message);
          d1 = (int)Pm_MessageData1(mev.message);
          d2 = (int)Pm_MessageData2(mev.message);
          /* unknown message or sysex data: ignore */
          if (UNLIKELY(st < 0x80))
            continue;
          /* ignore most system messages */
          if (UNLIKELY(st >= 0xF0 &&
                       !(st == 0xF8 || st == 0xFA || st == 0xFB ||
                         st == 0xFC || st == 0xFF)))
            continue;
          nbytes -= (datbyts[(st - 0x80) >> 4] + 1);
          if (UNLIKELY(nbytes < 0)) {
            portMidiErrMsg(csound, Str("buffer overflow in MIDI input"));
            break;
          }
          /* channel messages */
          n += (datbyts[(st - 0x80) >> 4] + 1);
          switch (datbyts[(st - 0x80) >> 4]) {
            case 0:
              *mbuf++ = (unsigned char) st;
              break;
            case 1:
              *mbuf++ = (unsigned char) st;
              *mbuf++ = (unsigned char) d1;
              break;
            case 2:
              *mbuf++ = (unsigned char) st;
              *mbuf++ = (unsigned char) d1;
              *mbuf++ = (unsigned char) d2;
              break;
          }
        }
        if (UNLIKELY(retval < 0)) {
          portMidiErrMsg(csound, Str("read error %d"), retval);
          if (n < 1)
            n = -1;
        }
      }
      data = data->next;
    }
    /* return the number of bytes read */
    return n;
}
Ejemplo n.º 5
0
PmError Pm_Write( PortMidiStream *stream, PmEvent *buffer, long length)
{
    PmInternal *midi = (PmInternal *) stream;
    PmError err;
    int i;
    int bits;
    
    /* arg checking */
    if(midi == NULL)
        err = pmBadPtr;
    else if(Pm_HasHostError(midi))
        err = pmHostError;
    else if(!descriptors[midi->device_id].pub.opened)
        err = pmBadPtr;
    else if(!descriptors[midi->device_id].pub.output)
        err = pmBadPtr;
    else
        err = pmNoError;
    
    if (err != pmNoError) goto pm_write_error;
    
    if (midi->latency == 0) {
        midi->now = 0;
    } else {
        midi->now = (*(midi->time_proc))(midi->time_info);
        if (midi->first_message || midi->sync_time + 100 /*ms*/ < midi->now) {
            /* time to resync */
            midi->now = (*midi->dictionary->synchronize)(midi);
            midi->first_message = FALSE;
        }
    }

    for (i = 0; i < length; i++) {
        unsigned long msg = buffer[i].message;
        bits = 0;
        /* is this a sysex message? */
        if (Pm_MessageStatus(msg) == MIDI_SYSEX) {
            if (midi->sysex_in_progress) {
                /* error: previous sysex was not terminated by EOX */
                midi->sysex_in_progress = FALSE;
                err = pmBadData;
                goto pm_write_error;
            }
            midi->sysex_in_progress = TRUE;
            if ((err = (*midi->dictionary->begin_sysex)(midi, 
                               buffer[i].timestamp)) != pmNoError)
                goto pm_write_error;
            if ((err = (*midi->dictionary->write_byte)(midi, MIDI_SYSEX,
                               buffer[i].timestamp)) != pmNoError) 
                goto pm_write_error;
            bits = 8;
            /* fall through to continue sysex processing */
        } else if ((msg & MIDI_STATUS_MASK) && 
                   (Pm_MessageStatus(msg) != MIDI_EOX)) {
            /* a non-sysex message */
            if (midi->sysex_in_progress) {
                /* this should be a non-realtime message */
                if (is_real_time(msg)) {
                    if ((err = (*midi->dictionary->write_realtime)(midi, 
                                       &(buffer[i]))) != pmNoError)
                        goto pm_write_error;
                } else {
                    midi->sysex_in_progress = FALSE;
                    err = pmBadData;
                    /* ignore any error from this, because we already have one */
                    /* pass 0 as timestamp -- it's ignored */
                    (*midi->dictionary->end_sysex)(midi, 0);
                    goto pm_write_error;
                }
            } else { /* regular short midi message */
                if ((err = (*midi->dictionary->write_short)(midi, 
                                   &(buffer[i]))) != pmNoError)
                    goto pm_write_error;
                continue;
            }
        }
        if (midi->sysex_in_progress) { /* send sysex bytes until EOX */
            while (bits < 32) {
                unsigned char midi_byte = (unsigned char) (msg >> bits);
                if ((err = (*midi->dictionary->write_byte)(midi, midi_byte, 
                                   buffer[i].timestamp)) != pmNoError)
                    goto pm_write_error;
                if (midi_byte == MIDI_EOX) {
                    midi->sysex_in_progress = FALSE;
                    if ((err = (*midi->dictionary->end_sysex)(midi, 
                                       buffer[i].timestamp)) != pmNoError)
                        goto pm_write_error;
                    break; /* from while loop */
                }
                bits += 8;
            }
        } else {
            /* not in sysex mode, but message did not start with status */
            err = pmBadData;
            goto pm_write_error;
        }
    }
Ejemplo n.º 6
0
PMEXPORT PmError Pm_Write( PortMidiStream *stream, PmEvent *buffer, int32_t length)
{
    PmInternal *midi = (PmInternal *) stream;
    PmError err = pmNoError;
    int i;
    int bits;

    pm_hosterror = FALSE;
    /* arg checking */
    if(midi == NULL)
        err = pmBadPtr;
    else if(!descriptors[midi->device_id].pub.opened)
        err = pmBadPtr;
    else if(!descriptors[midi->device_id].pub.output)
        err = pmBadPtr;
    else
        err = pmNoError;

    if (err != pmNoError) goto pm_write_error;

    if (midi->latency == 0) {
        midi->now = 0;
    } else {
        midi->now = (*(midi->time_proc))(midi->time_info);
        if (midi->first_message || midi->sync_time + 100 /*ms*/ < midi->now) {
            /* time to resync */
            midi->now = (*midi->dictionary->synchronize)(midi);
            midi->first_message = FALSE;
        }
    }
    /* error recovery: when a sysex is detected, we call
     *   dictionary->begin_sysex() followed by calls to
     *   dictionary->write_byte() and dictionary->write_realtime()
     *   until an end-of-sysex is detected, when we call
     *   dictionary->end_sysex(). After an error occurs,
     *   Pm_Write() continues to call functions. For example,
     *   it will continue to call write_byte() even after
     *   an error sending a sysex message, and end_sysex() will be
     *   called when an EOX or non-real-time status is found.
     * When errors are detected, Pm_Write() returns immediately,
     *   so it is possible that this will drop data and leave
     *   sysex messages in a partially transmitted state.
     */
    for (i = 0; i < length; i++) {
        uint32_t msg = buffer[i].message;
        bits = 0;
        /* is this a sysex message? */
        if (Pm_MessageStatus(msg) == MIDI_SYSEX) {
            if (midi->sysex_in_progress) {
                /* error: previous sysex was not terminated by EOX */
                midi->sysex_in_progress = FALSE;
                err = pmBadData;
                goto pm_write_error;
            }
            midi->sysex_in_progress = TRUE;
            if ((err = (*midi->dictionary->begin_sysex)(midi,
                               buffer[i].timestamp)) != pmNoError)
                goto pm_write_error;
            if ((err = (*midi->dictionary->write_byte)(midi, MIDI_SYSEX,
                               buffer[i].timestamp)) != pmNoError)
                goto pm_write_error;
            bits = 8;
            /* fall through to continue sysex processing */
        } else if ((msg & MIDI_STATUS_MASK) &&
                   (Pm_MessageStatus(msg) != MIDI_EOX)) {
            /* a non-sysex message */
            if (midi->sysex_in_progress) {
                /* this should be a realtime message */
                if (is_real_time(msg)) {
                    if ((err = (*midi->dictionary->write_realtime)(midi,
                                       &(buffer[i]))) != pmNoError)
                        goto pm_write_error;
                } else {
                    midi->sysex_in_progress = FALSE;
                    err = pmBadData;
                    /* ignore any error from this, because we already have one */
                    /* pass 0 as timestamp -- it's ignored */
                    (*midi->dictionary->end_sysex)(midi, 0);
                    goto pm_write_error;
                }
            } else { /* regular short midi message */
                if ((err = (*midi->dictionary->write_short)(midi,
                                   &(buffer[i]))) != pmNoError)
                    goto pm_write_error;
                continue;
            }
        }
        if (midi->sysex_in_progress) { /* send sysex bytes until EOX */
            /* see if we can accelerate data transfer */
            if (bits == 0 && midi->fill_base && /* 4 bytes to copy */
                (*midi->fill_offset_ptr) + 4 <= midi->fill_length &&
                (msg & 0x80808080) == 0) { /* all data */
                    /* copy 4 bytes from msg to fill_base + fill_offset */
                    unsigned char *ptr = midi->fill_base +
                                         *(midi->fill_offset_ptr);
                    ptr[0] = msg; ptr[1] = msg >> 8;
                    ptr[2] = msg >> 16; ptr[3] = msg >> 24;
                    (*midi->fill_offset_ptr) += 4;
                     continue;
            }
            /* no acceleration, so do byte-by-byte copying */
            while (bits < 32) {
                unsigned char midi_byte = (unsigned char) (msg >> bits);
                if ((err = (*midi->dictionary->write_byte)(midi, midi_byte,
                                   buffer[i].timestamp)) != pmNoError)
                    goto pm_write_error;
                if (midi_byte == MIDI_EOX) {
                    err = pm_end_sysex(midi);
                    if (err != pmNoError) goto error_exit;
                    break; /* from while loop */
                }
                bits += 8;
            }
        } else {
Ejemplo n.º 7
0
/* timer interrupt for processing midi data */
void process_midi(PtTimestamp timestamp, void *userData)
{
    PmError result;
    PmEvent buffer; /* just one message at a time */
    long msg;

    /* do nothing until initialization completes */
    if (!active) 
        return;

    /* check for messages */
    do { 
        result = Pm_Dequeue(main_to_midi, &msg); 
        if (result) {
            if (msg >= -127 && msg <= 127) 
                transpose = msg;
            else if (msg == QUIT_MSG) {
                /* acknowledge receipt of quit message */
                Pm_Enqueue(midi_to_main, &msg);
                active = FALSE;
                return;
            } else if (msg == MONITOR_MSG) {
                /* main has requested a pitch. monitor is a flag that
                 * records the request:
                 */
                monitor = TRUE;
            } else if (msg == THRU_MSG) {
                /* toggle Thru on or off */
                midi_thru = !midi_thru;
            }
        }
    } while (result);         
    
    /* see if there is any midi input to process */
    do {
		result = Pm_Poll(midi_in);
        if (result) {
            long status, data1, data2;
            if (Pm_Read(midi_in, &buffer, 1) == pmBufferOverflow) 
                continue;
            if (midi_thru) 
                Pm_Write(midi_out, &buffer, 1);
            /* unless there was overflow, we should have a message now */
            status = Pm_MessageStatus(buffer.message);
            data1 = Pm_MessageData1(buffer.message);
            data2 = Pm_MessageData2(buffer.message);
            if ((status & 0xF0) == 0x90 ||
                (status & 0xF0) == 0x80) {
                
                /* this is a note-on or note-off, so transpose and send */
                data1 += transpose;
                
                /* keep within midi pitch range, keep proper pitch class */
                while (data1 > 127) 
                    data1 -= 12;
                while (data1 < 0) 
                    data1 += 12;
                
                /* send the message */
                buffer.message = Pm_Message(status, data1, data2);
                Pm_Write(midi_out, &buffer, 1);
                
                /* if monitor is set, send the pitch to the main thread */
                if (monitor) {
                    Pm_Enqueue(midi_to_main, &data1);
                    monitor = FALSE; /* only send one pitch per request */
                }
            }
        }
    } while (result);
}