# Other midi needs

**URL:** <https://forum.juce.com/t/other-midi-needs/1755>\
**Category:** Linux\
**Created:** [June 4, 2007, 7:35am UTC](https://forum.juce.com/t/other-midi-needs/1755 "2007-06-04T07:35:23Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![kunitoki](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/kunitoki/32/15_2.png) [@kunitoki](https://forum.juce.com/u/kunitoki)\
**Post date:** [June 4, 2007, 7:35am UTC](https://forum.juce.com/t/other-midi-needs/1755/1 "2007-06-04T07:35:23Z")

</div>

i just found that there will be a couple of static functions needed in the midi code. we have now openDevice, which will open a midi device that already exists in the system. but sometimes (well in my case most of the time!) i just do not attach to any existent device, but instead i publish a new device in alsa\_seq (and give it the name of my application).  
so i’ve added this pair of functions:

```auto

//---------------------------------------------------------------------------------

    /** Tries to create a new midi input device.

        This will return a MidiInput object if it manages to open it. You can then
        call start() and stop() on this device, and delete it when no longer needed.

        If the device can't be opened, this will return a null pointer.

        @param deviceName the name you will like to give to the device
        @param callback the object that will receive the midi messages from this device.

        @see MidiInputCallback, getDevices
    */
    static MidiInput* createNewDevice (const String& deviceName,
                                       MidiInputCallback* callback);

//---------------------------------------------------------------------------------

    /** Tries to create a new midi output device.

        This will return a MidiOutput object if it manages to open it. You can then
        send messages to this device, and delete it when no longer needed.

        If the device can't be opened, this will return a null pointer.

        @param deviceName the name of the device
        @see getDevices
    */
    static MidiOutput* createNewDevice (const String& deviceName);

```

with the linux implementation:

```auto

static snd_seq_t* createDevice (const bool forInput,
                                const String& deviceNameToOpen)
{
    snd_seq_t* returnedHandle = 0;
    snd_seq_t* seqHandle;

    if (snd_seq_open (&seqHandle, "default", forInput ? SND_SEQ_OPEN_INPUT
                                                      : SND_SEQ_OPEN_OUTPUT, 0) == 0)
    {
        snd_seq_set_client_name (seqHandle,
                                    forInput ? (const char*) (deviceNameToOpen + " Input")
                                             : (const char*) (deviceNameToOpen + " Output"));
        /* const int portId = */
        snd_seq_create_simple_port (seqHandle,
                                    forInput ? "in"
                                             : "out",
                                    forInput ? (SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE)
                                             : (SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ),
                                    forInput ? SND_SEQ_PORT_TYPE_APPLICATION
                                             : SND_SEQ_PORT_TYPE_MIDI_GENERIC);

        returnedHandle = seqHandle;

        if (returnedHandle == 0)
            snd_seq_close (seqHandle);
    }

    return returnedHandle;
}

// ...

MidiOutput* MidiOutput::createNewDevice (const String& deviceName)
{
    MidiOutput* newDevice = 0;

    snd_seq_t* const handle = createDevice (false, deviceName);

    if (handle != 0)
    {
        newDevice = new MidiOutput();
        newDevice->internal = new MidiOutputDevice (newDevice, handle);
    }

    return newDevice;
}

// ...

MidiInput* MidiInput::createNewDevice (const String& deviceName, MidiInputCallback* callback)
{
    MidiInput* newDevice = 0;

    snd_seq_t* const handle = createDevice (true, deviceName);

    if (handle != 0)
    {
        newDevice = new MidiInput (deviceName);
        newDevice->internal = new MidiInputThread (newDevice, handle, callback);
    }

    return newDevice;
}

```

this way i can publish a new midi input/output port to alsa, with the name of my application (so if i open 2 instances i can have different names)…  
cause the problem is when having multiple juce application using midi… they all have the same “Juce Midi Input” names (and they are difficult to distinguish!)

hope will be accepted in the next version !

cheers

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [June 4, 2007, 10:13am UTC](https://forum.juce.com/t/other-midi-needs/1755/2 "2007-06-04T10:13:03Z")

</div>

Seems pretty sensible to me! Thanks, kraken!

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [June 4, 2007, 10:18am UTC](https://forum.juce.com/t/other-midi-needs/1755/3 "2007-06-04T10:18:52Z")

</div>

…except for the error checking… What’s supposed to be going on here?

[code]  
returnedHandle = seqHandle;

```
    if (returnedHandle == 0)
        snd_seq_close (seqHandle);[/code]

```

Surely it should be checking that snd\_seq\_create\_simple\_port has worked correctly?

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [June 4, 2007, 10:24am UTC](https://forum.juce.com/t/other-midi-needs/1755/4 "2007-06-04T10:24:01Z")

</div>

Maybe this would be better:

[code]  
snd\_seq\_t\* seqHandle = 0;

```
if (snd_seq_open (&seqHandle, "default", forInput ? SND_SEQ_OPEN_INPUT
                                                  : SND_SEQ_OPEN_OUTPUT, 0) == 0)
{
    snd_seq_set_client_name (seqHandle,
                             (const char*) (forInput ? (deviceNameToOpen + " Input")
                                                     : (deviceNameToOpen + " Output")));

    const int portId 
        = snd_seq_create_simple_port (seqHandle,
                                      forInput ? "in"
                                               : "out",
                                      forInput ? (SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE)
                                               : (SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ),
                                      forInput ? SND_SEQ_PORT_TYPE_APPLICATION
                                               : SND_SEQ_PORT_TYPE_MIDI_GENERIC);

    if (portId < 0)
    {
        snd_seq_close (seqHandle);
        seqHandle = 0;
    }
}

return seqHandle;[/code]

```

---

<div class="post-metadata">

**Author:** ![kunitoki](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/kunitoki/32/15_2.png) [@kunitoki](https://forum.juce.com/u/kunitoki)\
**Post date:** [June 4, 2007, 10:36am UTC](https://forum.juce.com/t/other-midi-needs/1755/5 "2007-06-04T10:36:44Z")

</div>

eek, yeah jules you right :oops:

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [May 12, 2017, 7:50pm UTC](https://forum.juce.com/t/other-midi-needs/1755/6 "2017-05-12T19:50:38Z")

</div>


