void MidiSession::openOutputDevice(std::string device)
{
    auto numMidiInputs = Pm_CountDevices();
    auto devices = getDevices();
    
    for(auto i = 0; i < numMidiInputs; i++)
    {
        if(devices[i] == device)
        {
            if(!Pm_GetDeviceInfo(i)->opened)
                error = Pm_OpenOutput(&midiStream, i, nullptr, 3, nullptr, nullptr, 0);
            else
                std::cout<<"Device is already opened"<<std::endl;
            
            if(error != pmNoError)
            {
                std::cout<<"Trying to open device: "<<devices[i]<<std::endl;
                std::cout<<Pm_GetErrorText(error)<<std::endl;
                return;
            }
            
            midiThread = std::thread(&MidiSession::read, this);
            midiThread.detach();
            
            return;
        }
    }
}
Exemplo n.º 2
0
int keyboard_init(MidiObj* m,char* name) {
		
	m->midi_stream_out = NULL;
	m->midi_stream = NULL;
	
	// open midi device
	if(! initialized)
	{
		Pm_Initialize();
		initialized=1;
	}

	int devid= find_device_id_in(name);
	int devid_out= find_device_id_out(name);
	const PmDeviceInfo* dev_info = Pm_GetDeviceInfo(devid);
	const PmDeviceInfo* dev_info_out = Pm_GetDeviceInfo(devid_out);

	if(dev_info_out) {
		Pm_OpenOutput(&(m->midi_stream_out), devid_out, NULL, KEYBOARD_MAX_EVENTS, NULL, NULL,0);
	}
	if(dev_info) {
		Pm_OpenInput(&(m->midi_stream), devid, NULL, KEYBOARD_MAX_EVENTS, NULL, NULL);
		return 1;
	}
	return 0;
}
Exemplo n.º 3
0
bool PortMidiDriver::init()
      {
      inputId = getDeviceIn(preferences.getString(PREF_IO_PORTMIDI_INPUTDEVICE));
      if (inputId == -1)
            inputId  = Pm_GetDefaultInputDeviceID();

      if (inputId == pmNoDevice)
            return false;

      outputId = getDeviceOut(preferences.getString(PREF_IO_PORTMIDI_OUTPUTDEVICE)); // Note: allow init even if outputId == pmNoDevice, since input is more important than output.

      static const int DRIVER_INFO = 0;
      static const int TIME_INFO = 0;

      Pt_Start(20, 0, 0);      // timer started, 20 millisecond accuracy

      PmError error = Pm_OpenInput(&inputStream,
         inputId,
         (void*)DRIVER_INFO,
         preferences.getInt(PREF_IO_PORTMIDI_INPUTBUFFERCOUNT),
         ((PmTimeProcPtr) Pt_Time),
         (void*)TIME_INFO);
      if (error != pmNoError) {
            const char* p = Pm_GetErrorText(error);
            qDebug("PortMidi: open input (id=%d) failed: %s", int(inputId), p);
            Pt_Stop();
            return false;
            }

      Pm_SetFilter(inputStream, PM_FILT_ACTIVE | PM_FILT_CLOCK | PM_FILT_SYSEX);

      PmEvent buffer[1];
      while (Pm_Poll(inputStream))
            Pm_Read(inputStream, buffer, 1);

      if (outputId != pmNoDevice) {
            error = Pm_OpenOutput(&outputStream,
               outputId,
               (void*)DRIVER_INFO,
               preferences.getInt(PREF_IO_PORTMIDI_OUTPUTBUFFERCOUNT),
               ((PmTimeProcPtr) Pt_Time),
               (void*)TIME_INFO,
               preferences.getInt(PREF_IO_PORTMIDI_OUTPUTLATENCYMILLISECONDS));
            if (error != pmNoError) {
                  const char* p = Pm_GetErrorText(error);
                  qDebug("PortMidi: open output (id=%d) failed: %s", int(outputId), p);
                  Pt_Stop();
                  return false;
                  }
            }

      timer = new QTimer();
      timer->setInterval(20);       // 20 msec
      timer->start();
      timer->connect(timer, SIGNAL(timeout()), seq, SLOT(midiInputReady()));
      return true;
      }
Exemplo n.º 4
0
void SonifyBeginSonification()
{
   PmError err = Pm_OpenOutput(&sonMidiStream, Pm_GetDefaultOutputDeviceID(),
                               NULL, 0, NULL, NULL, 0);
   if (err) sonMidiStream = NULL;
   if (sonMidiStream)
      Pm_WriteShort(sonMidiStream, 0, Pm_Message(0xC0, SON_PROGRAM, 0));
   sonificationStarted = true;
}
Exemplo n.º 5
0
bool midibus::init_out ()
{
    PmError err = Pm_OpenOutput(&m_pms, m_pm_num, NULL, 100, NULL, NULL, 0);
    if (err != pmNoError)
    {
        errprintf("Pm_OpenOutput: %s\n", Pm_GetErrorText(err));
        return false;
    }
    return true;
}
Exemplo n.º 6
0
/*
 * Method:    Pm_OpenOutput
 */
JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1OpenOutput
  (JNIEnv *env, jclass cl, jobject jstream, jint index, jstring extras,
   jint bufsiz, jint latency)
{
    PmError rslt;
    PortMidiStream *stream;
    CLASS(c, jstream);
    ADDRESS_FID(fid, c);
    rslt = Pm_OpenOutput(&stream, index, NULL, bufsiz, NULL, NULL, latency);
    SET_PMSTREAM(jstream, fid, stream);
    return rslt;
}
/*!
 @function midi_start
 @abstract
 @discussion
 @param
 @result
 */
void midi_start()
{
    Pm_Initialize();
    Pt_Start(1, NULL, NULL);

    retval = Pm_OpenOutput(&mstream, 0,NULL,512,NULL,NULL,0);
    if(retval != pmNoError)
    {
        printf("error: %s \n", Pm_GetErrorText(retval));
    }
    else /* set channel 1 to grand piano */
        program_change(1, 1);
}
Exemplo n.º 8
0
static int OpenMidiOutDevice_(CSOUND *csound, void **userData, const char *dev)
{
    int         cntdev, devnum;
    PmError     retval;
    PmDeviceInfo *info;
    PortMidiStream *midistream;

    if (UNLIKELY(start_portmidi(csound) != 0))
      return -1;
    /* check if there are any devices available */
    cntdev = portMidi_getDeviceCount(1);
    if (UNLIKELY(cntdev < 1)) {
      return portMidiErrMsg(csound, Str("no output devices are available"));
    }
    /* look up device in list */
    portMidi_listDevices(csound, 1);
    if (dev == NULL || dev[0] == '\0')
      devnum =
        portMidi_getPackedDeviceID((int)Pm_GetDefaultOutputDeviceID(), 1);
    else if (UNLIKELY(dev[0] < '0' || dev[0] > '9')) {
      portMidiErrMsg(csound, Str("error: must specify a device number (>=0), "
                                 "not a name"));
      return -1;
    }
    else
      devnum = (int)atoi(dev);
    if (UNLIKELY(devnum < 0 || devnum >= cntdev)) {
      portMidiErrMsg(csound, Str("error: device number is out of range"));
      return -1;
    }
    info = portMidi_getDeviceInfo(devnum, 1);
    if (info->interf != NULL)
      csound->Message(csound,
                      Str("PortMIDI: selected output device %d: '%s' (%s)\n"),
                      devnum, info->name, info->interf);
    else
      csound->Message(csound,
                      Str("PortMIDI: selected output device %d: '%s'\n"),
                      devnum, info->name);
    retval = Pm_OpenOutput(&midistream,
                           (PmDeviceID) portMidi_getRealDeviceID(devnum, 1),
                           NULL, 512L, (PmTimeProcPtr) NULL, NULL, 0L);
    if (retval != pmNoError) {
      return portMidiErrMsg(csound, Str("error opening output device %d: %s"),
                                    devnum, Pm_GetErrorText(retval));
    }
    *userData = (void*) midistream;
    /* report success */

    return 0;
}
Exemplo n.º 9
0
osd_midi_device *osd_open_midi_output(const char *devname)
{
    int num_devs = Pm_CountDevices();
    int found_dev = -1;
    const PmDeviceInfo *pmInfo;
    PortMidiStream *stm;
    osd_midi_device *ret;

    if (!strcmp("default", devname))
    {
        found_dev = Pm_GetDefaultOutputDeviceID();
    }
    else
    {
        for (int i = 0; i < num_devs; i++)
        {
            pmInfo = Pm_GetDeviceInfo(i);

            if (pmInfo->output)
            {
                if (!strcmp(devname, pmInfo->name))
                {
                    found_dev = i;
                    break;
                }
            }
        }
    }

    if (found_dev >= 0)
    {
        if (Pm_OpenOutput(&stm, found_dev, NULL, 100, NULL, NULL, 0) == pmNoError)
        {
            ret = (osd_midi_device *)osd_malloc(sizeof(osd_midi_device));
            memset(ret, 0, sizeof(osd_midi_device));
            ret->pmStream = stm;
            return ret;
        }
        else
        {
            printf("Couldn't open PM device\n");
            return NULL;
        }
    }
    else
    {
        return NULL;
    }
    return NULL;
}
Exemplo n.º 10
0
void midiOpenDevice(int inId, int outId)
{
        // Initialize time
        Pt_Start(TIME_RESOLUTION_MS, NULL, NULL);

        // Open input
        Pm_OpenInput(&in, inId, NULL, INPUT_BUFFER_SIZE, 
                        (PmTimestamp (*)(void *)) Pt_Time, NULL);
        Pm_SetFilter(in, PM_FILT_ACTIVE | PM_FILT_CLOCK);
        

        // Open output
        Pm_OpenOutput(&out, outId, NULL, OUTPUT_BUFFER_SIZE,
                        (PmTimestamp (*)(void *)) Pt_Time, NULL, 0);
}
Exemplo n.º 11
0
bool osd_midi_device_pm::open_output(const char *devname)
{
	int num_devs = Pm_CountDevices();
	int found_dev = -1;
	const PmDeviceInfo *pmInfo;
	PortMidiStream *stm;

	if (!strcmp("default", devname))
	{
		found_dev = Pm_GetDefaultOutputDeviceID();
	}
	else
	{
		for (int i = 0; i < num_devs; i++)
		{
			pmInfo = Pm_GetDeviceInfo(i);

			if (pmInfo->output)
			{
				if (!strcmp(devname, pmInfo->name))
				{
					found_dev = i;
					break;
				}
			}
		}
	}

	if (found_dev >= 0)
	{
		if (Pm_OpenOutput(&stm, found_dev, NULL, 100, NULL, NULL, 0) == pmNoError)
		{
			pmStream = stm;
			return true;
		}
		else
		{
			printf("Couldn't open PM device\n");
			return false;
		}
	}
	else
	{
		return false;
	}
	return false;
}
/*!
 @function select_midi_out
 @abstract
 @discussion
 @param
 @result
 */
void select_midi_out(PortMidiStream *outstream)
{
    int i;
    int nod;
    int midiout;
    const PmDeviceInfo *di;

    //Get number of devices
    nod=Pm_CountDevices();

    //Display only MIDI OUT devices
    printf("MIDI OUT Devices\n----------------\n");
    for(i=0; i<nod; i++)
    {
        di=Pm_GetDeviceInfo(i);
        if(di->output>0)
        {
            printf("Device ID: %d\n",i);
            printf("Intreface: %s\n     Name: %s\n",di->interf,di->name);
            printf("  Outputs: %d\n",di->output);
            //printf("   Inputs: %d\n  Outputs: %d\n",(di->input>0)?di->input:0,(di->output>0)?di->output:0);
            printf("  Opened?: %s\n\n",(di->opened)?"true":"false");
        }
    }

    do
    {
        printf("Select MIDI OUT Devide ID: ");
        scanf("%d",&midiout);

        retval = Pm_OpenOutput(&outstream, midiout,NULL,512,NULL,NULL,0);
        if(retval != pmNoError)
        {
            printf("error: %s \n\n", Pm_GetErrorText(retval));
        }
        else
        {
            printf("Selected device %d\n\n",midiout);
        }
    }
    while(retval != pmNoError); //while((midiin<0|midiin>nod-1)|(di->input==0));

}
Exemplo n.º 13
0
int initMIDI()
{
	try {
		midiCleanUp();

		TPmErr(Pm_Initialize());
		int nbDev = Pm_CountDevices();
		int inIndex = 0;
		int outIndex = 0;
		int pmdid;

		for( int i = 0; i < nbDev ; ++i ) {
			const PmDeviceInfo* devInfo = Pm_GetDeviceInfo(i);
			if( devInfo->input )
			{
				gNumMIDIInPorts++;
				gMidiInputIndexToPmDevIndex[inIndex++] = i;
				gMidiPmDevIndexToInputIndex[i] = inIndex;
			}
			if( devInfo->output )
			{
				gNumMIDIOutPorts++;
				gMidiOutputIndexToPmDevIndex[outIndex++] = i;
				gMidiPmDevIndexToOutputIndex[i] = outIndex;
			}
		}

		for( int i = 0; i < gNumMIDIOutPorts; i++) {
			pmdid = gMidiOutputIndexToPmDevIndex[i];
			Pm_OpenOutput(&gMIDIOutStreams[i], pmdid, NULL, 512, NULL, NULL, 0);
		}

		/* will call our function, PMProcessMidi() every millisecond */
		Pt_Start(1, &PMProcessMidi, 0); /* start a timer with millisecond accuracy */
	}
	catch(PmError) {
		return errFailed;
	}

	gMIDIInitialized = true;
	return errNone;
}
Exemplo n.º 14
0
TTErr MIDIOutput::setName(TTSymbol& newName)
{
	const PmDeviceInfo*	deviceInfo;
    int					i, deviceCount;
	PmError				err = pmNoError;
	
	if (newName != mName) {
        
        // check there is an output with this name
        deviceCount = Pm_CountDevices();
        for (i = 0; i < deviceCount; i++) {
            
            deviceInfo = Pm_GetDeviceInfo(i);
            
            if (deviceInfo->output && newName == TTSymbol(deviceInfo->name))
                break;
        }
        
        if (i == deviceCount)
            return kTTErrGeneric;
		
		mName = newName;
        
        setRunning(NO);
		
		if (mStream) {
			Pm_Close(mStream);
			mStream = NULL;
		}
		
		err = Pm_OpenOutput(&mStream, i, NULL, kMidiBufferSize, NULL, NULL, 0);
		if (err) {
            
			TTLogError("MIDIOutput::setName : can't open the %s device\n", mName.c_str());
            return kTTErrGeneric;
        }
	}
    
	return kTTErrNone;
}
Exemplo n.º 15
0
MIDIController::MIDIController(const DataSource& __source,
		unsigned int device, unsigned int channel) : source(__source)
{
	keep_polling  = true;

	const PmDeviceInfo* info = Pm_GetDeviceInfo(device);
	assert(info != 0);
	assert(info->output != 0);
	assert(channel < 16);

	this->midi_device  = device;
	this->channel = channel;
	this->midi = NULL;
	this->sending_data = false;

	mute.resize(8);
	for(unsigned int i=0;i<8;i++){
		mute[i] = true; // don't send anything initially
	}

	if(pthread_mutex_init(&portmidi_lock, NULL) != 0){
		throw std::runtime_error("Cannot initialize emotiv mutex.");
	}

	// no latency [TODO: check for errors]
	if(Pm_OpenOutput(&midi, midi_device, NULL, 0, NULL, NULL, 0) != pmNoError){
		pthread_mutex_destroy(&portmidi_lock);
		throw std::runtime_error("Opening MIDI device failed (portmidi).");
	}


	if(pthread_create(&poll_thread, NULL, __midicontroller_thread, (void*)this) != 0){
		pthread_mutex_destroy(&portmidi_lock);
		Pm_Close(midi);
		throw std::runtime_error("Starting thread failed.");
	}
}
Exemplo n.º 16
0
int main()
{
    int id;
    long n;
    const PmDeviceInfo *info;
    char line[STRING_MAX];
    int spin;
    int done = FALSE;

    /* determine what type of test to run */
    printf("begin PortMidi multithread test...\n");
	
    /* note that it is safe to call PortMidi from the main thread for
       initialization and opening devices. You should not make any
       calls to PortMidi from this thread once the midi thread begins.
       to make PortMidi calls.
     */

    /* make the message queues */
    /* messages can be of any size and any type, but all messages in
     * a given queue must have the same size. We'll just use long's
     * for our messages in this simple example
     */
    midi_to_main = Pm_QueueCreate(32, sizeof(long));
    assert(midi_to_main != NULL);
    main_to_midi = Pm_QueueCreate(32, sizeof(long));
    assert(main_to_midi != NULL);

    /* a little test of enqueue and dequeue operations. Ordinarily, 
     * you would call Pm_Enqueue from one thread and Pm_Dequeue from
     * the other. Since the midi thread is not running, this is safe.
     */
    n = 1234567890;
    Pm_Enqueue(midi_to_main, &n);
    n = 987654321;
    Pm_Enqueue(midi_to_main, &n);
	Pm_Dequeue(midi_to_main, &n);
	if (n != 1234567890) {
        exit_with_message("Pm_Dequeue produced unexpected result.");
    }
    Pm_Dequeue(midi_to_main, &n);
	if(n != 987654321) {
        exit_with_message("Pm_Dequeue produced unexpected result.");
    }

    /* always start the timer before you start midi */
    Pt_Start(1, &process_midi, 0); /* start a timer with millisecond accuracy */
    /* the timer will call our function, process_midi() every millisecond */
    
	Pm_Initialize();

    id = Pm_GetDefaultOutputDeviceID();
    info = Pm_GetDeviceInfo(id);
    if (info == NULL) {
        printf("Could not open default output device (%d).", id);
        exit_with_message("");
    }
    printf("Opening output device %s %s\n", info->interf, info->name);

    /* use zero latency because we want output to be immediate */
    Pm_OpenOutput(&midi_out, 
                  id, 
                  DRIVER_INFO,
                  OUTPUT_BUFFER_SIZE,
                  TIME_PROC,
                  TIME_INFO,
                  LATENCY);

    id = Pm_GetDefaultInputDeviceID();
    info = Pm_GetDeviceInfo(id);
    if (info == NULL) {
        printf("Could not open default input device (%d).", id);
        exit_with_message("");
    }
    printf("Opening input device %s %s\n", info->interf, info->name);
    Pm_OpenInput(&midi_in, 
                 id, 
                 DRIVER_INFO,
                 INPUT_BUFFER_SIZE,
                 TIME_PROC,
                 TIME_INFO);

    active = TRUE; /* enable processing in the midi thread -- yes, this
                      is a shared variable without synchronization, but
                      this simple assignment is safe */

    printf("Enter midi input; it will be transformed as specified by...\n");
    printf("%s\n%s\n%s\n",
           "Type 'q' to quit, 'm' to monitor next pitch, t to toggle thru or",
           "type a number to specify transposition.",
		   "Must terminate with [ENTER]");

    while (!done) {
        long msg;
        int len;
        fgets(line, STRING_MAX, stdin);
        /* remove the newline: */
        len = strlen(line);
        if (len > 0) line[len - 1] = 0; /* overwrite the newline char */
        if (strcmp(line, "q") == 0) {
            msg = QUIT_MSG;
            Pm_Enqueue(main_to_midi, &msg);
            /* wait for acknowlegement */
            do {
                spin = Pm_Dequeue(midi_to_main, &msg);
            } while (spin == 0); /* spin */ ;
            done = TRUE; /* leave the command loop and wrap up */
        } else if (strcmp(line, "m") == 0) {
            msg = MONITOR_MSG;
            Pm_Enqueue(main_to_midi, &msg);
            printf("Waiting for note...\n");
            do {
                spin = Pm_Dequeue(midi_to_main, &msg);
            } while (spin == 0); /* spin */ ;
            printf("... pitch is %ld\n", msg);
        } else if (strcmp(line, "t") == 0) {
            /* reading midi_thru asynchronously could give incorrect results,
               e.g. if you type "t" twice before the midi thread responds to
               the first one, but we'll do it this way anyway. Perhaps a more
               correct way would be to wait for an acknowledgement message
               containing the new state. */
            printf("Setting THRU %s\n", (midi_thru ? "off" : "on"));
            msg = THRU_MSG;
            Pm_Enqueue(main_to_midi, &msg);
        } else if (sscanf(line, "%ld", &msg) == 1) {
            if (msg >= -127 && msg <= 127) {
                /* send transposition value */
                printf("Transposing by %ld\n", msg);
                Pm_Enqueue(main_to_midi, &msg);
            } else {
                printf("Transposition must be within -127...127\n");
            }
        } else {
            printf("%s\n%s\n%s\n",
                   "Type 'q' to quit, 'm' to monitor next pitch, or",
                   "type a number to specify transposition.",
				   "Must terminate with [ENTER]");
        }
    }

    /* at this point, midi thread is inactive and we need to shut down
     * the midi input and output
     */
    Pt_Stop(); /* stop the timer */
    Pm_QueueDestroy(midi_to_main);
    Pm_QueueDestroy(main_to_midi);

    /* Belinda! if close fails here, some memory is deleted, right??? */
    Pm_Close(midi_in);
    Pm_Close(midi_out);
    
    printf("finished portMidi multithread test...enter any character to quit [RETURN]...");
    fgets(line, STRING_MAX, stdin);
    return 0;
}
Exemplo n.º 17
0
int main()
{
    char line[STRING_MAX];
    int i;
    int len;
    int choice;
    PtTimestamp stop;
    printf("Latency histogram.\n");
    period = 0;
    while (period < 1) {
        period = get_number("Choose timer period (in ms, >= 1): ");
    }
    printf("Benchmark with:\n\t%s\n\t%s\n\t%s\n\t%s\n",
           "1. No MIDI traffic",
           "2. MIDI input",
           "3. MIDI output",
           "4. MIDI input and output");
    choice = get_number("? ");
    switch (choice) {
      case 1: test_in = 0; test_out = 0; break;
      case 2: test_in = 1; test_out = 0; break;
      case 3: test_in = 0; test_out = 1; break;
      case 4: test_in = 1; test_out = 1; break;
      default: assert(0);
    }
    if (test_in || test_out) {
        /* list device information */
        for (i = 0; i < Pm_CountDevices(); i++) {
            const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
            if ((test_in && info->input) ||
                (test_out && info->output)) {
                printf("%d: %s, %s", i, info->interf, info->name);
                if (info->input) printf(" (input)");
                if (info->output) printf(" (output)");
                printf("\n");
            }
        }
        /* open stream(s) */
        if (test_in) {
            int i = get_number("MIDI input device number: ");
            Pm_OpenInput(&in, 
                  i,
                  NULL, 
                  INPUT_BUFFER_SIZE, 
                  (long (*)(void *)) Pt_Time, 
                  NULL);
            /* turn on filtering; otherwise, input might overflow in the 
               5-second period before timer callback starts reading midi */
            Pm_SetFilter(in, PM_FILT_ACTIVE | PM_FILT_CLOCK);
        }
        if (test_out) {
            int i = get_number("MIDI output device number: ");
            PmEvent buffer[1];
            Pm_OpenOutput(&out, 
                  i,
                  NULL,
                  OUTPUT_BUFFER_SIZE,
                  (long (*)(void *)) Pt_Time,
                  NULL, 
                  0); /* no latency scheduling */

            /* send a program change to force a status byte -- this fixes
               a problem with a buggy linux MidiSport driver, and shouldn't
               hurt anything else
             */
            buffer[0].timestamp = 0;
            buffer[0].message = Pm_Message(0xC0, 0, 0); /* program change */
            Pm_Write(out, buffer, 1);

            output_period = get_number(
                "MIDI out should be sent every __ callback iterations: ");

            assert(output_period >= 1);
        }
    }

    printf("%s%s", "Latency measurements will start in 5 seconds. ",
                   "Type return to stop: ");
    Pt_Start(period, &pt_callback, 0);
    fgets(line, STRING_MAX, stdin);
    stop = Pt_Time();
    Pt_Stop();

    /* courteously turn off the last note, if necessary */
    if (note_on) {
       PmEvent buffer[1];
       buffer[0].timestamp = Pt_Time(NULL);
       buffer[0].message = Pm_Message(0x90, 60, 0);
       Pm_Write(out, buffer, 1);
    }

    /* print the histogram */
    printf("Duration of test: %g seconds\n\n", max(0, stop - 5000) * 0.001);
    printf("Latency(ms)  Number of occurrences\n");
    /* avoid printing beyond last non-zero histogram entry */
    len = min(HIST_LEN, max_latency + 1);
    for (i = 0; i < len; i++) {
        printf("%2d      %10ld\n", i, histogram[i]);
    }
    printf("Number of points greater than %dms: %ld\n", 
           HIST_LEN - 1, out_of_range);
    printf("Maximum latency: %ld milliseconds\n", max_latency);
    printf("\nNote that due to rounding, actual latency can be 1ms higher\n");
    printf("than the numbers reported here.\n");
    printf("Type return to exit...");
    fgets(line, STRING_MAX, stdin);

	if(choice == 2)
		Pm_Close(in);
	else if(choice == 3)
		Pm_Close(out);
	else if(choice == 4)
	{
		Pm_Close(in);
		Pm_Close(out);
	}
    return 0;
}
Exemplo n.º 18
0
/*    The winmm stream mode is used for latency>0, and sends
   timestamped messages. The timestamps are relative (delta) 
   times, whereas PortMidi times are absolute. Since peculiar
   things happen when messages are not always sent in advance,
   this function allows us to exercise the system and test it.
 */
void main_test_stream() {
    PmStream * midi;
	char line[80];
    PmEvent buffer[16];

	/* determine which output device to use */
    int i = get_number("Type output number: ");

	latency = 500; /* ignore LATENCY for this test and
				      fix the latency at 500ms */

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

	/* open output device */
    Pm_OpenOutput(&midi, 
                  i, 
                  DRIVER_INFO,
                  OUTPUT_BUFFER_SIZE, 
                  TIME_PROC,
                  TIME_INFO, 
                  latency);
    printf("Midi Output opened with %ld ms latency.\n", (long) latency);

    /* output note on/off w/latency offset; hold until user prompts */
    printf("ready to send output... (type RETURN):");
    fgets(line, STRING_MAX, stdin);

    /* if we were writing midi for immediate output, we could always use
       timestamps of zero, but since we may be writing with latency, we
       will explicitly set the timestamp to "now" by getting the time.
       The source of timestamps should always correspond to the TIME_PROC
       and TIME_INFO parameters used in Pm_OpenOutput(). */
    buffer[0].timestamp = TIME_PROC(TIME_INFO);
    buffer[0].message = Pm_Message(0xC0, 0, 0);
	buffer[1].timestamp = buffer[0].timestamp;
	buffer[1].message = Pm_Message(0x90, 60, 100);
	buffer[2].timestamp = buffer[0].timestamp + 1000;
	buffer[2].message = Pm_Message(0x90, 62, 100);
	buffer[3].timestamp = buffer[0].timestamp + 2000;
	buffer[3].message = Pm_Message(0x90, 64, 100);
	buffer[4].timestamp = buffer[0].timestamp + 3000;
	buffer[4].message = Pm_Message(0x90, 66, 100);
	buffer[5].timestamp = buffer[0].timestamp + 4000;
	buffer[5].message = Pm_Message(0x90, 60, 0);
	buffer[6].timestamp = buffer[0].timestamp + 4000;
	buffer[6].message = Pm_Message(0x90, 62, 0);
	buffer[7].timestamp = buffer[0].timestamp + 4000;
	buffer[7].message = Pm_Message(0x90, 64, 0);
	buffer[8].timestamp = buffer[0].timestamp + 4000;
	buffer[8].message = Pm_Message(0x90, 66, 0);

    Pm_Write(midi, buffer, 9);
#ifdef SEND8
	/* Now, we're ready for the real test.
	   Play 4 notes at now, now+500, now+1000, and now+1500
	   Then wait until now+2000.
	   Play 4 more notes as before.
	   We should hear 8 evenly spaced notes. */
	now = TIME_PROC(TIME_INFO);
	for (i = 0; i < 4; i++) {
		buffer[i * 2].timestamp = now + (i * 500);
		buffer[i * 2].message = Pm_Message(0x90, 60, 100);
		buffer[i * 2 + 1].timestamp = now + 250 + (i * 500);
		buffer[i * 2 + 1].message = Pm_Message(0x90, 60, 0);
	}
    Pm_Write(midi, buffer, 8);

    while (Pt_Time() < now + 2500) 
		/* busy wait */;
	/* now we are 500 ms behind schedule, but since the latency
	   is 500, the delay should not be audible */
	now += 2000;
	for (i = 0; i < 4; i++) {
		buffer[i * 2].timestamp = now + (i * 500);
		buffer[i * 2].message = Pm_Message(0x90, 60, 100);
		buffer[i * 2 + 1].timestamp = now + 250 + (i * 500);
		buffer[i * 2 + 1].message = Pm_Message(0x90, 60, 0);
	}
    Pm_Write(midi, buffer, 8);
#endif
    /* close device (this not explicitly needed in most implementations) */
    printf("ready to close and terminate... (type RETURN):");
    fgets(line, STRING_MAX, stdin);
	
    Pm_Close(midi);
    Pm_Terminate();
    printf("done closing and terminating...\n");
}
Exemplo n.º 19
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(); 
}
Exemplo n.º 20
0
void main_test_output() {
    PmStream * midi;
	char line[80];
    int32_t off_time;
    int chord[] = { 60, 67, 76, 83, 90 };
    #define chord_size 5 
    PmEvent buffer[chord_size];
    PmTimestamp timestamp;

    /* determine which output device to use */
    int i = get_number("Type output number: ");

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

    /* open output device -- since PortMidi avoids opening a timer
       when latency is zero, we will pass in a NULL timer pointer
       for that case. If PortMidi tries to access the time_proc,
       we will crash, so this test will tell us something. */
    Pm_OpenOutput(&midi, 
                  i, 
                  DRIVER_INFO,
                  OUTPUT_BUFFER_SIZE, 
                  (latency == 0 ? NULL : TIME_PROC),
                  (latency == 0 ? NULL : TIME_INFO), 
                  latency);
    printf("Midi Output opened with %ld ms latency.\n", (long) latency);

    /* output note on/off w/latency offset; hold until user prompts */
    printf("ready to send program 1 change... (type RETURN):");
    fgets(line, STRING_MAX, stdin);
    /* if we were writing midi for immediate output, we could always use
       timestamps of zero, but since we may be writing with latency, we
       will explicitly set the timestamp to "now" by getting the time.
       The source of timestamps should always correspond to the TIME_PROC
       and TIME_INFO parameters used in Pm_OpenOutput(). */
    buffer[0].timestamp = TIME_PROC(TIME_INFO);
    /* Send a program change to increase the chances we will hear notes */
    /* Program 0 is usually a piano, but you can change it here: */
#define PROGRAM 0
    buffer[0].message = Pm_Message(0xC0, PROGRAM, 0);
    Pm_Write(midi, buffer, 1);

    printf("ready to note-on... (type RETURN):");
    fgets(line, STRING_MAX, stdin);
    buffer[0].timestamp = TIME_PROC(TIME_INFO);
    buffer[0].message = Pm_Message(0x90, 60, 100);
    Pm_Write(midi, buffer, 1);
    printf("ready to note-off... (type RETURN):");
    fgets(line, STRING_MAX, stdin);
    buffer[0].timestamp = TIME_PROC(TIME_INFO);
    buffer[0].message = Pm_Message(0x90, 60, 0);
    Pm_Write(midi, buffer, 1);

    /* output short note on/off w/latency offset; hold until user prompts */
    printf("ready to note-on (short form)... (type RETURN):");
    fgets(line, STRING_MAX, stdin);
    Pm_WriteShort(midi, TIME_PROC(TIME_INFO),
                  Pm_Message(0x90, 60, 100));
    printf("ready to note-off (short form)... (type RETURN):");
    fgets(line, STRING_MAX, stdin);
    Pm_WriteShort(midi, TIME_PROC(TIME_INFO),
                  Pm_Message(0x90, 60, 0));

    /* output several note on/offs to test timing. 
       Should be 1s between notes */
    printf("chord will arpeggiate if latency > 0\n");
    printf("ready to chord-on/chord-off... (type RETURN):");
    fgets(line, STRING_MAX, stdin);
    timestamp = TIME_PROC(TIME_INFO);
    for (i = 0; i < chord_size; i++) {
        buffer[i].timestamp = timestamp + 1000 * i;
        buffer[i].message = Pm_Message(0x90, chord[i], 100);
    }
    Pm_Write(midi, buffer, chord_size);

    off_time = timestamp + 1000 + chord_size * 1000; 
    while (TIME_PROC(TIME_INFO) < off_time) 
		/* busy wait */;
    for (i = 0; i < chord_size; i++) {
        buffer[i].timestamp = timestamp + 1000 * i;
        buffer[i].message = Pm_Message(0x90, chord[i], 0);
    }
    Pm_Write(midi, buffer, chord_size);    

    /* close device (this not explicitly needed in most implementations) */
    printf("ready to close and terminate... (type RETURN):");
    fgets(line, STRING_MAX, stdin);
	
    Pm_Close(midi);
    Pm_Terminate();
    printf("done closing and terminating...\n");
}
Exemplo n.º 21
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
  int code = 'L';
  PmError err;
  
  init(); /* returns immediately if already done */
  
  if (nrhs > 0) {
    char arg[2];
    
    if (mxIsUint8(prhs[0])) {
      if (outStream == NULL) {
        mexErrMsgTxt("No MIDI output device is opened");
      } else {
        playRaw(prhs[0]);
      }
      return;
    }
    
    if (!mxIsChar(prhs[0]) || mxGetNumberOfElements(prhs[0]) > 1) {
      mexErrMsgTxt("Bad call\n");
    }
    mxGetString(prhs[0], arg, 2);
    code = arg[0];
  }
  
  switch(code) {
    case 'P':
      if (outStream == NULL) {
        mexErrMsgTxt("No MIDI output device is opened");
      } else {
        if (nrhs < 3) mexErrMsgTxt("Usage for 'program change': midiOut('P', channel, program)");
        sendProgChange(prhs);
      }
      break;
    case '+':	/* Note on */
      if (outStream == NULL) {
        mexErrMsgTxt("No MIDI output device is opened");
      } else {
        if (nrhs < 4) mexErrMsgTxt("Usage for 'note on': midiOut('+', channel, notes, velocities)");
        sendNoteOnOff(0x90, prhs);
      }
      break;
    case '-': 	/* Note off */
      if (outStream == NULL) {
        mexErrMsgTxt("No MIDI output device is opened");
      } else {
        if (nrhs < 4) mexErrMsgTxt("Usage for 'note on': midiOut('+', channel, notes, velocities)");
        sendNoteOnOff(0x80, prhs);
      }
      break;
    case '.':	/* All notes off */
      if (outStream == NULL) {
        mexErrMsgTxt("No MIDI output device is opened");
      } else {
        int channel;
        
        if (nrhs < 2) mexErrMsgTxt("Usage for 'all notes off': midiOut('.', channel)");
        channel = (int) mxGetScalar(prhs[1]);
        if (channel < 1 || channel > 16) mexErrMsgTxt("Channel (2nd arg.) must be 1..16");
        --channel;
        err = Pm_WriteShort(outStream, 0, Pm_Message(0xB0 | channel, 123, 0));
        if (err!=pmNoError) reportPmError(err);
      }
      break;
    case 'C':   /* Close output stream */
      if (outStream == NULL) {
        mexWarnMsgTxt("No MIDI output device is opened - ignoring 'close' command");
      } else {
        err = Pm_Close(outStream);
        outStream = NULL;
      }
      break;
    case 'O':	/* Open output stream */
    {
      int device = 0;
      
      
      if (nrhs<2 || !mxIsNumeric(prhs[1])) mexErrMsgTxt("Bad call\n");
      device = (int) mxGetScalar(prhs[1]);
      if (device < 1 || device > Pm_CountDevices()) mexErrMsgTxt("Device index out of range");
      --device;
      
      if (outStream != NULL) {
        if (openID == device) {
          mexWarnMsgTxt("MIDI output device is already open - ignoring request");
          return;
        }
        mexWarnMsgTxt("Another MIDI output device is open - closing that one");
        err = Pm_Close(outStream);
        outStream = NULL;
        if (err != pmNoError) reportPmError(err);
      }
      
      /* last parameter = latency = 0 means that timestamps are ignored */
      err = Pm_OpenOutput(&outStream, device, NULL, OUTPUT_BUFFER_SIZE, NULL, NULL, 0);
      if (err != pmNoError) {
        outStream = NULL;
        reportPmError(err);
      }
      openID = device;
    }
    break;
    case 'L':	/* List devices */
      plhs[0] = getDevices();
      break;
    default:
      mexErrMsgTxt("Bad call\n");
  }
}
Exemplo n.º 22
0
int
Server_pm_init(Server *self)
{
    int i = 0, ret = 0;
    PmError pmerr;

    if (self->midiActive == 0) {
        self->withPortMidi = 0;
        self->withPortMidiOut = 0;
        return 0;
    }

    pmerr = Pm_Initialize();
    if (pmerr) {
        Server_warning(self, "Portmidi warning: could not initialize Portmidi: %s\n", Pm_GetErrorText(pmerr));
        self->withPortMidi = 0;
        self->withPortMidiOut = 0;
        return -1;
    }
    else {
        Server_debug(self, "Portmidi initialized.\n");
        self->withPortMidi = 1;
        self->withPortMidiOut = 1;
    }

    PyoPmBackendData *be_data = (PyoPmBackendData *) malloc(sizeof(PyoPmBackendData *));
    self->midi_be_data = (void *) be_data;

    if (self->withPortMidi == 1) {
        self->midiin_count = self->midiout_count = 0;
        int num_devices = Pm_CountDevices();
        Server_debug(self, "Portmidi number of devices: %d.\n", num_devices);
        if (num_devices > 0) {
            if (self->midi_input < num_devices) {
                if (self->midi_input == -1)
                    self->midi_input = Pm_GetDefaultInputDeviceID();
                Server_debug(self, "Midi input device : %d.\n", self->midi_input);
                const PmDeviceInfo *info = Pm_GetDeviceInfo(self->midi_input);
                if (info != NULL) {
                    if (info->input) {
                        pmerr = Pm_OpenInput(&be_data->midiin[0], self->midi_input, NULL, 100, NULL, NULL);
                        if (pmerr) {
                            Server_warning(self,
                                 "Portmidi warning: could not open midi input %d (%s): %s\n",
                                 self->midi_input, info->name, Pm_GetErrorText(pmerr));
                            self->withPortMidi = 0;
                        }
                        else {
                            Server_debug(self, "Midi input (%s) opened.\n", info->name);
                            self->midiin_count = 1;
                        }
                    }
                    else {
                        Server_warning(self, "Portmidi warning: Midi Device (%s), not an input device!\n", info->name);
                        self->withPortMidi = 0;
                    }
                }
            }
            else if (self->midi_input >= num_devices) {
                Server_debug(self, "Midi input device : all!\n");
                self->midiin_count = 0;
                for (i=0; i<num_devices; i++) {
                    const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
                    if (info != NULL) {
                        if (info->input) {
                            pmerr = Pm_OpenInput(&be_data->midiin[self->midiin_count], i, NULL, 100, NULL, NULL);
                            if (pmerr) {
                                Server_warning(self,
                                     "Portmidi warning: could not open midi input %d (%s): %s\n",
                                     0, info->name, Pm_GetErrorText(pmerr));
                            }
                            else {
                                Server_debug(self, "Midi input (%s) opened.\n", info->name);
                                self->midiin_count++;
                            }
                        }
                    }
                }
                if (self->midiin_count == 0)
                    self->withPortMidi = 0;
            }
            else {
                    Server_warning(self, "Portmidi warning: no input device!\n");
                    self->withPortMidi = 0;
            }

            if (self->midi_output < num_devices) {
                if (self->midi_output == -1)
                    self->midi_output = Pm_GetDefaultOutputDeviceID();
                Server_debug(self, "Midi output device : %d.\n", self->midi_output);
                const PmDeviceInfo *outinfo = Pm_GetDeviceInfo(self->midi_output);
                if (outinfo != NULL) {
                    if (outinfo->output) {
                        Pt_Start(1, 0, 0); /* start a timer with millisecond accuracy */
                        pmerr = Pm_OpenOutput(&be_data->midiout[0], self->midi_output, NULL, 0, NULL, NULL, 1);
                        if (pmerr) {
                            Server_warning(self,
                                     "Portmidi warning: could not open midi output %d (%s): %s\n",
                                     self->midi_output, outinfo->name, Pm_GetErrorText(pmerr));
                            self->withPortMidiOut = 0;
                            if (Pt_Started())
                                Pt_Stop();
                        }
                        else {
                            Server_debug(self, "Midi output (%s) opened.\n", outinfo->name);
                            self->midiout_count = 1;
                        }
                    }
                    else {
                        Server_warning(self, "Portmidi warning: Midi Device (%s), not an output device!\n", outinfo->name);
                        self->withPortMidiOut = 0;
                    }
                }
            }
            else if (self->midi_output >= num_devices) {
                Server_debug(self, "Midi output device : all!\n");
                self->midiout_count = 0;
                Pt_Start(1, 0, 0); /* start a timer with millisecond accuracy */
                for (i=0; i<num_devices; i++) {
                    const PmDeviceInfo *outinfo = Pm_GetDeviceInfo(i);
                    if (outinfo != NULL) {
                        if (outinfo->output) {
                            pmerr = Pm_OpenOutput(&be_data->midiout[self->midiout_count], i, NULL, 100, NULL, NULL, 1);
                            if (pmerr) {
                                Server_warning(self,
                                     "Portmidi warning: could not open midi output %d (%s): %s\n",
                                     0, outinfo->name, Pm_GetErrorText(pmerr));
                            }
                            else {
                                Server_debug(self, "Midi output (%s) opened.\n", outinfo->name);
                                self->midiout_count++;
                            }
                        }
                    }
                }
                if (self->midiout_count == 0) {
                    if (Pt_Started())
                        Pt_Stop();
                    self->withPortMidiOut = 0;
                }
            }
            else {
                    Server_warning(self, "Portmidi warning: no output device!\n");
                    self->withPortMidiOut = 0;
            }

            if (self->withPortMidi == 0 && self->withPortMidiOut == 0) {
                Pm_Terminate();
                Server_warning(self, "Portmidi closed.\n");
                ret = -1;
            }
        }
        else {
            Server_warning(self, "Portmidi warning: no midi device found!\nPortmidi closed.\n");
            self->withPortMidi = 0;
            self->withPortMidiOut = 0;
            Pm_Terminate();
            ret = -1;
        }
    }
    if (self->withPortMidi == 1) {
        self->midi_count = 0;
        for (i=0; i<self->midiin_count; i++) {
            Pm_SetFilter(be_data->midiin[i], PM_FILT_ACTIVE | PM_FILT_CLOCK);
        }
    }
    return ret;
}
Exemplo n.º 23
0
void sys_do_open_midi(int nmidiin, int *midiinvec,
                      int nmidiout, int *midioutvec)
{
    int i = 0, j, devno;
    int n = 0;
    PmError err;

    Pt_Start(1, 0, 0); /* start a timer with millisecond accuracy */

    mac_nmidiindev = 0;
    for (i = 0; i < nmidiin; i++)
    {
        for (j = 0, devno = 0; j < Pm_CountDevices(); j++)
        {
            const PmDeviceInfo *info = Pm_GetDeviceInfo(j);
            if (info->input)
            {
                if (devno == midiinvec[i])
                {
                    err = Pm_OpenInput(&mac_midiindevlist[mac_nmidiindev],
                                       j, NULL, 100, NULL, NULL);
                    if (err)
                        post("could not open midi input %d (%s): %s",
                             j, info->name, Pm_GetErrorText(err));

                    else
                    {
                        if (sys_verbose)
                            post("Midi Input (%s) opened.",
                                 info->name);
                        mac_nmidiindev++;
                    }
                }
                devno++;
            }
        }
    }

    mac_nmidioutdev = 0;
    for (i = 0; i < nmidiout; i++)
    {
        for (j = 0, devno = 0; j < Pm_CountDevices(); j++)
        {
            const PmDeviceInfo *info = Pm_GetDeviceInfo(j);
            if (info->output)
            {
                if (devno == midioutvec[i])
                {
                    err = Pm_OpenOutput(
                              &mac_midioutdevlist[mac_nmidioutdev],
                              j, NULL, 0, NULL, NULL, 0);
                    if (err)
                        post("could not open midi output %d (%s): %s",
                             j, info->name, Pm_GetErrorText(err));
                    else
                    {
                        if (sys_verbose)
                            post("Midi Output (%s) opened.",
                                 info->name);
                        mac_nmidioutdev++;
                    }
                }
                devno++;
            }
        }
    }
}