diff --git a/examples/Demo/Builds/iOS/Info-App.plist b/examples/Demo/Builds/iOS/Info-App.plist index 6aa71d6b65..bb70315700 100644 --- a/examples/Demo/Builds/iOS/Info-App.plist +++ b/examples/Demo/Builds/iOS/Info-App.plist @@ -10,6 +10,8 @@ LSRequiresIPhoneOS + NSMicrophoneUsageDescription + This app requires microphone input. UIViewControllerBasedStatusBarAppearance CFBundleExecutable diff --git a/examples/Demo/JuceDemo.jucer b/examples/Demo/JuceDemo.jucer index 4355e0f19f..3f8c023ae6 100644 --- a/examples/Demo/JuceDemo.jucer +++ b/examples/Demo/JuceDemo.jucer @@ -35,7 +35,8 @@ + customPList="<plist> <dict> <key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict> </dict> </plist>" + microphonePermissionNeeded="1"> 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 (framesPerSlice) != actualBufferSize) { - actualBufferSize = static_cast (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 (device)->handleStreamFormatChange(); + } + JUCE_DECLARE_NON_COPYABLE (iOSAudioIODevice) };