Cheers, I’ll take a look at that asap!
And here’s a patch for MIDI Input:
https://github.com/yairchu/JUCE/commit/e26b5fad7e946be04e58f214340bdecef1ce2319
As for MIDI output, I don’t have anything to test it with, nor any need for it atm, so I suppose someone else will have to add that
Cheers! Yair
good job, I can’t wait to test it.
Now, only the problem with the hanging of Pro Tools on exit remains to be solved… has anyone reproduced the issue?
Wow, you’re really pumping out the changes! Thanks again, I’ve added that midi stuff. Testing welcome!
it seems odd, but it appears that in this code in the process () function:
#if JucePlugin_WantsMidiInput
{
AAX_CMidiStream* const midiStream = midiNodeIn->GetNodeBuffer();
const uint32_t numMidiEvents = midiStream->mBufferSize;
for (uint32_t i = 0; i < numMidiEvents; ++i)
{
const AAX_CMidiPacket& m = midiStream->mBuffer[i]; // THIS LINE
jassert ((int) m.mTimestamp < bufferSize);
midiBuffer.addEvent (m.mData, (int) m.mLength,
jlimit (0, (int) bufferSize - 1, (int) m.mTimestamp));
}
}
#endif
things get quite funny at the line marked with the “THIS LINE” comment: when receiving multiple MIDI messages in a buffer (for example using an expression pedal) I’ve noticed that the first one is ok, while the subsequent ones look like garbage, with ridiculous values for timestamp and length.
I looked at the memory pointed by midiStream->mBuffer and it appears clear that the AAX_CMidiPacket elements are placed at 16 byte intervals, while sizeof(AAX_CMidiPacket) reports that the structure is only 14 bytes long.
I hacked the above code forcing it to use 16 bytes intervals as follows:
#if JucePlugin_WantsMidiInput
{
AAX_CMidiStream* const midiStream = midiNodeIn->GetNodeBuffer();
const uint32_t numMidiEvents = midiStream->mBufferSize;
for (uint32_t i = 0; i < numMidiEvents; ++i)
{
// const AAX_CMidiPacket& m = midiStream->mBuffer[i]; // this is the original line
const AAX_CMidiPacket& m = *((AAX_CMidiPacket*)(((unsigned char *)midiStream->mBuffer) + (i * 16)));
jassert ((int) m.mTimestamp < bufferSize);
midiBuffer.addEvent (m.mData, (int) m.mLength,
jlimit (0, (int) bufferSize - 1, (int) m.mTimestamp));
}
}
#endif
and it works like a charm.
Here are my investigations on the subject:
AAX_CMidiPacket is declared in AAX.h as follows
struct AAX_CMidiPacket
{
uint32_t mTimestamp; //!< This is the playback time at which the MIDI event should occur, relative to the beginning of the current audio buffer.
uint32_t mLength; //!< The length of MIDI message, in terms of bytes.
unsigned char mData[4]; //!< The MIDI message itself. Each array element is one byte of the message, with the 0th element being the first byte.
AAX_CBoolean mIsImmediate; //!< Indicates that the message is to be sent as soon as possible.
};
the first 3 members clearly take 4 bytes each, the AAX_CBoolean type is defined as follows
and it adds one more byte to the size of the structure, which sums up to 13, which is neither the reported sizeof of 14 nor the expected 16. This makes me think about an alignment problem: for some reason the SDK is being built with 2 byte alignment instead of 4 or pheraps 8. Can anyone confirm about this?
I’m using Xcode 4.5.2, building with Apple LLVM 4.1 a 32 bit plug-in that uses the 1.5.0 AAX SDK, to be tested on Pro Tools 10.3.3
Hello,
Just want to thank you all for the efforts to get AAX working.
Salvator
Ouch! That’s a good question for the Avid guys… I’m certainly very surprised that it’d align to a 2-byte boundary. Perhaps as a semi-hacky workaround we could do something like this:
const AAX_CMidiPacket& m = *addBytesToPointer (midiStream->mBuffer, i * ((sizeof (AAX_CMidiPacket) + 3) & ~3));
I’ve just checked on the Avid developers forum and it seems to be a bug reported the last days of December. Until it is fixed in the SDK, I think we should rely on this piece of information given:
“It looks like there already was an explicit struct packing around this structure, but I think it was rather confusing. I’m planning on switching it to explicit 8 byte alignment because it is a structure required by the algorithm, and all algorithm structs must be 8 byte aligned. I still have an open question about potential issues that may cause in DAE though, so this issue is still open on my end.”
So, until this is sorted out on the AAX SDK side, I think the “hack” should round the size of the AAX_CMidiPacket structure to the next multiple of 8 and hope for the better
Interesting. I’ve checked-in the 8-byte alignment workaround, hopefully it should sort things out for now.
ok, got to playing with MIDI output too, and here’s a patch: https://github.com/yairchu/JUCE/commit/becb4e39cf424660ebcc6ae08d8e6f2b7ad2077e
only tested with monophonic outputs
btw, how to route MIDI output in PT (10.2):
create MIDI track, set track’s input to the plugin’s output node (in the mixer window), enable “record” on the midi track, and now you can send it to any MIDI input node
cheers, Yair
Awesome stuff, although surely if it gets a sysex, it’ll trash the stack?
I also noticed that the mIsImmediate value wasn’t getting set, but am not 100% sure what it should be… false, maybe?
I’ve checked-in some code that I think sidesteps these problems, but just ignores sysexes - not sure how those are supposed to be handled…
[quote=“jules”]Awesome stuff, although surely if it gets a sysex, it’ll trash the stack?
I also noticed that the mIsImmediate value wasn’t getting set, but am not 100% sure what it should be… false, maybe?
I’ve checked-in some code that I think sidesteps these problems, but just ignores sysexes - not sure how those are supposed to be handled…[/quote]
Awesome
But for some reason there’s a typo in your commit (midiNoteOut instead of midiNodeOut)… perhaps you built it with AAX turned off?
Yes, almost certainly! Thanks, I’ve fixed the typo now!