Propagate max frames property for AirPods compatibility

This commit is contained in:
Matthias Neeracher 2017-11-24 22:56:38 +01:00
parent 21291b8f3f
commit e30b1dd440
2 changed files with 74 additions and 9 deletions

View File

@ -5,7 +5,7 @@
// //
// (MN) Matthias Neeracher // (MN) Matthias Neeracher
// //
// Copyright © 2006-2011 Matthias Neeracher // Copyright © 2006-2011 Matthias Neeracher
// //
#import "VLSheetView.h" #import "VLSheetView.h"

View File

@ -5,7 +5,7 @@
// //
// (MN) Matthias Neeracher // (MN) Matthias Neeracher
// //
// Copyright © 2005-2011 Matthias Neeracher // Copyright © 2005-2017 Matthias Neeracher
// //
#include "VLSoundOut.h" #include "VLSoundOut.h"
@ -47,15 +47,21 @@ public:
virtual ~VLAUSoundOut(); virtual ~VLAUSoundOut();
void PollMusic(); void PollMusic();
void PropagateProperty(AudioUnitPropertyID inID,
AudioUnitScope inScope,
AudioUnitElement inElement);
protected: protected:
VLAUSoundOut(bool fileOutput); VLAUSoundOut(bool fileOutput);
void InitSoundOutput(bool fileOutput); void InitSoundOutput(bool fileOutput);
void TeardownSoundOutput();
virtual void SetupOutput(AUNode outputNode); virtual void SetupOutput(AUNode outputNode);
void SkipTimeInterval(); void SkipTimeInterval();
AUGraph fGraph; AUGraph fGraph;
MusicPlayer fPlayer; MusicPlayer fPlayer;
AudioUnit fOutputUnit;
AudioUnit fSynthUnit;
private: private:
MusicSequence fMusic; MusicSequence fMusic;
MusicTimeStamp fMusicEnd; MusicTimeStamp fMusicEnd;
@ -182,8 +188,18 @@ VLAUSoundOut::~VLAUSoundOut()
{ {
Stop(false); Stop(false);
dispatch_release(fMusicPoll); dispatch_release(fMusicPoll);
DisposeMusicPlayer(fPlayer); TeardownSoundOutput();
DisposeAUGraph(fGraph); }
extern "C" void
VLAUSoundOutPropagateProperty(void * inRefCon,
AudioUnit, AudioUnitPropertyID inID,
AudioUnitScope inScope,
AudioUnitElement inElement)
{
VLAUSoundOut * liveAudioObject = reinterpret_cast<VLAUSoundOut *>(inRefCon);
liveAudioObject->PropagateProperty(inID, inScope, inElement);
} }
void VLAUSoundOut::InitSoundOutput(bool fileOutput) void VLAUSoundOut::InitSoundOutput(bool fileOutput)
@ -219,20 +235,27 @@ void VLAUSoundOut::InitSoundOutput(bool fileOutput)
AUGraphConnectNodeInput(fGraph, synthNode, 0, limiterNode, 0); AUGraphConnectNodeInput(fGraph, synthNode, 0, limiterNode, 0);
AUGraphConnectNodeInput(fGraph, limiterNode, 0, outNode, 0); AUGraphConnectNodeInput(fGraph, limiterNode, 0, outNode, 0);
R(AUGraphNodeInfo(fGraph, outNode, NULL, &fOutputUnit));
R(AUGraphNodeInfo(fGraph, synthNode, NULL, &fSynthUnit));
if (fileOutput) { if (fileOutput) {
UInt32 value = 1; UInt32 value = 1;
AudioUnit synth; R(AudioUnitSetProperty(fSynthUnit,
R(AUGraphNodeInfo(fGraph, synthNode, NULL, &synth));
R(AudioUnitSetProperty(synth,
kAudioUnitProperty_OfflineRender, kAudioUnitProperty_OfflineRender,
kAudioUnitScope_Global, 0, kAudioUnitScope_Global, 0,
&value, sizeof(value))); &value, sizeof(value)));
value = 512; value = 512;
R(AudioUnitSetProperty(synth, R(AudioUnitSetProperty(fSynthUnit,
kAudioUnitProperty_OfflineRender, kAudioUnitProperty_OfflineRender,
kAudioUnitScope_Global, 0, kAudioUnitScope_Global, 0,
&value, sizeof(value))); &value, sizeof(value)));
} else {
AudioUnitAddPropertyListener(fOutputUnit,
kAudioUnitProperty_MaximumFramesPerSlice,
VLAUSoundOutPropagateProperty,
this);
} }
SetupOutput(outNode); SetupOutput(outNode);
R(AUGraphInitialize(fGraph)); R(AUGraphInitialize(fGraph));
@ -240,6 +263,48 @@ void VLAUSoundOut::InitSoundOutput(bool fileOutput)
NewMusicPlayer(&fPlayer); NewMusicPlayer(&fPlayer);
} }
void VLAUSoundOut::PropagateProperty(AudioUnitPropertyID inID,
AudioUnitScope inScope,
AudioUnitElement inElement)
{
Boolean running = false;
if (MusicPlayerIsPlaying(fPlayer, &running))
running = false;
else if (running)
MusicPlayerStop(fPlayer);
std::vector<char> data;
UInt32 sz = 0;
Boolean wr;
if (AudioUnitGetPropertyInfo(fOutputUnit, inID, inScope, inElement, &sz, &wr))
goto reinitialize;
data.resize(sz);
if (!AudioUnitGetProperty(fOutputUnit, inID, inScope, inElement, &data[0], &sz)) {
if (OSStatus status = AudioUnitSetProperty(fSynthUnit, inID, inScope, inElement,
&data[0], sz)) {
if (status == kAudioUnitErr_Initialized) {
AudioUnitUninitialize(fSynthUnit);
status = AudioUnitSetProperty(fSynthUnit, inID, inScope, inElement,
&data[0], sz);
AudioUnitInitialize(fSynthUnit);
}
}
}
reinitialize:
if (running)
MusicPlayerStart(fPlayer);
}
void VLAUSoundOut::TeardownSoundOutput()
{
AudioUnitRemovePropertyListenerWithUserData(fOutputUnit,
kAudioUnitProperty_MaximumFramesPerSlice,
VLAUSoundOutPropagateProperty,
this);
DisposeMusicPlayer(fPlayer);
DisposeAUGraph(fGraph);
}
void VLAUSoundOut::SetupOutput(AUNode) void VLAUSoundOut::SetupOutput(AUNode)
{ {
} }