Audio Unit support for MIDI output and getCurrentPosition


#1

Hello,

I’m running through a couple of issues:

  1. I’m working in a plugin that outputs MIDI correctly in VST mode but fails to do so in the Audio Unit version.
    I suspect that this feature (MIDI output) is not implemented in the JUCE plugin wrapper for Audio Unit. Can anybody confirm?
    Apparently it would be possible. http://lists.apple.com/archives/coreaudio-api/2007/Mar/msg00053.html

  2. I’m also having problems with getCurrentPosition. If I run:

AudioPlayHead::CurrentPositionInfo pos; getPlayHead()->getCurrentPosition(pos);
Only the bpm and signature fields are correct. Everything else doesn’t seem to be written (e.g. isPlaying or ppqPosition, in particular, are critical to me). Is there a way to get this information in Audio Units?

I compiled with juce 2.0 and the latest snapshot from git, Mac OSX lion and XCode 4.3.3 (after following Jules’ instructions in http://www.rawmaterialsoftware.com/viewtopic.php?f=8&t=8682)

Thanks in advance


#2

[quote=“MarC”]Hello,

I’m running through a couple of issues:

  1. I’m working in a plugin that outputs MIDI correctly in VST mode but fails to do so in the Audio Unit version.
    I suspect that this feature (MIDI output) is not implemented in the JUCE plugin wrapper for Audio Unit. Can anybody confirm?
    Apparently it would be possible. http://lists.apple.com/archives/coreaudio-api/2007/Mar/msg00053.html
    [/quote]

AFAIK this feature is not supported by any Audio Unit host. We had to implement this for one of our plugins and the only solution we found is to use the IAC driver. This is far more difficult for the user to set it up but this works.
Concerning RTAS, after tweaking a little the wrapper, this works great in Pro Tools, I can give some code if needed.

I have to check this but I think both isPlaying and ppqPosition work well for me. What host are you using?


#4

You have to create a MIDI output node like this:

#if JucePlugin_ProducesMidiOutput
    CEffectType* const type = dynamic_cast <CEffectType*> (this->GetProcessType());
    if (type != 0)
    {
        char nodeName [64];
        type->GetProcessTypeName (63, nodeName);
        p2cstrcpy (nodeName, reinterpret_cast <unsigned char*> (nodeName));
        
        mMidiOutNode = new CEffectMIDIRTASBufferedOutputNode( &mMIDIWorld, nodeName, 8192);
        mMidiOutNode->Initialize( 0x0001 ); // Channel 1 and channel 2
        
    }
#endif

Put this code just after the creation CEffectMIDIOtherBufferedNode of the inside the MIDILogIn() test.

Then in the RenderAudio callback you have to push the MIDI packets into the node:

if (! midiEvents.isEmpty())
{
#if JucePlugin_ProducesMidiOutput
    const JUCE_NAMESPACE::uint8* midiEventData;
    int midiEventSize, midiEventPosition;
    MidiBuffer::Iterator it (midiEvents);

    while (it.getNextEvent (midiEventData, midiEventSize, midiEventPosition))
    {
        DirectMidiPacket packet;
        packet.mTimestamp = midiEventPosition;
        packet.mLength = midiEventSize;
        for(int i = 0; i < jmin(4, midiEventSize); ++i){
            packet.mData[i] = midiEventData[i];
        }
        mMidiOutNode->PushMIDIPacket(&packet);
    }
#else
    // if your plugin creates midi messages, you'll need to set
    // the JucePlugin_ProducesMidiOutput macro to 1 in your
    // JucePluginCharacteristics.h file
    jassert (midiEvents.getNumEvents() <= numMidiEventsComingIn);
#endif
    midiEvents.clear();
}

That’s all :slight_smile:
Hope this helps.

Kevin


#5

Does someone know if there is a “simple” way to make AudioUntis output MIDI data? What exactly is required to make it work?


#6

There is an API for that but AFAIK there is no DAW that is supporting it :).
The workaround we have used in Spark is sending the data through the IAC driver.

Kevin


#7

[quote=“ke20”]There is an API for that but AFAIK there is no DAW that is supporting it :).
The workaround we have used in Spark is sending the data through the IAC driver.

Kevin[/quote]
Thanks for the fast reply. I hoped so much that there is an easy solution for this without leaving the JUCE framework :slight_smile: