コード例 #1
0
ファイル: keyboard.c プロジェクト: glocklueng/midiDmxCtrlv2
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;
}
コード例 #2
0
void MidiSession::openDevice(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_OpenInput(&midiStream, i, nullptr, 3, nullptr, nullptr);
            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;
        }
    }
}
コード例 #3
0
ファイル: SC_PortMIDI.cpp プロジェクト: 2mc/supercollider
int prConnectMIDIIn(struct VMGlobals *g, int numArgsPushed)
{
	ScopeMutexLock mulo(&gPmStreamMutex);

	//PyrSlot *a = g->sp - 2;
	PyrSlot *b = g->sp - 1;
	PyrSlot *c = g->sp;

	int err, inputIndex, uid;
	err = slotIntVal(b, &inputIndex);
	if (err) return errWrongType;
	if (inputIndex < 0 || inputIndex >= gNumMIDIInPorts) 
	return errIndexOutOfRange;

	err = slotIntVal(c, &uid);
	if (err) 
	return errWrongType;

	PmStream* inStream = NULL;
	int pmdid = gMidiInputIndexToPmDevIndex[uid];

	PmError pmerr = Pm_OpenInput( &inStream, pmdid, 
	PMSTREAM_DRIVER_INFO,
	PMSTREAM_INPUT_BUFFER_SIZE,
	PMSTREAM_TIME_PROC,
	PMSTREAM_TIME_INFO );

	if(pmerr != pmNoError)
	return errFailed;

	gMIDIInStreams[uid] = inStream;
	return errNone;
}
コード例 #4
0
void FLiveEditorManager::FindDevices()
{
	//find all our devices
	int NumDevices = Pm_CountDevices(); //needs to remain int (instead of int32) since numbers are derived from TPL that uses int
	for ( int i = 0; i < NumDevices; i++ )
	{
		const PmDeviceInfo *Info = Pm_GetDeviceInfo( i );
		if ( Info->input && !InputConnections.Find(i) )
		{
			PortMidiStream *MIDIStream;
			PmError Error = Pm_OpenInput( &MIDIStream, i, NULL, DEFAULT_BUFFER_SIZE, NULL, NULL );
			if ( Error == pmNoError )
			{
				FLiveEditorDeviceInstance DeviceInstance;
				DeviceInstance.Data.DeviceName = FString(Info->name);

				DeviceInstance.Connection.MIDIStream = MIDIStream;

				LoadDeviceData( DeviceInstance.Data.DeviceName, DeviceInstance.Data );

				InputConnections.Add( i, DeviceInstance );
			}
		}
	}
}
コード例 #5
0
ファイル: test.c プロジェクト: AkiraShirase/audacity
/*
 * the somethingStupid parameter can be set to simulate a program crash.
 * We want PortMidi to close Midi ports automatically in the event of a
 * crash because Windows does not (and this may cause an OS crash)
 */
void main_test_input(unsigned int somethingStupid) {
    PmStream * midi;
    PmError status, length;
    PmEvent buffer[1];
    int num = 10;
    int i = get_number("Type input number: ");
    /* It is recommended to start timer before Midi; otherwise, PortMidi may
       start the timer with its (default) parameters
     */
    TIME_START;

    /* open input device */
    Pm_OpenInput(&midi, 
                 i,
                 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 | PM_FILT_SYSEX);
    /* empty the buffer after setting filter, just in case anything
       got through */
    while (Pm_Poll(midi)) {
        Pm_Read(midi, buffer, 1);
    }
    /* now start paying attention to messages */
    i = 0; /* count messages as they arrive */
    while (i < num) {
        status = Pm_Poll(midi);
        if (status == TRUE) {
            length = Pm_Read(midi,buffer, 1);
            if (length > 0) {
                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);
            }
        }
        /* simulate crash if somethingStupid is 1 or 2 */
        if ((i > (num/2)) && (somethingStupid == 1)) {
            doSomethingStupid();
        } else if ((i > (num/2)) && (somethingStupid == 2)) {
            doSomethingReallyStupid();
        }
    }

    /* close device (this not explicitly needed in most implementations) */
    printf("ready to close...");

    Pm_Close(midi);
    printf("done closing...");
}
コード例 #6
0
ファイル: pm.cpp プロジェクト: IsaacWeiss/MuseScore
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;
      }
コード例 #7
0
ファイル: keyboard.c プロジェクト: 2bt/little-synths
int keyboard_init() {
	Pm_Initialize();
	const PmDeviceInfo* dev_info = Pm_GetDeviceInfo(KEYBOARD_DEV_ID);
	if (dev_info) {
		Pm_OpenInput(&midi_stream, KEYBOARD_DEV_ID, NULL, KEYBOARD_MAX_EVENTS, NULL, NULL);
		return 1;
	}
	return 0;
}
コード例 #8
0
ファイル: midibus_portmidi.cpp プロジェクト: EQ4/sequencer64
bool midibus::init_in ()
{
    PmError err = Pm_OpenInput(&m_pms, m_pm_num, NULL, 100, NULL, NULL);
    if (err != pmNoError)
    {
        errprintf("Pm_OpenInput: %s\n", Pm_GetErrorText(err));
        return false;
    }
    return true;
}
コード例 #9
0
ファイル: port_midi.c プロジェクト: ssj71/reMID.lv2
int port_init_seq()
{
    //if(seq_handle!=NULL) return 1;

    pm_status=Pm_Initialize();
    if(pm_status!=pmNoError)
    {
        fprintf(stderr, "Error initialising PortMIDI\n");
        return 0;
    }

    int i;
    const PmDeviceInfo *pm_dev_info;
    int num_devices=Pm_CountDevices();
    printf("Available MIDI devices:\n");
    for(i=0; i<num_devices; i++)
    {
        pm_dev_info=Pm_GetDeviceInfo(i);
        if(pm_dev_info->input) printf("%d: %s\n", i, pm_dev_info->name);
    }
    printf("\n");

    pm_status=Pm_OpenInput(&pm_stream, midiport, DRIVER_INFO, INPUT_BUFFER_SIZE, NULL, NULL);
    if(pm_status!=pmNoError)
    {
        fprintf(stderr, "Error opening MIDI input device\n");
    }


    /*
    	if(snd_seq_open(&seq_handle, "default", SND_SEQ_OPEN_INPUT, 0)<0) {
    		fprintf(stderr, "Error opening ALSA sequencer.\n");
    		return 0;
    	}

    	snd_seq_set_client_name(seq_handle, clientname);

    	in_port=snd_seq_create_simple_port(seq_handle, portname,
    		SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE,
    		SND_SEQ_PORT_TYPE_APPLICATION);

    	if(in_port<0) {
    		fprintf(stderr, "Error creating sequencer port.\n");
    		return 0;
    	}

    	npfd=snd_seq_poll_descriptors_count(seq_handle, POLLIN);
    	pfd=(struct pollfd *)malloc(npfd*sizeof(struct pollfd));
    	snd_seq_poll_descriptors(seq_handle, pfd, npfd, POLLIN);
    */

    return 1;
}
コード例 #10
0
QMidiSequencer::QMidiSequencer(QString clientName, int device, QObject *parent) :
    QThread(parent)
{;
    TIME_START;
    Pm_OpenInput(&m_midi,
                 device,
                 DRIVER_INFO,
                 INPUT_BUFFER_SIZE,
                 TIME_PROC,
                 TIME_INFO);
    //Pm_SetFilter(m_midi, PM_FILT_ACTIVE | PM_FILT_CLOCK | PM_FILT_SYSEX);
}
コード例 #11
0
ファイル: pmjni.c プロジェクト: AkiraShirase/audacity
/*
 * Method:    Pm_OpenInput
 */
JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1OpenInput
  (JNIEnv *env, jclass cl, 
   jobject jstream, jint index, jstring extras, jint bufsiz)
{
    PmError rslt;
    PortMidiStream *stream;
    CLASS(c, jstream);
    ADDRESS_FID(fid, c);
    rslt = Pm_OpenInput(&stream, index, NULL, bufsiz, NULL, NULL);
    SET_PMSTREAM(jstream, fid, stream);
    return rslt;
}
コード例 #12
0
ファイル: portmidi.c プロジェクト: crazii/mameplus
osd_midi_device *osd_open_midi_input(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_GetDefaultInputDeviceID();
    }
    else
    {
        for (int i = 0; i < num_devs; i++)
        {
            pmInfo = Pm_GetDeviceInfo(i);

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

    if (found_dev >= 0)
    {
        if (Pm_OpenInput(&stm, found_dev, NULL, RX_EVENT_BUF_SIZE, NULL, NULL) == 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;
    }
}
コード例 #13
0
ファイル: midi.c プロジェクト: amoweb/RaspberryBoucle
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);
}
コード例 #14
0
ファイル: portmidi.cpp プロジェクト: ccmurray/mame
bool osd_midi_device_pm::open_input(const char *devname)
{
	int num_devs = Pm_CountDevices();
	int found_dev = -1;
	const PmDeviceInfo *pmInfo;
	PortMidiStream *stm;

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

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

	if (found_dev >= 0)
	{
		if (Pm_OpenInput(&stm, found_dev, nullptr, RX_EVENT_BUF_SIZE, nullptr, nullptr) == pmNoError)
		{
			pmStream = stm;
			return true;
		}
		else
		{
			printf("Couldn't open PM device\n");
			return false;
		}
	}
	else
	{
		return false;
	}
}
コード例 #15
0
ファイル: server.cpp プロジェクト: 2bt/terminal-tracker
void Server::start() {
	// midi
	Pm_Initialize();
	int dev_count = Pm_CountDevices();
	int i;
	for (i = 0; i < dev_count; i++) {
		auto info = Pm_GetDeviceInfo(i);
		if (info->output &&
			std::string(info->name).find("MIDI") != std::string::npos) break;
	}
	if (i < dev_count) Pm_OpenInput(&m_midi, 3, nullptr, 0, nullptr, nullptr);

	// start sound server
	static SDL_AudioSpec spec = { MIXRATE, AUDIO_S16SYS,
		2, 0, 1024, 0, 0, &Server::audio_callback, this
	};
	SDL_OpenAudio(&spec, &spec);
	SDL_PauseAudio(0);
}
コード例 #16
0
/*!
 @function select_midi_in
 @abstract
 @discussion
 @param
 @result
 */
void select_midi_in(PortMidiStream *instream)
{
    int i;
    int nod;
    int midiin;
    const PmDeviceInfo * di;

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

    //Display only MIDI IN devices
    printf("MIDI IN Devices\n----------------\n");
    for(i=0; i<nod; i++)
    {
        di=Pm_GetDeviceInfo(i);
        if(di->input>0)
        {
            printf("Device ID: %d\n",i);
            printf("Intreface: %s\n     Name: %s\n",di->interf,di->name);
            printf("   Inputs: %d\n",di->input);
            //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 IN Devide ID: ");
        scanf("%d",&midiin);
        printf("%d\n\n",midiin);
        retval = Pm_OpenInput(&instream, midiin,NULL,512,NULL,NULL);
        if(retval != pmNoError)
        {
            printf("error: %s \n\n", Pm_GetErrorText(retval));
        }
        else
        {
            printf("Selected device %d\n\n",midiin);
        }
    }
    while(retval != pmNoError); //while((midiin<0|midiin>nod-1)|(di->input==0));
}
コード例 #17
0
ファイル: pm.cpp プロジェクト: Angeldude/MuseScore
bool PortMidiDriver::init()
      {
      inputId = getDeviceIn(preferences.portMidiInput);
      if(inputId == -1)
        inputId  = Pm_GetDefaultInputDeviceID();
      outputId = Pm_GetDefaultOutputDeviceID();

      if (inputId == pmNoDevice)
            return false;

      static const int INPUT_BUFFER_SIZE = 100;
      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, INPUT_BUFFER_SIZE,
         ((long (*)(void*)) 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);

      timer = new QTimer();
      timer->setInterval(20);       // 20 msec
      timer->start();
      timer->connect(timer, SIGNAL(timeout()), seq, SLOT(midiInputReady()));
      return true;
      }
コード例 #18
0
ファイル: MIDIInput.cpp プロジェクト: EQ4/JamomaCore
TTErr MIDIInput::setName(TTSymbol& newName)
{
	const PmDeviceInfo*	deviceInfo;
    int					i, deviceCount;
	PmError				err = pmNoError;
	
	if (newName != mName) {
        
        // check there is an input with this name
        deviceCount = Pm_CountDevices();
        for (i = 0; i < deviceCount; i++) {
            
            deviceInfo = Pm_GetDeviceInfo(i);
            
            if (deviceInfo->input && newName == TTSymbol(deviceInfo->name))
                break;
        }
        
        if (i == deviceCount)
            return kTTErrGeneric;
		
		mName = newName;
        
        setRunning(NO);
		
		if (mStream) {
			Pm_Close(mStream);
			mStream = NULL;
		}
		
		err = Pm_OpenInput(&mStream, i, NULL, kMidiBufferSize, NULL, NULL);
		if (err) {
            
			TTLogError("MIDIInput::setName : can't open the %s device\n", mName.c_str());
            return kTTErrGeneric;
        }
	}
    
	return kTTErrNone;
}
コード例 #19
0
ファイル: md_portmidi.c プロジェクト: Rotbaeckchen/pyo
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;
}
コード例 #20
0
ファイル: latency.c プロジェクト: gillspice/mios32
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;
}
コード例 #21
0
ファイル: midiIn.c プロジェクト: JmauLeonetti/eegsynth
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
  int code = 'L';
  PmError err1;
  PtError err2;
  
  init(); /* this returns immediately if already done */
  
  if (nrhs > 0) {
    char arg[2];
    if (!mxIsChar(prhs[0]) || mxGetNumberOfElements(prhs[0]) > 1) {
      mexErrMsgTxt("Bad call\n");
    }
    mxGetString(prhs[0], arg, 2);
    code = arg[0];
  }
  
  switch(code) {
    case 'V':
      if (inStream == NULL) {
        mexErrMsgTxt("No MIDI input device is opened");
      } else {
        if (nrhs < 2) mexErrMsgTxt("Usage for 'verbose': midiIn('V', value)");
        verbose = mxGetScalar(prhs[1]);
      }
      break;
    case 'G': /* Return the buffered events as array */
      if (inStream == NULL) {
        mexErrMsgTxt("No MIDI input device is opened");
      } else {
        plhs[0] = getEvent();
      }
      break;
    case 'F': /* Flush all buffered events */
      if (inStream == NULL) {
        mexErrMsgTxt("No MIDI input device is opened");
      } else {
        /* reset the counter to the beginning of the buffer */
        numReceived = 0;
      }
      break;
    case 'C':   /* Close input stream */
      if (inStream == NULL) {
        mexWarnMsgTxt("No MIDI input device is opened - ignoring 'close' command");
      } else {
        err1 = Pm_Close(inStream);
        inStream = NULL;
        if (err1 != pmNoError) reportPmError(err1);
      }
      break;
    case 'O':	/* Open input 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 (inStream != NULL) {
        if (deviceOpen == device) {
          mexWarnMsgTxt("MIDI input device is already open - ignoring request");
          return;
        }
        mexWarnMsgTxt("Another MIDI input device is open - closing that one");
        err1 = Pm_Close(inStream);
        inStream = NULL;
        if (err1 != pmNoError) reportPmError(err1);
      }
      
      err1 = Pm_OpenInput(&inStream, device, NULL, INPUT_BUFFER_SIZE, NULL, NULL);
      if (err1 != pmNoError) {
        inStream = NULL;
        reportPmError(err1);
      }
      
      /* remember which device we just opened */
      deviceOpen = device;
    }
    break;
    case 'L':	/* List devices */
      plhs[0] = getDevices();
      break;
    default:
      mexErrMsgTxt("Bad call\n");
  }
}
コード例 #22
0
ファイル: midilistenermodule.c プロジェクト: belangeo/pyo
static PyObject * MidiListener_play(MidiListener *self) {
    int i, num_devices;
    PmError pmerr;

    /* always start the timer before you start midi */
    Pt_Start(1, &process_midi, (void *)self);
    
    pmerr = Pm_Initialize();
    if (pmerr) {
        PySys_WriteStdout("Portmidi warning: could not initialize Portmidi: %s\n", Pm_GetErrorText(pmerr));
    }

    num_devices = Pm_CountDevices();
    if (num_devices > 0) {
        if (self->mididev < num_devices) {
            if (self->mididev == -1)
                self->mididev = Pm_GetDefaultInputDeviceID();
            const PmDeviceInfo *info = Pm_GetDeviceInfo(self->mididev);
            if (info != NULL) {
                if (info->input) {
                    pmerr = Pm_OpenInput(&self->midiin[0], self->mididev, NULL, 100, NULL, NULL);
                    if (pmerr) {
                        PySys_WriteStdout("Portmidi warning: could not open midi input %d (%s): %s\n",
                             self->mididev, info->name, Pm_GetErrorText(pmerr));
                    }
                    else {
                        self->midicount = 1;
                    }
                }
            }
        }
        else if (self->mididev >= num_devices) {
            self->midicount = 0;
            for (i=0; i<num_devices; i++) {
                const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
                if (info != NULL) {
                    if (info->input) {
                        pmerr = Pm_OpenInput(&self->midiin[self->midicount], i, NULL, 100, NULL, NULL);
                        if (pmerr) {
                            PySys_WriteStdout("Portmidi warning: could not open midi input %d (%s): %s\n",
                                    i, info->name, Pm_GetErrorText(pmerr));
                        }
                        else {
                            self->midicount++;
                        }
                    }
                }
            }
        }
    }

    for (i=0; i<self->midicount; i++) {
        Pm_SetFilter(self->midiin[i], PM_FILT_ACTIVE | PM_FILT_CLOCK);
    }

    if (self->midicount > 0)
        self->active = 1;

	Py_INCREF(Py_None);
	return Py_None;
};
コード例 #23
0
ファイル: pmidi.c プロジェクト: hlolli/csound
static int OpenMidiInDevice_(CSOUND *csound, void **userData, const char *dev)
{
    int         cntdev, devnum, opendevs, i;
    PmEvent     buffer;
    PmError     retval;
    PmDeviceInfo *info;
//     PortMidiStream *midistream;
    pmall_data *data = NULL;
    pmall_data *next = NULL;


    if (start_portmidi(csound) != 0)
      return -1;
    /* check if there are any devices available */
    cntdev = portMidi_getDeviceCount(0);
    portMidi_listDevices(csound, 0);
    /* look up device in list */
    if (dev == NULL || dev[0] == '\0')
      devnum =
        portMidi_getPackedDeviceID((int)Pm_GetDefaultInputDeviceID(), 0);
    else if (UNLIKELY((dev[0] < '0' || dev[0] > '9') && dev[0] != 'a')) {
      portMidiErrMsg(csound,
                     Str("error: must specify a device number (>=0) or"
                         " 'a' for all, not a name"));
      return -1;
    }
    else if (dev[0] != 'a') {
      devnum = (int)atoi(dev);
      if (UNLIKELY(devnum < 0 || devnum >= cntdev)) {
        portMidiErrMsg(csound, Str("error: device number is out of range"));
        return -1;
      }
    }
    else {
    // allow to proceed if 'a' is given even if there are no MIDI devices
      devnum = -1;
    }

    if (UNLIKELY(cntdev < 1 && (dev==NULL || dev[0] != 'a'))) {
      return portMidiErrMsg(csound, Str("no input devices are available"));
    }
    opendevs = 0;
    for (i = 0; i < cntdev; i++) {
      if (devnum == i || devnum == -1) {
        if (opendevs == 0) {
          data = (pmall_data *) malloc(sizeof(pmall_data));
          next = data;
          data->next = NULL;
          opendevs++;
        }
        else {
          next->next = (pmall_data *) malloc(sizeof(pmall_data));
          next = next->next;
          next->next = NULL;
          opendevs++;
        }
        info = portMidi_getDeviceInfo(i, 0);
        if (info->interf != NULL)
          csound->Message(csound,
                          Str("PortMIDI: Activated input device %d: '%s' (%s)\n"),
                          i, info->name, info->interf);
        else
          csound->Message(csound,
                          Str("PortMIDI: Activated input device %d: '%s'\n"),
                          i, info->name);
        retval = Pm_OpenInput(&next->midistream,
                 (PmDeviceID) portMidi_getRealDeviceID(i, 0),
                         NULL, 512L, (PmTimeProcPtr) NULL, NULL);
        if (UNLIKELY(retval != pmNoError)) {
          // Prevent leaking memory from "data"
          if (data) {
            next = data->next;
            free(data);
          }
          return portMidiErrMsg(csound, Str("error opening input device %d: %s"),
                                          i, Pm_GetErrorText(retval));
        }
          /* only interested in channel messages (note on, control change, etc.) */
        /* GAB: fixed for portmidi v.23Aug06 */
        Pm_SetFilter(next->midistream, (PM_FILT_ACTIVE | PM_FILT_SYSEX));
        /* empty the buffer after setting filter */
        while (Pm_Poll(next->midistream) == TRUE) {
          Pm_Read(next->midistream, &buffer, 1);
        }
      }
    }
    *userData = (void*) data;
    /* report success */
    return 0;
}
コード例 #24
0
ファイル: midithread.c プロジェクト: RTcmix/RTcmix
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;
}
コード例 #25
0
ファイル: midiVideoMod.c プロジェクト: jhjlim/videoMidiPi
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;
}
コード例 #26
0
ファイル: test.c プロジェクト: AkiraShirase/audacity
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(); 
}
コード例 #27
0
ファイル: s_midi_pm.c プロジェクト: umnum/pd-extended
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++;
            }
        }
    }
}