Amend MIDI Audio Unit player a bit

This should fix some potential initialization errors it may have had
before, but this doesn't fix the broken Sound Canvas VA plugin. Roland
says it's supposed to be broken on macOS 12+ and/or Apple silicon
anyway, so I guess there's no dodging that.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
main
Christopher Snowhill 2022-10-21 16:37:01 -07:00
parent 5882affd3f
commit bcd5ab0dd2
2 changed files with 46 additions and 26 deletions

View File

@ -59,6 +59,8 @@ class AUPlayer : public MIDIPlayer {
float *audioBuffer; float *audioBuffer;
OSType componentSubType, componentManufacturer; OSType componentSubType, componentManufacturer;
BOOL needsInput;
}; };
#endif #endif

View File

@ -47,24 +47,18 @@ void AUPlayer::send_sysex(const uint8_t *data, size_t size, size_t port) {
} }
void AUPlayer::send_event_time(uint32_t b, unsigned int time) { void AUPlayer::send_event_time(uint32_t b, unsigned int time) {
#ifdef AUPLAYERVIEW
int _port = -1;
#endif
unsigned char event[3]; unsigned char event[3];
event[0] = (unsigned char)b; event[0] = (unsigned char)b;
event[1] = (unsigned char)(b >> 8); event[1] = (unsigned char)(b >> 8);
event[2] = (unsigned char)(b >> 16); event[2] = (unsigned char)(b >> 16);
unsigned port = (b >> 24) & 0x7F; unsigned port = (b >> 24) & 0x7F;
if(port > 2) port = 2; if(port > 2) port = 2;
#ifdef AUPLAYERVIEW
_port = (int)port;
#endif
MusicDeviceMIDIEvent(samplerUnit[port], event[0], event[1], event[2], time); MusicDeviceMIDIEvent(samplerUnit[port], event[0], event[1], event[2], time);
#ifdef AUPLAYERVIEW #ifdef AUPLAYERVIEW
if(_port >= 0 && !samplerUIinitialized[_port]) { if(port >= 0 && !samplerUIinitialized[port]) {
samplerUIinitialized[_port] = true; samplerUIinitialized[port] = true;
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
samplerUI[_port] = new AUPluginUI(samplerUnit[_port]); samplerUI[port] = new AUPluginUI(samplerUnit[port]);
}); });
} }
#endif #endif
@ -72,19 +66,16 @@ void AUPlayer::send_event_time(uint32_t b, unsigned int time) {
void AUPlayer::send_sysex_time(const uint8_t *data, size_t size, size_t port, unsigned int time) { void AUPlayer::send_sysex_time(const uint8_t *data, size_t size, size_t port, unsigned int time) {
if(port > 2) port = 0; if(port > 2) port = 0;
#ifdef AUPLAYERVIEW
_port = (int)port;
#endif
MusicDeviceSysEx(samplerUnit[port], data, (UInt32)size); MusicDeviceSysEx(samplerUnit[port], data, (UInt32)size);
if(port == 0) { if(port == 0) {
MusicDeviceSysEx(samplerUnit[1], data, (UInt32)size); MusicDeviceSysEx(samplerUnit[1], data, (UInt32)size);
MusicDeviceSysEx(samplerUnit[2], data, (UInt32)size); MusicDeviceSysEx(samplerUnit[2], data, (UInt32)size);
} }
#ifdef AUPLAYERVIEW #ifdef AUPLAYERVIEW
if(_port >= 0 && !samplerUIinitialized[_port]) { if(port >= 0 && !samplerUIinitialized[port]) {
samplerUIinitialized[_port] = true; samplerUIinitialized[port] = true;
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
samplerUI[_port] = new AUPluginUI(samplerUnit[_port]); samplerUI[port] = new AUPluginUI(samplerUnit[port]);
}); });
} }
#endif #endif
@ -256,19 +247,42 @@ bool AUPlayer::startup() {
if(error != noErr) if(error != noErr)
return false; return false;
needsInput = NO;
{ {
AudioStreamBasicDescription stream = { 0 }; AudioStreamBasicDescription stream = { 0 };
stream.mSampleRate = uSampleRate; stream.mSampleRate = uSampleRate;
stream.mFormatID = kAudioFormatLinearPCM; stream.mFormatID = kAudioFormatLinearPCM;
stream.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved | kAudioFormatFlagsNativeEndian; stream.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved;
stream.mFramesPerPacket = 1;
stream.mBytesPerPacket = 4; stream.mBytesPerPacket = 4;
stream.mFramesPerPacket = 1;
stream.mBytesPerFrame = 4; stream.mBytesPerFrame = 4;
stream.mBitsPerChannel = 32;
stream.mChannelsPerFrame = 2; stream.mChannelsPerFrame = 2;
stream.mBitsPerChannel = 32;
AudioUnitSetProperty(samplerUnit[i], kAudioUnitProperty_StreamFormat, AUChannelInfo channelInfo = { 0 };
kAudioUnitScope_Input, 0, &stream, sizeof(stream)); Boolean *isWritable = 0;
size = 0;
error = AudioUnitGetPropertyInfo(samplerUnit[i], kAudioUnitProperty_SupportedNumChannels, kAudioUnitScope_Global, 0, &size, isWritable);
if(error == noErr) {
size = sizeof(channelInfo);
error = AudioUnitGetProperty(samplerUnit[i], kAudioUnitProperty_SupportedNumChannels, kAudioUnitScope_Global, 0, &channelInfo, &size);
if(error == noErr && channelInfo.inChannels == -1 || channelInfo.inChannels <= -2 || channelInfo.inChannels >= 2) {
needsInput = YES;
}
} else {
UInt32 channelCount = 0;
size = sizeof(channelCount);
error = AudioUnitGetProperty(samplerUnit[i], kAudioUnitProperty_ElementCount, kAudioUnitScope_Input, 0, &channelCount, &size);
if(error == noErr && channelCount >= 2) {
needsInput = YES;
}
}
if(needsInput) {
AudioUnitSetProperty(samplerUnit[i], kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input, 0, &stream, sizeof(stream));
}
AudioUnitSetProperty(samplerUnit[i], kAudioUnitProperty_StreamFormat, AudioUnitSetProperty(samplerUnit[i], kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output, 0, &stream, sizeof(stream)); kAudioUnitScope_Output, 0, &stream, sizeof(stream));
@ -282,11 +296,13 @@ bool AUPlayer::startup() {
AudioUnitSetProperty(samplerUnit[i], kAudioUnitProperty_RenderQuality, AudioUnitSetProperty(samplerUnit[i], kAudioUnitProperty_RenderQuality,
kAudioUnitScope_Global, 0, &value, size); kAudioUnitScope_Global, 0, &value, size);
AURenderCallbackStruct callbackStruct; if(needsInput) {
callbackStruct.inputProc = renderCallback; AURenderCallbackStruct callbackStruct;
callbackStruct.inputProcRefCon = 0; callbackStruct.inputProc = renderCallback;
AudioUnitSetProperty(samplerUnit[i], kAudioUnitProperty_SetRenderCallback, callbackStruct.inputProcRefCon = 0;
kAudioUnitScope_Input, 0, &callbackStruct, sizeof(callbackStruct)); AudioUnitSetProperty(samplerUnit[i], kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Input, 0, &callbackStruct, sizeof(callbackStruct));
}
/*Float64 sampleRateIn = 0, sampleRateOut = 0; /*Float64 sampleRateIn = 0, sampleRateOut = 0;
UInt32 sampleRateSize = sizeof (sampleRateIn); UInt32 sampleRateSize = sizeof (sampleRateIn);
@ -302,7 +318,9 @@ bool AUPlayer::startup() {
if (sampleRateOut != sr) if (sampleRateOut != sr)
AudioUnitSetProperty (samplerUnit[i], kAudioUnitProperty_SampleRate, kAudioUnitScope_Output, i, &sr, sizeof (sr));*/ AudioUnitSetProperty (samplerUnit[i], kAudioUnitProperty_SampleRate, kAudioUnitScope_Output, i, &sr, sizeof (sr));*/
AudioUnitReset(samplerUnit[i], kAudioUnitScope_Input, 0); if(needsInput) {
AudioUnitReset(samplerUnit[i], kAudioUnitScope_Input, 0);
}
AudioUnitReset(samplerUnit[i], kAudioUnitScope_Output, 0); AudioUnitReset(samplerUnit[i], kAudioUnitScope_Output, 0);
AudioUnitReset(samplerUnit[i], kAudioUnitScope_Global, 0); AudioUnitReset(samplerUnit[i], kAudioUnitScope_Global, 0);