|
|
|
@@ -92,7 +92,7 @@ bool getNotificationValueForKey (NSNotification* notification, NSString* key, NS |
|
|
|
- (id) init: (juce::AudioSessionHolder*) holder;
|
|
|
|
- (void) dealloc;
|
|
|
|
|
|
|
|
- (void) audioSessionDidChangeInterruptionType: (NSNotification*) notification;
|
|
|
|
- (void) audioSessionChangedInterruptionType: (NSNotification*) notification;
|
|
|
|
- (void) handleMediaServicesReset;
|
|
|
|
- (void) handleMediaServicesLost;
|
|
|
|
- (void) handleRouteChange: (NSNotification*) notification;
|
|
|
|
@@ -112,7 +112,7 @@ bool getNotificationValueForKey (NSNotification* notification, NSString* key, NS |
|
|
|
auto centre = [NSNotificationCenter defaultCenter];
|
|
|
|
|
|
|
|
[centre addObserver: self
|
|
|
|
selector: @selector (audioSessionDidChangeInterruptionType:)
|
|
|
|
selector: @selector (audioSessionChangedInterruptionType:)
|
|
|
|
name: AVAudioSessionInterruptionNotification
|
|
|
|
object: session];
|
|
|
|
|
|
|
|
@@ -145,7 +145,7 @@ bool getNotificationValueForKey (NSNotification* notification, NSString* key, NS |
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) audioSessionDidChangeInterruptionType: (NSNotification*) notification
|
|
|
|
- (void) audioSessionChangedInterruptionType: (NSNotification*) notification
|
|
|
|
{
|
|
|
|
NSUInteger value;
|
|
|
|
|
|
|
|
@@ -263,6 +263,11 @@ public: |
|
|
|
// depending on whether the headphones are plugged in or not!
|
|
|
|
setAudioSessionActive (true);
|
|
|
|
|
|
|
|
AudioUnitRemovePropertyListenerWithUserData (audioUnit,
|
|
|
|
kAudioUnitProperty_StreamFormat,
|
|
|
|
handleStreamFormatChangeCallback,
|
|
|
|
this);
|
|
|
|
|
|
|
|
const double lowestRate = trySampleRate (4000);
|
|
|
|
const double highestRate = trySampleRate (192000);
|
|
|
|
|
|
|
|
@@ -274,7 +279,12 @@ public: |
|
|
|
rate = jmax (rate, supportedRate);
|
|
|
|
}
|
|
|
|
|
|
|
|
trySampleRate (sampleRate);
|
|
|
|
trySampleRate (getCurrentSampleRate());
|
|
|
|
|
|
|
|
AudioUnitAddPropertyListener (audioUnit,
|
|
|
|
kAudioUnitProperty_StreamFormat,
|
|
|
|
handleStreamFormatChangeCallback,
|
|
|
|
this);
|
|
|
|
|
|
|
|
for (auto r : rates)
|
|
|
|
{
|
|
|
|
@@ -289,7 +299,7 @@ public: |
|
|
|
{
|
|
|
|
Array<int> r;
|
|
|
|
|
|
|
|
for (int i = 6; i < 12; ++i)
|
|
|
|
for (int i = 6; i < 13; ++i)
|
|
|
|
r.add (1 << i);
|
|
|
|
|
|
|
|
return r;
|
|
|
|
@@ -487,7 +497,10 @@ public: |
|
|
|
}
|
|
|
|
|
|
|
|
if (callback != nullptr)
|
|
|
|
{
|
|
|
|
callback->audioDeviceStopped();
|
|
|
|
callback->audioDeviceAboutToStart (this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -618,7 +631,8 @@ private: |
|
|
|
actualBufferSize = roundToInt (sampleRate * session.IOBufferDuration);
|
|
|
|
|
|
|
|
JUCE_IOS_AUDIO_LOG ("AVAudioSession: sampleRate: " << sampleRate
|
|
|
|
<< "Hz, audioInputAvailable: " << (int) audioInputIsAvailable);
|
|
|
|
<< " Hz, audioInputAvailable: " << (int) audioInputIsAvailable
|
|
|
|
<< ", buffer size: " << actualBufferSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
void updateCurrentBufferSize()
|
|
|
|
@@ -703,18 +717,17 @@ private: |
|
|
|
|
|
|
|
AudioUnitInitialize (audioUnit);
|
|
|
|
|
|
|
|
AudioUnitSetProperty (audioUnit, kAudioUnitProperty_MaximumFramesPerSlice,
|
|
|
|
kAudioUnitScope_Global, 0, &actualBufferSize, sizeof (actualBufferSize));
|
|
|
|
|
|
|
|
updateCurrentBufferSize();
|
|
|
|
|
|
|
|
if (AudioUnitGetProperty (audioUnit, kAudioUnitProperty_MaximumFramesPerSlice,
|
|
|
|
kAudioUnitScope_Global, 0, &framesPerSlice, &dataSize) == noErr
|
|
|
|
&& dataSize == sizeof (framesPerSlice) && static_cast<int> (framesPerSlice) != actualBufferSize)
|
|
|
|
{
|
|
|
|
actualBufferSize = static_cast<int> (framesPerSlice);
|
|
|
|
prepareFloatBuffers (actualBufferSize);
|
|
|
|
prepareFloatBuffers (framesPerSlice);
|
|
|
|
}
|
|
|
|
|
|
|
|
AudioUnitAddPropertyListener (audioUnit, kAudioUnitProperty_StreamFormat, handleStreamFormatChangeCallback, this);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -744,6 +757,39 @@ private: |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void handleStreamFormatChange()
|
|
|
|
{
|
|
|
|
AudioStreamBasicDescription desc;
|
|
|
|
zerostruct (desc);
|
|
|
|
UInt32 dataSize = sizeof (desc);
|
|
|
|
AudioUnitGetProperty(audioUnit,
|
|
|
|
kAudioUnitProperty_StreamFormat,
|
|
|
|
kAudioUnitScope_Output,
|
|
|
|
0,
|
|
|
|
&desc,
|
|
|
|
&dataSize);
|
|
|
|
if (desc.mSampleRate != getCurrentSampleRate())
|
|
|
|
{
|
|
|
|
updateSampleRateAndAudioInput();
|
|
|
|
const ScopedLock sl (callbackLock);
|
|
|
|
if (callback != nullptr)
|
|
|
|
{
|
|
|
|
callback->audioDeviceStopped();
|
|
|
|
callback->audioDeviceAboutToStart (this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void handleStreamFormatChangeCallback (void* device,
|
|
|
|
AudioUnit,
|
|
|
|
AudioUnitPropertyID,
|
|
|
|
AudioUnitScope scope,
|
|
|
|
AudioUnitElement element)
|
|
|
|
{
|
|
|
|
if (scope == kAudioUnitScope_Output && element == 0)
|
|
|
|
static_cast<iOSAudioIODevice*> (device)->handleStreamFormatChange();
|
|
|
|
}
|
|
|
|
|
|
|
|
JUCE_DECLARE_NON_COPYABLE (iOSAudioIODevice)
|
|
|
|
};
|
|
|
|
|
|
|
|
|