From 72acfe4d82606f2ca6a9317813cf6d9d6cf3412e Mon Sep 17 00:00:00 2001 From: Daymon Date: Tue, 7 Oct 2025 13:50:07 -0500 Subject: [PATCH 01/10] Add live audio screen --- .../FirebaseAIExample/ContentView.swift | 5 + .../FirebaseAIExampleApp.swift | 4 + .../Assets.xcassets/Contents.json | 6 + .../gemini-logo.imageset/Contents.json | 35 ++ .../gemini-logo.imageset/gemini-logo.png | Bin 0 -> 240400 bytes .../Audio/AudioBufferHelpers.swift | 89 ++++++ .../Audio/AudioController.swift | 234 ++++++++++++++ .../LiveAudioExample/Audio/AudioPlayer.swift | 85 +++++ .../LiveAudioExample/Audio/Microphone.swift | 61 ++++ .../Models/TranscriptLine.swift | 28 ++ .../Screens/LiveAudioScreen.swift | 52 +++ .../ViewModels/LiveViewModel.swift | 299 ++++++++++++++++++ .../ViewModels/TranscriptViewModel.swift | 147 +++++++++ .../Views/ConnectButton.swift | 103 ++++++ .../Views/LiveErrorDetailsView.swift | 85 +++++ .../Views/LiveErrorView.swift | 44 +++ .../LiveAudioExample/Views/ModelPhoto.swift | 65 ++++ .../Views/TranscriptView.swift | 39 +++ 18 files changed, 1381 insertions(+) create mode 100644 firebaseai/LiveAudioExample/Assets.xcassets/Contents.json create mode 100644 firebaseai/LiveAudioExample/Assets.xcassets/gemini-logo.imageset/Contents.json create mode 100644 firebaseai/LiveAudioExample/Assets.xcassets/gemini-logo.imageset/gemini-logo.png create mode 100644 firebaseai/LiveAudioExample/Audio/AudioBufferHelpers.swift create mode 100644 firebaseai/LiveAudioExample/Audio/AudioController.swift create mode 100644 firebaseai/LiveAudioExample/Audio/AudioPlayer.swift create mode 100644 firebaseai/LiveAudioExample/Audio/Microphone.swift create mode 100644 firebaseai/LiveAudioExample/Models/TranscriptLine.swift create mode 100644 firebaseai/LiveAudioExample/Screens/LiveAudioScreen.swift create mode 100644 firebaseai/LiveAudioExample/ViewModels/LiveViewModel.swift create mode 100644 firebaseai/LiveAudioExample/ViewModels/TranscriptViewModel.swift create mode 100644 firebaseai/LiveAudioExample/Views/ConnectButton.swift create mode 100644 firebaseai/LiveAudioExample/Views/LiveErrorDetailsView.swift create mode 100644 firebaseai/LiveAudioExample/Views/LiveErrorView.swift create mode 100644 firebaseai/LiveAudioExample/Views/ModelPhoto.swift create mode 100644 firebaseai/LiveAudioExample/Views/TranscriptView.swift diff --git a/firebaseai/FirebaseAIExample/ContentView.swift b/firebaseai/FirebaseAIExample/ContentView.swift index 1714a0653..9a9b0aa48 100644 --- a/firebaseai/FirebaseAIExample/ContentView.swift +++ b/firebaseai/FirebaseAIExample/ContentView.swift @@ -50,6 +50,11 @@ struct ContentView: View { } Section("Examples") { + NavigationLink { + LiveAudioScreen(firebaseService: firebaseService, backend: selectedBackend) + } label: { + Label("Live Audio", systemImage: "microphone") + } NavigationLink { GenerateContentScreen(firebaseService: firebaseService) } label: { diff --git a/firebaseai/FirebaseAIExample/FirebaseAIExampleApp.swift b/firebaseai/FirebaseAIExample/FirebaseAIExampleApp.swift index 1d59440ea..1d4be15bd 100644 --- a/firebaseai/FirebaseAIExample/FirebaseAIExampleApp.swift +++ b/firebaseai/FirebaseAIExample/FirebaseAIExampleApp.swift @@ -13,6 +13,7 @@ // limitations under the License. import FirebaseCore +import FirebaseAppCheck import SwiftUI class AppDelegate: NSObject, UIApplicationDelegate { @@ -22,6 +23,9 @@ class AppDelegate: NSObject, UIApplicationDelegate { // Recommendation: Protect your Vertex AI API resources from abuse by preventing unauthorized // clients using App Check; see https://firebase.google.com/docs/app-check#get_started. + // let providerFactor = AppCheckDebugProviderFactory() + // AppCheck.setAppCheckProviderFactory(providerFactor) + FirebaseApp.configure() if let firebaseApp = FirebaseApp.app(), firebaseApp.options.projectID == "mockproject-1234" { diff --git a/firebaseai/LiveAudioExample/Assets.xcassets/Contents.json b/firebaseai/LiveAudioExample/Assets.xcassets/Contents.json new file mode 100644 index 000000000..73c00596a --- /dev/null +++ b/firebaseai/LiveAudioExample/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/firebaseai/LiveAudioExample/Assets.xcassets/gemini-logo.imageset/Contents.json b/firebaseai/LiveAudioExample/Assets.xcassets/gemini-logo.imageset/Contents.json new file mode 100644 index 000000000..8d93c4b5c --- /dev/null +++ b/firebaseai/LiveAudioExample/Assets.xcassets/gemini-logo.imageset/Contents.json @@ -0,0 +1,35 @@ +{ + "images" : [ + { + "filename" : "gemini-logo.png", + "idiom" : "universal", + "resizing" : { + "cap-insets" : { + "bottom" : 512, + "left" : 511, + "right" : 512, + "top" : 511 + }, + "center" : { + "height" : 1, + "mode" : "tile", + "width" : 1 + }, + "mode" : "9-part" + }, + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/firebaseai/LiveAudioExample/Assets.xcassets/gemini-logo.imageset/gemini-logo.png b/firebaseai/LiveAudioExample/Assets.xcassets/gemini-logo.imageset/gemini-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..11ef95cdd7d86a10a63dedbb5e0262ed19cdbcab GIT binary patch literal 240400 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 WW{s8uaFU+>DJBg9eja3(6#M#QD-onRd1FWK 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 z%0A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 EKli+qdjJ3c literal 0 HcmV?d00001 diff --git a/firebaseai/LiveAudioExample/Audio/AudioBufferHelpers.swift b/firebaseai/LiveAudioExample/Audio/AudioBufferHelpers.swift new file mode 100644 index 000000000..b6d1f51dc --- /dev/null +++ b/firebaseai/LiveAudioExample/Audio/AudioBufferHelpers.swift @@ -0,0 +1,89 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import AVFoundation + +extension AVAudioPCMBuffer { + /// Creates a new `AVAudioPCMBuffer` from a `Data` struct. + /// + /// Only works with interleaved data. + static func fromInterleavedData(data: Data, format: AVAudioFormat) -> AVAudioPCMBuffer? { + guard format.isInterleaved else { + fatalError("Only interleaved data is supported") + } + + let frameCapacity = AVAudioFrameCount(data.count / Int(format.streamDescription.pointee.mBytesPerFrame)) + guard let buffer = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: frameCapacity) else { + return nil + } + + buffer.frameLength = frameCapacity + data.withUnsafeBytes { bytes in + guard let baseAddress = bytes.baseAddress else { return } + let dst = buffer.mutableAudioBufferList.pointee.mBuffers + dst.mData?.copyMemory(from: baseAddress, byteCount: Int(dst.mDataByteSize)) + } + + return buffer + } + + /// Gets the underlying `Data` in this buffer. + /// + /// Will throw an error if this buffer doesn't hold int16 data. + func int16Data() -> Data? { + guard let bufferPtr = audioBufferList.pointee.mBuffers.mData else { + fatalError("Missing audio buffer list") + } + + let audioBufferLenth = Int(audioBufferList.pointee.mBuffers.mDataByteSize) + return Data(bytes: bufferPtr, count: audioBufferLenth) + } +} + +extension AVAudioConverter { + /// Uses the converter to convert the provided `buffer`. + /// + /// Will handle determining the proper frame capacity, ensuring formats align, and propogating any errors that occur. + /// + /// - Returns: A new buffer, with the converted data. + func convertBuffer(_ buffer: AVAudioPCMBuffer) -> AVAudioPCMBuffer { + if buffer.format == outputFormat { return buffer } + guard buffer.format == inputFormat else { + fatalError("The buffer's format was different than the converter's input format") + } + + let frameCapacity = AVAudioFrameCount( + ceil(Double(buffer.frameLength) * outputFormat.sampleRate / inputFormat.sampleRate) + ) + + guard let output = AVAudioPCMBuffer( + pcmFormat: outputFormat, + frameCapacity: frameCapacity + ) else { + fatalError("Failed to create output buffer") + } + + var error: NSError? + convert(to: output, error: &error) { _, status in + status.pointee = .haveData + return buffer + } + + if let error { + fatalError("Failed to convert buffer: \(error.localizedDescription)") + } + + return output + } +} diff --git a/firebaseai/LiveAudioExample/Audio/AudioController.swift b/firebaseai/LiveAudioExample/Audio/AudioController.swift new file mode 100644 index 000000000..cd445a5cb --- /dev/null +++ b/firebaseai/LiveAudioExample/Audio/AudioController.swift @@ -0,0 +1,234 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import AVFoundation + +/// Controls audio playback and recording. +class AudioController { + /// Data processed from the microphone. + private let microphoneData: AsyncStream + private let microphoneDataQueue: AsyncStream.Continuation + private var audioPlayer: AudioPlayer? = nil + private var audioEngine: AVAudioEngine? = nil + private var microphone: Microphone? = nil + private var listenTask: Task? = nil + + /// Port types that are considered "headphones" for our use-case. + /// + /// More specifically, airpods are considered bluetooth ports instead of headphones, so + /// this array is necessary. + private let headphonePortTypes: [AVAudioSession.Port] = [ + .headphones, + .bluetoothA2DP, + .bluetoothLE, + .bluetoothHFP + ] + + private let modelInputFormat: AVAudioFormat + private let modelOutputFormat: AVAudioFormat + + private var stopped = false + + public init() throws { + let session = AVAudioSession.sharedInstance() + try session.setCategory(.playAndRecord, mode: .voiceChat, options: [.defaultToSpeaker, .allowBluetooth, .duckOthers, .interruptSpokenAudioAndMixWithOthers, .allowBluetoothA2DP]) + try session.setPreferredIOBufferDuration(0.01) + try session.setActive(true) + + guard let modelInputFormat = AVAudioFormat( + commonFormat: .pcmFormatInt16, + sampleRate: 16_000, + channels: 1, + interleaved: false + ) else { + fatalError("Failed to create model input format") + } + + guard let modelOutputFormat = AVAudioFormat( + commonFormat: .pcmFormatInt16, + sampleRate: 24_000, + channels: 1, + interleaved: true + ) else { + fatalError("Failed to create model output format") + } + + self.modelInputFormat = modelInputFormat + self.modelOutputFormat = modelOutputFormat + + let (processedData, dataQueue) = AsyncStream.makeStream() + self.microphoneData = processedData + self.microphoneDataQueue = dataQueue + + listenForRouteChange() + } + + deinit { + stop() + } + + /// Kicks off audio processing, and returns a stream of recorded microphone audio data. + public func listenToMic() throws -> AsyncStream { + spawnAudioProcessingThread() + return microphoneData + } + + /// Permanently stop all audio processing. + /// + /// To start again, create a new instance of ``AudioController``. + public func stop() { + stopped = true + stopListeningAndPlayback() + microphoneDataQueue.finish() + NotificationCenter.default.removeObserver( + self, + name: AVAudioSession.routeChangeNotification, + object: nil + ) + } + + /// Queues audio for playback. + public func playAudio(audio: Data) { + audioPlayer?.play(audio) + } + + /// Interrupts and clears the currently pending audio playback queue. + public func interrupt() { + audioPlayer?.interrupt() + } + + private func stopListeningAndPlayback() { + listenTask?.cancel() + // audio engine needs to be stopped before disconnecting nodes + audioEngine?.pause() + audioEngine?.stop() + if let audioEngine { + do { + // the VP IO leaves behind artifacts, so we need to disable it to properly clean up + if audioEngine.inputNode.isVoiceProcessingEnabled { + try audioEngine.inputNode.setVoiceProcessingEnabled(false) + } + } catch { + print("Failed to disable voice processing: \(error.localizedDescription)") + } + } + microphone?.stop() + audioPlayer?.stop() + } + + /// Start audio processing functionality. + /// + /// Will stop any currently running audio processing. + /// + /// This function is also called whenever the input or output device change, + /// so it needs to be able to setup the audio processing without disrupting + /// the consumer of the microphone data. + private func spawnAudioProcessingThread() { + if stopped { return } + + stopListeningAndPlayback() + + // we need to start a new audio engine if the output device changed, so we might as well do it regardless + let audioEngine = AVAudioEngine() + self.audioEngine = audioEngine + + setupAudioPlayback(audioEngine) + setupVoiceProcessing(audioEngine) + + do { + try audioEngine.start() + } catch { + fatalError("Failed to start audio engine: \(error.localizedDescription)") + } + + setupMicrophone(audioEngine) + } + + private func setupMicrophone(_ engine: AVAudioEngine) { + let microphone = Microphone(engine: engine) + self.microphone = microphone + + microphone.start() + + let micFormat = engine.inputNode.outputFormat(forBus: 0) + guard let converter = AVAudioConverter(from: micFormat, to: modelInputFormat) else { + fatalError("Failed to create audio converter") + } + + listenTask = Task { + for await audio in microphone.audio { + microphoneDataQueue.yield(converter.convertBuffer(audio)) + } + } + } + + private func setupAudioPlayback(_ engine: AVAudioEngine) { + let playbackFormat = engine.outputNode.outputFormat(forBus: 0) + self.audioPlayer = AudioPlayer( + engine: engine, + inputFormat: self.modelOutputFormat, + outputFormat: playbackFormat + ) + } + + /// Sets up the voice processing I/O, if it needs to be setup. + private func setupVoiceProcessing(_ engine: AVAudioEngine) { + do { + let headphonesConnected = headphonesConnected() + let vpEnabled = engine.inputNode.isVoiceProcessingEnabled + + if !vpEnabled && !headphonesConnected { + try engine.inputNode.setVoiceProcessingEnabled(true) + } else if headphonesConnected && vpEnabled { + // bluetooth headphones have integrated AEC, so if we don't disable VP IO we get muted output + try engine.inputNode.setVoiceProcessingEnabled(false) + } + } catch { + fatalError("Failed to enable voice processing: \(error.localizedDescription)") + } + } + + /// When the output device changes, ensure the audio playback and recording classes are properly restarted. + private func listenForRouteChange() { + NotificationCenter.default.addObserver( + self, + selector: #selector(handleRouteChange), + name: AVAudioSession.routeChangeNotification, + object: nil + ) + } + + @objc private func handleRouteChange(notification: Notification) { + guard let userInfo = notification.userInfo, + let reasonValue = userInfo[AVAudioSessionRouteChangeReasonKey] as? UInt, + let reason = AVAudioSession.RouteChangeReason(rawValue: reasonValue) else { + return + } + + switch reason { + case .newDeviceAvailable, .oldDeviceUnavailable: + spawnAudioProcessingThread() + default: () + } + } + + /// Checks if the current audio route is a a headphone. + /// + /// This includes airpods. + private func headphonesConnected() -> Bool { + return AVAudioSession.sharedInstance().currentRoute.outputs.contains { + headphonePortTypes.contains($0.portType) + } + } +} diff --git a/firebaseai/LiveAudioExample/Audio/AudioPlayer.swift b/firebaseai/LiveAudioExample/Audio/AudioPlayer.swift new file mode 100644 index 000000000..281f3b8aa --- /dev/null +++ b/firebaseai/LiveAudioExample/Audio/AudioPlayer.swift @@ -0,0 +1,85 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import AVFoundation +import Foundation + +/// Plays back audio through the primary output device. +class AudioPlayer { + private let engine: AVAudioEngine + private let inputFormat: AVAudioFormat + private let outputFormat: AVAudioFormat + private let playbackNode: AVAudioPlayerNode + private var formatConverter: AVAudioConverter + + init(engine: AVAudioEngine, inputFormat: AVAudioFormat, outputFormat: AVAudioFormat) { + self.engine = engine + + guard let formatConverter = AVAudioConverter(from: inputFormat, to: outputFormat) else { + fatalError("Failed to create the audio converter") + } + + let playbackNode = AVAudioPlayerNode() + + engine.attach(playbackNode) + engine.connect(playbackNode, to: engine.mainMixerNode, format: outputFormat) + + self.inputFormat = inputFormat + self.outputFormat = outputFormat + self.formatConverter = formatConverter + self.playbackNode = playbackNode + } + + deinit { + stop() + } + + /// Queue audio to be played through the output device. + /// + /// Note that in a real app, you'd ideally schedule the data before converting it, and then mark data as consumed after its been played + /// back. That way, if the audio route changes during playback, you can requeue the buffer on the new output device. + /// + /// For the sake of simplicity, that is not implemented here; a route change will prevent the currently queued conversation from + /// being played through the output device. + public func play(_ audio: Data) { + guard engine.isRunning else { + print("Audio engine needs to be running to play audio.") + return + } + + guard let inputBuffer = AVAudioPCMBuffer.fromInterleavedData( + data: audio, + format: self.inputFormat + ) else { + fatalError("Failed to create input buffer for playback") + } + + let buffer = formatConverter.convertBuffer(inputBuffer) + + playbackNode.scheduleBuffer(buffer, at: nil) + playbackNode.play() + } + + /// Stops the current audio playing. + public func interrupt() { + playbackNode.stop() + } + + /// Permanently stop all audio playback. + public func stop() { + interrupt() + engine.disconnectNodeInput(playbackNode) + engine.disconnectNodeOutput(playbackNode) + } +} diff --git a/firebaseai/LiveAudioExample/Audio/Microphone.swift b/firebaseai/LiveAudioExample/Audio/Microphone.swift new file mode 100644 index 000000000..0764d390e --- /dev/null +++ b/firebaseai/LiveAudioExample/Audio/Microphone.swift @@ -0,0 +1,61 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import Foundation +import AVFoundation + +/// Microphone bindings using Apple's AudioEngine API. +class Microphone { + /// Data recorded from the microphone. + public let audio: AsyncStream + private let audioQueue: AsyncStream.Continuation + + private let inputNode: AVAudioInputNode + private let audioEngine: AVAudioEngine + + private var isRunning = false + + init(engine: AVAudioEngine) { + let (audio, audioQueue) = AsyncStream.makeStream() + + self.audio = audio + self.audioQueue = audioQueue + self.inputNode = engine.inputNode + self.audioEngine = engine + } + + deinit { + stop() + } + + public func start() { + guard !isRunning else { return } + isRunning = true + + // 50ms buffer size for balancing latency and cpu overhead + let targetBufferSize = UInt32(inputNode.outputFormat(forBus: 0).sampleRate / 20) + inputNode.installTap(onBus: 0, bufferSize: targetBufferSize, format: nil) { [weak self] buffer, _ in + guard let self else { return } + audioQueue.yield(buffer) + } + } + + public func stop() { + audioQueue.finish() + if isRunning { + isRunning = false + inputNode.removeTap(onBus: 0) + } + } +} diff --git a/firebaseai/LiveAudioExample/Models/TranscriptLine.swift b/firebaseai/LiveAudioExample/Models/TranscriptLine.swift new file mode 100644 index 000000000..0e9447c9d --- /dev/null +++ b/firebaseai/LiveAudioExample/Models/TranscriptLine.swift @@ -0,0 +1,28 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import FirebaseAI +import Foundation + +/// A line of a transcript. +struct TranscriptLine: Identifiable, Equatable { + let id = UUID().uuidString + var message: String = "" + + /// Whether text should be added or not. + /// + /// When a transcript line is final, no further text should be + /// added to `message`. + var isFinal: Bool = false +} diff --git a/firebaseai/LiveAudioExample/Screens/LiveAudioScreen.swift b/firebaseai/LiveAudioExample/Screens/LiveAudioScreen.swift new file mode 100644 index 000000000..a12164a84 --- /dev/null +++ b/firebaseai/LiveAudioExample/Screens/LiveAudioScreen.swift @@ -0,0 +1,52 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import MarkdownUI +import SwiftUI +import GenerativeAIUIComponents +import FirebaseAI +import AVFoundation +import Accelerate +import Charts + +struct LiveAudioScreen: View { + let firebaseService: FirebaseAI + @StateObject var viewModel: LiveViewModel + + init(firebaseService: FirebaseAI, backend: BackendOption) { + self.firebaseService = firebaseService + _viewModel = StateObject(wrappedValue: LiveViewModel(firebaseService: firebaseService, backend: backend)) + } + + var body: some View { + VStack(spacing: 20) { + ModelPhoto(isConnected: viewModel.state == .connected) + TranscriptView(vm: viewModel.transcriptViewModel) + + Spacer() + if let error = viewModel.error { + LiveErrorView(error: error) + } + ConnectButton(state: viewModel.state, onConnect: viewModel.connect, onDisconnect: viewModel.disconnect) + } + .padding() + .navigationTitle("Live Audio") + .background(viewModel.backgroundColor ?? .clear) + } +} + + +#Preview { + LiveAudioScreen(firebaseService: FirebaseAI.firebaseAI(), backend: .googleAI) +} diff --git a/firebaseai/LiveAudioExample/ViewModels/LiveViewModel.swift b/firebaseai/LiveAudioExample/ViewModels/LiveViewModel.swift new file mode 100644 index 000000000..e5f511d54 --- /dev/null +++ b/firebaseai/LiveAudioExample/ViewModels/LiveViewModel.swift @@ -0,0 +1,299 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import FirebaseAI +import Foundation +import OSLog +import AVFoundation +import SwiftUI +import AVFoundation +import AVKit + +enum LiveViewModelState { + case idle + case connecting + case connected +} + +@MainActor +class LiveViewModel: ObservableObject { + private var logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "generative-ai") + + @Published + var error: Error? + + @Published + var state: LiveViewModelState = .idle + + @Published + var transcriptViewModel: TranscriptViewModel = TranscriptViewModel() + + @Published + var backgroundColor: Color? = nil + + private var model: LiveGenerativeModel? + private var liveSession: LiveSession? + + private var audioController: AudioController? + private var microphoneTask = Task {} + + init(firebaseService: FirebaseAI, backend: BackendOption) { + model = firebaseService.liveModel( + modelName: (backend == .googleAI) ? "gemini-live-2.5-flash-preview" : "gemini-2.0-flash-exp", + generationConfig: LiveGenerationConfig( + responseModalities: [.audio], + speech: SpeechConfig(voiceName: "Zephyr", languageCode: "en-US"), + outputAudioTranscription: AudioTranscriptionConfig() + ), + tools: [ + .functionDeclarations([ + FunctionDeclaration( + name: "changeBackgroundColor", + description: "Changes the background color to the specified hex color.", + parameters: [ + "color": .string( + description: "Hex code of the color to change to. (eg, #F54927)" + ), + ], + ), + FunctionDeclaration( + name: "clearBackgroundColor", + description: "Removes the background color.", + parameters: [:] + ) + ]), + ] + ) + } + /// Start a connection to the model. + /// + /// If a connection is already active, you'll need to call ``LiveViewModel/disconnect()`` first. + func connect() async { + guard let model, state == .idle else { + return + } + + guard await requestRecordPermission() else { + logger.warning("The user denied us permission to record the microphone.") + return + } + + state = .connecting + transcriptViewModel.restart() + + do { + self.liveSession = try await model.connect() + self.audioController = try AudioController() + + try startRecording() + + state = .connected + try await startProcessingResponses() + } catch { + logger.error("\(String(describing: error))") + self.error = error + await disconnect() + } + } + + /// Disconnects the model. + /// + /// Will stop any pending playback, and the recording of the mic. + func disconnect() async { + audioController?.stop() + await liveSession?.close() + microphoneTask.cancel() + state = .idle + liveSession = nil + transcriptViewModel.clearPending() + + withAnimation { + backgroundColor = nil + } + } + + /// Starts recording data from the user's microphone, and sends it to the model. + private func startRecording() throws { + guard let audioController, let liveSession else { return } + + let stream = try audioController.listenToMic() + microphoneTask = Task { + for await audioBuffer in stream { + guard let data = audioBuffer.int16Data() else { + logger.error("Failed to convert audio buffer to int16 Data.") + continue + } + await liveSession.sendAudioRealtime(data) + } + } + } + + /// Starts queuing responses from the model for parsing. + private func startProcessingResponses() async throws { + guard let liveSession else { return } + + for try await response in liveSession.responses { + await processServerMessage(response) + } + } + + /// Requests permission to record the user's microphone, returning the result. + /// + /// This is a requirement on iOS devices, on top of needing the proper recording + /// intents. + private func requestRecordPermission() async -> Bool { + await withCheckedContinuation { cont in + if #available(iOS 17.0, *) { + Task { + let ok = await AVAudioApplication.requestRecordPermission() + cont.resume(with: .success(ok)) + } + } else { + AVAudioSession.sharedInstance().requestRecordPermission { ok in + cont.resume(with: .success(ok)) + } + } + } + } + + private func processServerMessage(_ message: LiveServerMessage) async { + switch message.payload { + case .content(let content): + await processServerContent(content) + case .toolCall(let toolCall): + await processFunctionCalls(functionCalls: toolCall.functionCalls ?? []) + case .toolCallCancellation(_): + // we don't have any long running functions to cancel + return + case .goingAwayNotice(let goingAwayNotice): + let time = goingAwayNotice.timeLeft?.description ?? "soon" + logger.warning("Going away in: \(time)") + } + } + + private func processServerContent(_ content: LiveServerContent) async { + if let message = content.modelTurn { + await processAudioMessages(message) + } + + if content.isTurnComplete { + // add a space, so the next time a transcript comes in, it's not squished with the previous one + transcriptViewModel.appendTranscript(" ") + } + + if content.wasInterrupted { + logger.warning("Model was interrupted") + audioController?.interrupt() + transcriptViewModel.clearPending() + // adds an em dash to indiciate that the model was cutoff + transcriptViewModel.appendTranscript("— ") + } else if let transcript = content.outputAudioTranscription?.text { + appendAudioTranscript(transcript) + } + } + + private func processAudioMessages(_ content: ModelContent) async { + for part in content.parts { + if let part = part as? InlineDataPart { + if part.mimeType.starts(with: "audio/pcm") { + audioController?.playAudio(audio: part.data) + } else { + logger.warning("Received non audio inline data part: \(part.mimeType)") + } + } + } + } + + private func processFunctionCalls(functionCalls: [FunctionCallPart]) async { + let responses = functionCalls.map { functionCall in + switch functionCall.name { + case "changeBackgroundColor": + return changeBackgroundColor(args: functionCall.args, id: functionCall.functionId) + case "clearBackgroundColor": + return clearBackgroundColor(id: functionCall.functionId) + default: + logger.debug("Function call: \(String(describing: functionCall))") + fatalError("Unknown function named \"\(functionCall.name)\".") + } + } + + await liveSession?.sendFunctionResponses(responses) + } + + private func appendAudioTranscript(_ transcript: String) { + transcriptViewModel.appendTranscript(transcript) + } + + private func changeBackgroundColor(args: JSONObject, id: String?) -> FunctionResponsePart { + guard case let .string(color) = args["color"] else { + logger.debug("Function arguments: \(String(describing: args))") + fatalError("Missing `color` parameter.") + } + + withAnimation { + backgroundColor = Color(hex: color) + } + + if backgroundColor == nil { + logger.warning("The model sent us an invalid hex color: \(color)") + } + + return FunctionResponsePart( + name: "changeBackgroundColor", + response: JSONObject(), + functionId: id + ) + } + + private func clearBackgroundColor(id: String?) -> FunctionResponsePart { + withAnimation { + backgroundColor = nil + } + + return FunctionResponsePart( + name: "clearBackgroundColor", + response: JSONObject(), + functionId: id + ) + } +} + +extension Color { + /// Creates a new `Color` instance from a hex string. + /// + /// Supports both RGB and RGBA hex strings. + init?(hex: String) { + let hex = hex.replacingOccurrences(of: "#", with: "").uppercased() + + var rgb: UInt64 = 0 + guard Scanner(string: hex).scanHexInt64(&rgb) else { return nil } + + var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 1 + + if hex.count == 6 { + r = CGFloat((rgb & 0xFF0000) >> 16) / 255.0 + g = CGFloat((rgb & 0x00FF00) >> 8) / 255.0 + b = CGFloat(rgb & 0x0000FF) / 255.0 + } else if hex.count == 8 { + r = CGFloat((rgb & 0xFF000000) >> 24) / 255.0 + g = CGFloat((rgb & 0x00FF0000) >> 16) / 255.0 + b = CGFloat((rgb & 0x0000FF00) >> 8) / 255.0 + a = CGFloat(rgb & 0x000000FF) / 255.0 + } else { + return nil + } + + self.init(red: r, green: g, blue: b, opacity: a) + } +} diff --git a/firebaseai/LiveAudioExample/ViewModels/TranscriptViewModel.swift b/firebaseai/LiveAudioExample/ViewModels/TranscriptViewModel.swift new file mode 100644 index 000000000..cdd8cda15 --- /dev/null +++ b/firebaseai/LiveAudioExample/ViewModels/TranscriptViewModel.swift @@ -0,0 +1,147 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import SwiftUI +import Foundation + +/// How long to wait (in milliseconds) between showing the next character. +private let CharDelayMS = 65 + +/// The intended amount of characters in a line. +/// +/// Can exceed this if the line doesn't end in a space of punctuation. +private let LineCharacterLength = 20 + +/// The max amount of lines to hold references for at a time. +private let MaxLines = 3 + +/// Creates lines of transcripts to display, populated in a type-writer manner. +@MainActor +class TranscriptViewModel: ObservableObject { + /// Lines of characters to display. + @Published + var audioTranscripts: [TranscriptLine] = [] + + private var pendingText = [Character]() + private var processTextTask: Task? = nil + + init() { + processTask() + } + + deinit { + processTextTask?.cancel() + } + + /// Queues text to show. + /// + /// Since the text is queued, the text wont be displayed until the previous + /// pending text is populated. + func appendTranscript(_ text: String) { + pendingText.append(contentsOf: text) + } + + /// Clears any text from the queue that is pending being added to a transcript line. + func clearPending() { + pendingText.removeAll() + } + + /// Restarts the class to be a fresh instance. + /// + /// Effectively, this removes all the currently tracked transcript lines, + /// and any pending text. + func restart() { + clearPending() + audioTranscripts.removeAll() + processTask() + } + + /// Long running task for processing characters. + private func processTask() { + processTextTask = Task { + var delay = CharDelayMS + while !Task.isCancelled { + try? await Task.sleep(for: .milliseconds(delay)) + + delay = processNextCharacter() + } + } + } + + private func processNextCharacter() -> Int { + guard !pendingText.isEmpty else { + return CharDelayMS // Default delay if no text is pending + } + + let char = pendingText.removeFirst() + var line = popCurrentLine() + line.message.append(char) + + let nextDelay = determineNextDelayAndFinalize(for: char, in: &line) + + updateTranscripts(with: line) + + return nextDelay + } + + /// Determines the delay for the next character, finalizing the line as needed. + /// + /// We don't have a delay when outputting whitespace or the end of a sentence. + /// + /// We also don't mark a line as "complete" unless it ends in whitespace or some + /// punctuation; as this helps avoid weird situations where words are split across lines. + /// + /// - Returns: The MS delay before working on the next character in the queue. + private func determineNextDelayAndFinalize(for char: Character, in line: inout TranscriptLine) -> Int { + if char.isWhitespace || char.isEndOfSentence { + if line.message.count >= LineCharacterLength { + line.isFinal = true + } + + return 0 + } + + return CharDelayMS + } + + /// Updates `audioTranscripts` with the current line. + /// + /// Will remove the oldest line if we exceed `MaxLines`. + private func updateTranscripts(with line: TranscriptLine) { + audioTranscripts.append(line) + + if audioTranscripts.count > MaxLines { + // fade out the removal; makes it less jumpy during rendering when lines are moved up + withAnimation { + let _ = audioTranscripts.removeFirst() + } + } + } + + /// Removes the last line from `audioTranscripts`. + /// + /// If the last line is already finalized, a new line will be returned instead. + private func popCurrentLine() -> TranscriptLine { + if audioTranscripts.last?.isFinal != false { + return TranscriptLine() + } + return audioTranscripts.removeLast() + } +} + +extension Character { + var isEndOfSentence: Bool { + self == "." || self == "!" || self == "?" + } +} diff --git a/firebaseai/LiveAudioExample/Views/ConnectButton.swift b/firebaseai/LiveAudioExample/Views/ConnectButton.swift new file mode 100644 index 000000000..8d446a544 --- /dev/null +++ b/firebaseai/LiveAudioExample/Views/ConnectButton.swift @@ -0,0 +1,103 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import SwiftUI + +struct ConnectButton: View { + var state: LiveViewModelState + var onConnect: () async -> () + var onDisconnect: () async -> () + + @State private var gradientAngle: Angle = .zero + + private var isConnected: Bool { state == .connected } + + private var title: String { + switch state { + case .connected: "Stop" + case .connecting: "Connecting..." + case .idle: "Start" + } + } + + private var image: String { + switch state { + case .connected: "stop.fill" + case .connecting: "wifi.square.fill" + case .idle: "play.square.fill" + } + } + + private var color: Color { + switch state { + case .connected: Color.red + case .connecting: Color.secondary + case .idle: Color.accentColor + } + } + + private var gradientColors: [Color] { + switch state { + case .connected: [] + case .connecting: [.secondary, .white] + case .idle: [.red, .blue, .green, .yellow, .red] + } + } + + var body: some View { + Button(action: onClick) { + Label(title, systemImage: image) + .font(.title2.bold()) + .frame(maxWidth: .infinity) + .padding() + .background(color) + .foregroundStyle(.white) + .clipShape(RoundedRectangle(cornerRadius: 12)) + }.disabled(state == .connecting).overlay( + RoundedRectangle(cornerRadius: 12) + .stroke( + AngularGradient( + gradient: Gradient(colors: gradientColors), + center: .center, + startAngle: gradientAngle, + endAngle: gradientAngle + .degrees(360) + ), + lineWidth: 3 + ) + ) + .onAppear { + withAnimation(.linear(duration: 5).repeatForever(autoreverses: false)) { + self.gradientAngle = .degrees(360) + } + } + } + + private func onClick() { + Task { + if isConnected { + await onDisconnect() + } else { + await onConnect() + } + } + } +} + +#Preview { + VStack(spacing: 30) { + ConnectButton(state: .idle, onConnect: {}, onDisconnect: {}) + ConnectButton(state: .connecting, onConnect: {}, onDisconnect: {}) + ConnectButton(state: .connected, onConnect: {}, onDisconnect: {}) + }.padding(.horizontal) +} diff --git a/firebaseai/LiveAudioExample/Views/LiveErrorDetailsView.swift b/firebaseai/LiveAudioExample/Views/LiveErrorDetailsView.swift new file mode 100644 index 000000000..e492efd28 --- /dev/null +++ b/firebaseai/LiveAudioExample/Views/LiveErrorDetailsView.swift @@ -0,0 +1,85 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +@testable import FirebaseAI +import MarkdownUI +import SwiftUI + +struct LiveErrorDetailsView: View { + var error: Error + + var body: some View { + NavigationView { + Form { + if let title = error.title { + Section("Error type") { + Text(title) + } + } + + Section("Details") { + SubtitleFormRow(title: "Error description", value: error.localizedDescription) + } + } + .navigationTitle("Error details") + .navigationBarTitleDisplayMode(.inline) + } + } +} + +private struct SubtitleFormRow: View { + var title: String + var value: String + + var body: some View { + VStack(alignment: .leading) { + Text(title).font(.subheadline) + Text(value) + } + } +} + +private extension Error { + var title: String? { + switch self { + case _ as LiveSessionSetupError: + "Failed to set up live session" + case _ as LiveSessionLostConnectionError: + "Lost connection to the model" + case _ as LiveSessionUnexpectedClosureError: + "Session was closed" + case _ as LiveSessionUnsupportedMessageError: + "Unsupported model message" + default: + nil + } + } +} + +#Preview("Live error") { + let cause = NSError(domain: "network.api", code: 1, userInfo: [ + NSLocalizedDescriptionKey: "Network timed out." + ]) + let error = LiveSessionLostConnectionError(underlyingError: cause) + + LiveErrorDetailsView(error: error) +} + +#Preview("Unexpected error") { + let error = NSError(domain: "network.api", code: 1, userInfo: [ + NSLocalizedDescriptionKey: "Network timed out." + ]) + + LiveErrorDetailsView(error: error) +} diff --git a/firebaseai/LiveAudioExample/Views/LiveErrorView.swift b/firebaseai/LiveAudioExample/Views/LiveErrorView.swift new file mode 100644 index 000000000..f615c6c56 --- /dev/null +++ b/firebaseai/LiveAudioExample/Views/LiveErrorView.swift @@ -0,0 +1,44 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +@testable import FirebaseAI +import SwiftUI + +struct LiveErrorView: View { + var error: Error + @State private var isDetailsSheetPresented = false + + var body: some View { + HStack { + Text("An error occurred.") + Button(action: { isDetailsSheetPresented.toggle() }) { + Image(systemName: "info.circle") + }.foregroundStyle(.red) + } + .frame(maxWidth: .infinity, alignment: .center) + .listRowSeparator(.hidden) + .sheet(isPresented: $isDetailsSheetPresented) { + LiveErrorDetailsView(error: error) + } + } +} + +#Preview { + let cause = NSError(domain: "network.api", code: 1, userInfo: [ + NSLocalizedDescriptionKey: "Network timed out." + ]) + let error = LiveSessionLostConnectionError(underlyingError: cause) + + LiveErrorView(error: error) +} diff --git a/firebaseai/LiveAudioExample/Views/ModelPhoto.swift b/firebaseai/LiveAudioExample/Views/ModelPhoto.swift new file mode 100644 index 000000000..82f50f373 --- /dev/null +++ b/firebaseai/LiveAudioExample/Views/ModelPhoto.swift @@ -0,0 +1,65 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import SwiftUI + +struct ModelPhoto: View { + var isConnected = false + + @State private var gradientAngle: Angle = .zero + + var colors: [Color] { + if isConnected { + [.red, .blue, .green, .yellow, .red] + } else { + [Color(red: 0.5, green: 0.5, blue: 0.5, opacity: 0.3)] + } + } + + var body: some View { + Image("gemini-logo").resizable().aspectRatio(contentMode: .fit).padding().colorMultiply(.black) + .maskedOverlay { + AngularGradient( + gradient: Gradient(colors: colors), + center: .leading, + startAngle: gradientAngle, + endAngle: gradientAngle + .degrees(360) + ) + }.onAppear { + withAnimation(.linear(duration: 10).repeatForever(autoreverses: false)) { + self.gradientAngle = .degrees(360) + } + } + } +} + +extension View { + /// Creates an overlay which takes advantage of a mask to respect the size of the view. + /// + /// Especially useful when you want to create an overlay of an view with a non standard + /// size. + @ViewBuilder + func maskedOverlay(mask: () -> some View) -> some View { + overlay { + mask().mask { self } + } + } +} + +#Preview { + VStack { + ModelPhoto(isConnected: true) + ModelPhoto(isConnected: false) + } +} diff --git a/firebaseai/LiveAudioExample/Views/TranscriptView.swift b/firebaseai/LiveAudioExample/Views/TranscriptView.swift new file mode 100644 index 000000000..cb310053f --- /dev/null +++ b/firebaseai/LiveAudioExample/Views/TranscriptView.swift @@ -0,0 +1,39 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import SwiftUI + +struct TranscriptView: View { + @ObservedObject var vm: TranscriptViewModel + + var body: some View { + VStack { + ForEach(vm.audioTranscripts) { transcript in + Text(transcript.message) + .bold() + .font(.title) + .frame(maxWidth: .infinity, alignment: .leading) + .transition(.opacity) + .padding(.horizontal) + } + } + } +} + +#Preview { + let vm = TranscriptViewModel() + TranscriptView(vm: vm).onAppear() { + vm.appendTranscript("The sky is blue primarily because of a phenomenon called Rayleigh scattering, where tiny molecules of gas (mainly nitrogen and oxygen) in Earth's atmosphere scatter sunlight in all directions.") + } +} From caaa8cd6bc0d4cb9ed60e8854fedbf41c55f5b02 Mon Sep 17 00:00:00 2001 From: Daymon Date: Tue, 7 Oct 2025 13:55:03 -0500 Subject: [PATCH 02/10] Add microphone usage description --- firebaseai/FirebaseAIExample.xcodeproj/project.pbxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/firebaseai/FirebaseAIExample.xcodeproj/project.pbxproj b/firebaseai/FirebaseAIExample.xcodeproj/project.pbxproj index 24a92e20c..9d2c5a9b7 100644 --- a/firebaseai/FirebaseAIExample.xcodeproj/project.pbxproj +++ b/firebaseai/FirebaseAIExample.xcodeproj/project.pbxproj @@ -755,6 +755,7 @@ ENABLE_PREVIEWS = YES; ENABLE_USER_SCRIPT_SANDBOXING = NO; GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSMicrophoneUsageDescription = "Communicating with the model through the Live Audio screen"; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; @@ -785,6 +786,7 @@ ENABLE_PREVIEWS = YES; ENABLE_USER_SCRIPT_SANDBOXING = NO; GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSMicrophoneUsageDescription = "Communicating with the model through the Live Audio screen"; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; From ca5df4578666a0685ec4d3a05157d484eede0781 Mon Sep 17 00:00:00 2001 From: Daymon Date: Tue, 7 Oct 2025 13:56:12 -0500 Subject: [PATCH 03/10] Add live screen to xcode project --- .../project.pbxproj | 132 ++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/firebaseai/FirebaseAIExample.xcodeproj/project.pbxproj b/firebaseai/FirebaseAIExample.xcodeproj/project.pbxproj index 9d2c5a9b7..b33bc51ae 100644 --- a/firebaseai/FirebaseAIExample.xcodeproj/project.pbxproj +++ b/firebaseai/FirebaseAIExample.xcodeproj/project.pbxproj @@ -7,6 +7,34 @@ objects = { /* Begin PBXBuildFile section */ + 0EE94F252E9599B800CEFD69 /* TranscriptView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F212E9599B800CEFD69 /* TranscriptView.swift */; }; + 0EE94F262E9599B800CEFD69 /* ConnectButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F1D2E9599B800CEFD69 /* ConnectButton.swift */; }; + 0EE94F272E9599B800CEFD69 /* TranscriptViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F1B2E9599B800CEFD69 /* TranscriptViewModel.swift */; }; + 0EE94F282E9599B800CEFD69 /* AudioPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F132E9599B800CEFD69 /* AudioPlayer.swift */; }; + 0EE94F292E9599B800CEFD69 /* LiveAudioScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F182E9599B800CEFD69 /* LiveAudioScreen.swift */; }; + 0EE94F2A2E9599B800CEFD69 /* LiveViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F1A2E9599B800CEFD69 /* LiveViewModel.swift */; }; + 0EE94F2B2E9599B800CEFD69 /* TranscriptLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F162E9599B800CEFD69 /* TranscriptLine.swift */; }; + 0EE94F2C2E9599B800CEFD69 /* ModelPhoto.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F202E9599B800CEFD69 /* ModelPhoto.swift */; }; + 0EE94F2D2E9599B800CEFD69 /* LiveErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F1F2E9599B800CEFD69 /* LiveErrorView.swift */; }; + 0EE94F2E2E9599B800CEFD69 /* Microphone.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F142E9599B800CEFD69 /* Microphone.swift */; }; + 0EE94F2F2E9599B800CEFD69 /* LiveErrorDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F1E2E9599B800CEFD69 /* LiveErrorDetailsView.swift */; }; + 0EE94F302E9599B800CEFD69 /* AudioController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F122E9599B800CEFD69 /* AudioController.swift */; }; + 0EE94F312E9599B800CEFD69 /* AudioBufferHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F112E9599B800CEFD69 /* AudioBufferHelpers.swift */; }; + 0EE94F322E9599B800CEFD69 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0EE94F232E9599B800CEFD69 /* Assets.xcassets */; }; + 0EE94F332E9599B800CEFD69 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0EE94F232E9599B800CEFD69 /* Assets.xcassets */; }; + 0EE94F342E9599B800CEFD69 /* TranscriptView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F212E9599B800CEFD69 /* TranscriptView.swift */; }; + 0EE94F352E9599B800CEFD69 /* ConnectButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F1D2E9599B800CEFD69 /* ConnectButton.swift */; }; + 0EE94F362E9599B800CEFD69 /* TranscriptViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F1B2E9599B800CEFD69 /* TranscriptViewModel.swift */; }; + 0EE94F372E9599B800CEFD69 /* AudioPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F132E9599B800CEFD69 /* AudioPlayer.swift */; }; + 0EE94F382E9599B800CEFD69 /* LiveAudioScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F182E9599B800CEFD69 /* LiveAudioScreen.swift */; }; + 0EE94F392E9599B800CEFD69 /* LiveViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F1A2E9599B800CEFD69 /* LiveViewModel.swift */; }; + 0EE94F3A2E9599B800CEFD69 /* TranscriptLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F162E9599B800CEFD69 /* TranscriptLine.swift */; }; + 0EE94F3B2E9599B800CEFD69 /* ModelPhoto.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F202E9599B800CEFD69 /* ModelPhoto.swift */; }; + 0EE94F3C2E9599B800CEFD69 /* LiveErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F1F2E9599B800CEFD69 /* LiveErrorView.swift */; }; + 0EE94F3D2E9599B800CEFD69 /* Microphone.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F142E9599B800CEFD69 /* Microphone.swift */; }; + 0EE94F3E2E9599B800CEFD69 /* LiveErrorDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F1E2E9599B800CEFD69 /* LiveErrorDetailsView.swift */; }; + 0EE94F3F2E9599B800CEFD69 /* AudioController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F122E9599B800CEFD69 /* AudioController.swift */; }; + 0EE94F402E9599B800CEFD69 /* AudioBufferHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE94F112E9599B800CEFD69 /* AudioBufferHelpers.swift */; }; 860F09212E8C4179002D85D0 /* FirebaseAILogic.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 860F09142E8C4171002D85D0 /* FirebaseAILogic.xcframework */; }; 860F09222E8C4179002D85D0 /* FirebaseAILogic.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 860F09142E8C4171002D85D0 /* FirebaseAILogic.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 860F09242E8C417A002D85D0 /* FirebaseAppCheckInterop.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 860F09152E8C4171002D85D0 /* FirebaseAppCheckInterop.xcframework */; }; @@ -93,6 +121,20 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 0EE94F112E9599B800CEFD69 /* AudioBufferHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioBufferHelpers.swift; sourceTree = ""; }; + 0EE94F122E9599B800CEFD69 /* AudioController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioController.swift; sourceTree = ""; }; + 0EE94F132E9599B800CEFD69 /* AudioPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioPlayer.swift; sourceTree = ""; }; + 0EE94F142E9599B800CEFD69 /* Microphone.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Microphone.swift; sourceTree = ""; }; + 0EE94F162E9599B800CEFD69 /* TranscriptLine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TranscriptLine.swift; sourceTree = ""; }; + 0EE94F182E9599B800CEFD69 /* LiveAudioScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveAudioScreen.swift; sourceTree = ""; }; + 0EE94F1A2E9599B800CEFD69 /* LiveViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveViewModel.swift; sourceTree = ""; }; + 0EE94F1B2E9599B800CEFD69 /* TranscriptViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TranscriptViewModel.swift; sourceTree = ""; }; + 0EE94F1D2E9599B800CEFD69 /* ConnectButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectButton.swift; sourceTree = ""; }; + 0EE94F1E2E9599B800CEFD69 /* LiveErrorDetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveErrorDetailsView.swift; sourceTree = ""; }; + 0EE94F1F2E9599B800CEFD69 /* LiveErrorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveErrorView.swift; sourceTree = ""; }; + 0EE94F202E9599B800CEFD69 /* ModelPhoto.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelPhoto.swift; sourceTree = ""; }; + 0EE94F212E9599B800CEFD69 /* TranscriptView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TranscriptView.swift; sourceTree = ""; }; + 0EE94F232E9599B800CEFD69 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 860F09142E8C4171002D85D0 /* FirebaseAILogic.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = FirebaseAILogic.xcframework; sourceTree = ""; }; 860F09152E8C4171002D85D0 /* FirebaseAppCheckInterop.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = FirebaseAppCheckInterop.xcframework; sourceTree = ""; }; 860F09162E8C4171002D85D0 /* FirebaseAuthInterop.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = FirebaseAuthInterop.xcframework; sourceTree = ""; }; @@ -163,6 +205,67 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 0EE94F152E9599B800CEFD69 /* Audio */ = { + isa = PBXGroup; + children = ( + 0EE94F112E9599B800CEFD69 /* AudioBufferHelpers.swift */, + 0EE94F122E9599B800CEFD69 /* AudioController.swift */, + 0EE94F132E9599B800CEFD69 /* AudioPlayer.swift */, + 0EE94F142E9599B800CEFD69 /* Microphone.swift */, + ); + path = Audio; + sourceTree = ""; + }; + 0EE94F172E9599B800CEFD69 /* Models */ = { + isa = PBXGroup; + children = ( + 0EE94F162E9599B800CEFD69 /* TranscriptLine.swift */, + ); + path = Models; + sourceTree = ""; + }; + 0EE94F192E9599B800CEFD69 /* Screens */ = { + isa = PBXGroup; + children = ( + 0EE94F182E9599B800CEFD69 /* LiveAudioScreen.swift */, + ); + path = Screens; + sourceTree = ""; + }; + 0EE94F1C2E9599B800CEFD69 /* ViewModels */ = { + isa = PBXGroup; + children = ( + 0EE94F1A2E9599B800CEFD69 /* LiveViewModel.swift */, + 0EE94F1B2E9599B800CEFD69 /* TranscriptViewModel.swift */, + ); + path = ViewModels; + sourceTree = ""; + }; + 0EE94F222E9599B800CEFD69 /* Views */ = { + isa = PBXGroup; + children = ( + 0EE94F1D2E9599B800CEFD69 /* ConnectButton.swift */, + 0EE94F1E2E9599B800CEFD69 /* LiveErrorDetailsView.swift */, + 0EE94F1F2E9599B800CEFD69 /* LiveErrorView.swift */, + 0EE94F202E9599B800CEFD69 /* ModelPhoto.swift */, + 0EE94F212E9599B800CEFD69 /* TranscriptView.swift */, + ); + path = Views; + sourceTree = ""; + }; + 0EE94F242E9599B800CEFD69 /* LiveAudioExample */ = { + isa = PBXGroup; + children = ( + 0EE94F152E9599B800CEFD69 /* Audio */, + 0EE94F172E9599B800CEFD69 /* Models */, + 0EE94F192E9599B800CEFD69 /* Screens */, + 0EE94F1C2E9599B800CEFD69 /* ViewModels */, + 0EE94F222E9599B800CEFD69 /* Views */, + 0EE94F232E9599B800CEFD69 /* Assets.xcassets */, + ); + path = LiveAudioExample; + sourceTree = ""; + }; 860F091A2E8C4171002D85D0 /* Firebase */ = { isa = PBXGroup; children = ( @@ -244,6 +347,7 @@ 8848C8262B0D04BC007B434F = { isa = PBXGroup; children = ( + 0EE94F242E9599B800CEFD69 /* LiveAudioExample */, DEFECAA82D7B4CCD00EF9621 /* ImagenScreen */, 88B8A9352B0FCBA700424728 /* GenerativeAIUIComponents */, 869200B22B879C4F00482873 /* GoogleService-Info.plist */, @@ -492,6 +596,7 @@ files = ( 86BB56022E8B2D6D0054B8B5 /* Preview Assets.xcassets in Resources */, 86BB56032E8B2D6D0054B8B5 /* Assets.xcassets in Resources */, + 0EE94F322E9599B800CEFD69 /* Assets.xcassets in Resources */, 86BB56042E8B2D6D0054B8B5 /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -502,6 +607,7 @@ files = ( 8848C83A2B0D04BD007B434F /* Preview Assets.xcassets in Resources */, 8848C8372B0D04BD007B434F /* Assets.xcassets in Resources */, + 0EE94F332E9599B800CEFD69 /* Assets.xcassets in Resources */, 869200B32B879C4F00482873 /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -519,6 +625,19 @@ 86BB55ED2E8B2D6D0054B8B5 /* ChatMessage.swift in Sources */, 86BB55EE2E8B2D6D0054B8B5 /* ErrorDetailsView.swift in Sources */, 86BB55EF2E8B2D6D0054B8B5 /* ContentView.swift in Sources */, + 0EE94F252E9599B800CEFD69 /* TranscriptView.swift in Sources */, + 0EE94F262E9599B800CEFD69 /* ConnectButton.swift in Sources */, + 0EE94F272E9599B800CEFD69 /* TranscriptViewModel.swift in Sources */, + 0EE94F282E9599B800CEFD69 /* AudioPlayer.swift in Sources */, + 0EE94F292E9599B800CEFD69 /* LiveAudioScreen.swift in Sources */, + 0EE94F2A2E9599B800CEFD69 /* LiveViewModel.swift in Sources */, + 0EE94F2B2E9599B800CEFD69 /* TranscriptLine.swift in Sources */, + 0EE94F2C2E9599B800CEFD69 /* ModelPhoto.swift in Sources */, + 0EE94F2D2E9599B800CEFD69 /* LiveErrorView.swift in Sources */, + 0EE94F2E2E9599B800CEFD69 /* Microphone.swift in Sources */, + 0EE94F2F2E9599B800CEFD69 /* LiveErrorDetailsView.swift in Sources */, + 0EE94F302E9599B800CEFD69 /* AudioController.swift in Sources */, + 0EE94F312E9599B800CEFD69 /* AudioBufferHelpers.swift in Sources */, 86BB55F02E8B2D6D0054B8B5 /* GenerateContentScreen.swift in Sources */, 86BB55F12E8B2D6D0054B8B5 /* FirebaseAIExampleApp.swift in Sources */, 86BB55F22E8B2D6D0054B8B5 /* ConversationViewModel.swift in Sources */, @@ -545,6 +664,19 @@ 886F95DE2B17D5010036F07A /* ChatMessage.swift in Sources */, 88263BF12B239C11008AB09B /* ErrorDetailsView.swift in Sources */, 8848C8352B0D04BC007B434F /* ContentView.swift in Sources */, + 0EE94F342E9599B800CEFD69 /* TranscriptView.swift in Sources */, + 0EE94F352E9599B800CEFD69 /* ConnectButton.swift in Sources */, + 0EE94F362E9599B800CEFD69 /* TranscriptViewModel.swift in Sources */, + 0EE94F372E9599B800CEFD69 /* AudioPlayer.swift in Sources */, + 0EE94F382E9599B800CEFD69 /* LiveAudioScreen.swift in Sources */, + 0EE94F392E9599B800CEFD69 /* LiveViewModel.swift in Sources */, + 0EE94F3A2E9599B800CEFD69 /* TranscriptLine.swift in Sources */, + 0EE94F3B2E9599B800CEFD69 /* ModelPhoto.swift in Sources */, + 0EE94F3C2E9599B800CEFD69 /* LiveErrorView.swift in Sources */, + 0EE94F3D2E9599B800CEFD69 /* Microphone.swift in Sources */, + 0EE94F3E2E9599B800CEFD69 /* LiveErrorDetailsView.swift in Sources */, + 0EE94F3F2E9599B800CEFD69 /* AudioController.swift in Sources */, + 0EE94F402E9599B800CEFD69 /* AudioBufferHelpers.swift in Sources */, 886F95D52B17BA010036F07A /* GenerateContentScreen.swift in Sources */, 8848C8332B0D04BC007B434F /* FirebaseAIExampleApp.swift in Sources */, 886F95E02B17D5010036F07A /* ConversationViewModel.swift in Sources */, From 39d50cb28473ddc83a225f1a7cad5ad7e6d9db3a Mon Sep 17 00:00:00 2001 From: Daymon Date: Tue, 7 Oct 2025 17:56:21 -0500 Subject: [PATCH 04/10] Fix bug in transcript view model --- firebaseai/LiveAudioExample/ViewModels/TranscriptViewModel.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/firebaseai/LiveAudioExample/ViewModels/TranscriptViewModel.swift b/firebaseai/LiveAudioExample/ViewModels/TranscriptViewModel.swift index cdd8cda15..04bed3f1e 100644 --- a/firebaseai/LiveAudioExample/ViewModels/TranscriptViewModel.swift +++ b/firebaseai/LiveAudioExample/ViewModels/TranscriptViewModel.swift @@ -64,7 +64,6 @@ class TranscriptViewModel: ObservableObject { func restart() { clearPending() audioTranscripts.removeAll() - processTask() } /// Long running task for processing characters. From 693e4982cfb9a996d3ee44218c8a111713b1200b Mon Sep 17 00:00:00 2001 From: Daymon Date: Tue, 7 Oct 2025 18:05:38 -0500 Subject: [PATCH 05/10] Formatting --- .../Audio/AudioBufferHelpers.swift | 3 +- .../Audio/AudioController.swift | 37 +++++++++++-------- .../LiveAudioExample/Audio/AudioPlayer.swift | 2 +- .../LiveAudioExample/Audio/Microphone.swift | 13 ++++--- .../Screens/LiveAudioScreen.swift | 10 +++-- .../ViewModels/LiveViewModel.swift | 30 +++++++-------- .../ViewModels/TranscriptViewModel.swift | 9 +++-- .../Views/ConnectButton.swift | 6 +-- .../Views/LiveErrorDetailsView.swift | 4 +- .../Views/LiveErrorView.swift | 2 +- .../LiveAudioExample/Views/ModelPhoto.swift | 2 +- .../Views/TranscriptView.swift | 7 +++- 12 files changed, 70 insertions(+), 55 deletions(-) diff --git a/firebaseai/LiveAudioExample/Audio/AudioBufferHelpers.swift b/firebaseai/LiveAudioExample/Audio/AudioBufferHelpers.swift index b6d1f51dc..3f02c8678 100644 --- a/firebaseai/LiveAudioExample/Audio/AudioBufferHelpers.swift +++ b/firebaseai/LiveAudioExample/Audio/AudioBufferHelpers.swift @@ -23,7 +23,8 @@ extension AVAudioPCMBuffer { fatalError("Only interleaved data is supported") } - let frameCapacity = AVAudioFrameCount(data.count / Int(format.streamDescription.pointee.mBytesPerFrame)) + let frameCapacity = AVAudioFrameCount(data + .count / Int(format.streamDescription.pointee.mBytesPerFrame)) guard let buffer = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: frameCapacity) else { return nil } diff --git a/firebaseai/LiveAudioExample/Audio/AudioController.swift b/firebaseai/LiveAudioExample/Audio/AudioController.swift index cd445a5cb..b6baaccd8 100644 --- a/firebaseai/LiveAudioExample/Audio/AudioController.swift +++ b/firebaseai/LiveAudioExample/Audio/AudioController.swift @@ -19,10 +19,10 @@ class AudioController { /// Data processed from the microphone. private let microphoneData: AsyncStream private let microphoneDataQueue: AsyncStream.Continuation - private var audioPlayer: AudioPlayer? = nil - private var audioEngine: AVAudioEngine? = nil - private var microphone: Microphone? = nil - private var listenTask: Task? = nil + private var audioPlayer: AudioPlayer? + private var audioEngine: AVAudioEngine? + private var microphone: Microphone? + private var listenTask: Task? /// Port types that are considered "headphones" for our use-case. /// @@ -32,7 +32,7 @@ class AudioController { .headphones, .bluetoothA2DP, .bluetoothLE, - .bluetoothHFP + .bluetoothHFP, ] private let modelInputFormat: AVAudioFormat @@ -42,13 +42,18 @@ class AudioController { public init() throws { let session = AVAudioSession.sharedInstance() - try session.setCategory(.playAndRecord, mode: .voiceChat, options: [.defaultToSpeaker, .allowBluetooth, .duckOthers, .interruptSpokenAudioAndMixWithOthers, .allowBluetoothA2DP]) + try session.setCategory( + .playAndRecord, + mode: .voiceChat, + options: [.defaultToSpeaker, .allowBluetooth, .duckOthers, + .interruptSpokenAudioAndMixWithOthers, .allowBluetoothA2DP] + ) try session.setPreferredIOBufferDuration(0.01) try session.setActive(true) guard let modelInputFormat = AVAudioFormat( commonFormat: .pcmFormatInt16, - sampleRate: 16_000, + sampleRate: 16000, channels: 1, interleaved: false ) else { @@ -57,7 +62,7 @@ class AudioController { guard let modelOutputFormat = AVAudioFormat( commonFormat: .pcmFormatInt16, - sampleRate: 24_000, + sampleRate: 24000, channels: 1, interleaved: true ) else { @@ -68,8 +73,8 @@ class AudioController { self.modelOutputFormat = modelOutputFormat let (processedData, dataQueue) = AsyncStream.makeStream() - self.microphoneData = processedData - self.microphoneDataQueue = dataQueue + microphoneData = processedData + microphoneDataQueue = dataQueue listenForRouteChange() } @@ -175,9 +180,9 @@ class AudioController { private func setupAudioPlayback(_ engine: AVAudioEngine) { let playbackFormat = engine.outputNode.outputFormat(forBus: 0) - self.audioPlayer = AudioPlayer( + audioPlayer = AudioPlayer( engine: engine, - inputFormat: self.modelOutputFormat, + inputFormat: modelOutputFormat, outputFormat: playbackFormat ) } @@ -188,9 +193,9 @@ class AudioController { let headphonesConnected = headphonesConnected() let vpEnabled = engine.inputNode.isVoiceProcessingEnabled - if !vpEnabled && !headphonesConnected { + if !vpEnabled, !headphonesConnected { try engine.inputNode.setVoiceProcessingEnabled(true) - } else if headphonesConnected && vpEnabled { + } else if headphonesConnected, vpEnabled { // bluetooth headphones have integrated AEC, so if we don't disable VP IO we get muted output try engine.inputNode.setVoiceProcessingEnabled(false) } @@ -211,8 +216,8 @@ class AudioController { @objc private func handleRouteChange(notification: Notification) { guard let userInfo = notification.userInfo, - let reasonValue = userInfo[AVAudioSessionRouteChangeReasonKey] as? UInt, - let reason = AVAudioSession.RouteChangeReason(rawValue: reasonValue) else { + let reasonValue = userInfo[AVAudioSessionRouteChangeReasonKey] as? UInt, + let reason = AVAudioSession.RouteChangeReason(rawValue: reasonValue) else { return } diff --git a/firebaseai/LiveAudioExample/Audio/AudioPlayer.swift b/firebaseai/LiveAudioExample/Audio/AudioPlayer.swift index 281f3b8aa..069cd2a8e 100644 --- a/firebaseai/LiveAudioExample/Audio/AudioPlayer.swift +++ b/firebaseai/LiveAudioExample/Audio/AudioPlayer.swift @@ -60,7 +60,7 @@ class AudioPlayer { guard let inputBuffer = AVAudioPCMBuffer.fromInterleavedData( data: audio, - format: self.inputFormat + format: inputFormat ) else { fatalError("Failed to create input buffer for playback") } diff --git a/firebaseai/LiveAudioExample/Audio/Microphone.swift b/firebaseai/LiveAudioExample/Audio/Microphone.swift index 0764d390e..7d182bad6 100644 --- a/firebaseai/LiveAudioExample/Audio/Microphone.swift +++ b/firebaseai/LiveAudioExample/Audio/Microphone.swift @@ -31,8 +31,8 @@ class Microphone { self.audio = audio self.audioQueue = audioQueue - self.inputNode = engine.inputNode - self.audioEngine = engine + inputNode = engine.inputNode + audioEngine = engine } deinit { @@ -45,10 +45,11 @@ class Microphone { // 50ms buffer size for balancing latency and cpu overhead let targetBufferSize = UInt32(inputNode.outputFormat(forBus: 0).sampleRate / 20) - inputNode.installTap(onBus: 0, bufferSize: targetBufferSize, format: nil) { [weak self] buffer, _ in - guard let self else { return } - audioQueue.yield(buffer) - } + inputNode + .installTap(onBus: 0, bufferSize: targetBufferSize, format: nil) { [weak self] buffer, _ in + guard let self else { return } + audioQueue.yield(buffer) + } } public func stop() { diff --git a/firebaseai/LiveAudioExample/Screens/LiveAudioScreen.swift b/firebaseai/LiveAudioExample/Screens/LiveAudioScreen.swift index a12164a84..9cf8756aa 100644 --- a/firebaseai/LiveAudioExample/Screens/LiveAudioScreen.swift +++ b/firebaseai/LiveAudioExample/Screens/LiveAudioScreen.swift @@ -26,7 +26,8 @@ struct LiveAudioScreen: View { init(firebaseService: FirebaseAI, backend: BackendOption) { self.firebaseService = firebaseService - _viewModel = StateObject(wrappedValue: LiveViewModel(firebaseService: firebaseService, backend: backend)) + _viewModel = + StateObject(wrappedValue: LiveViewModel(firebaseService: firebaseService, backend: backend)) } var body: some View { @@ -38,7 +39,11 @@ struct LiveAudioScreen: View { if let error = viewModel.error { LiveErrorView(error: error) } - ConnectButton(state: viewModel.state, onConnect: viewModel.connect, onDisconnect: viewModel.disconnect) + ConnectButton( + state: viewModel.state, + onConnect: viewModel.connect, + onDisconnect: viewModel.disconnect + ) } .padding() .navigationTitle("Live Audio") @@ -46,7 +51,6 @@ struct LiveAudioScreen: View { } } - #Preview { LiveAudioScreen(firebaseService: FirebaseAI.firebaseAI(), backend: .googleAI) } diff --git a/firebaseai/LiveAudioExample/ViewModels/LiveViewModel.swift b/firebaseai/LiveAudioExample/ViewModels/LiveViewModel.swift index e5f511d54..3e70b55c9 100644 --- a/firebaseai/LiveAudioExample/ViewModels/LiveViewModel.swift +++ b/firebaseai/LiveAudioExample/ViewModels/LiveViewModel.swift @@ -17,7 +17,6 @@ import Foundation import OSLog import AVFoundation import SwiftUI -import AVFoundation import AVKit enum LiveViewModelState { @@ -71,11 +70,12 @@ class LiveViewModel: ObservableObject { name: "clearBackgroundColor", description: "Removes the background color.", parameters: [:] - ) + ), ]), ] ) } + /// Start a connection to the model. /// /// If a connection is already active, you'll need to call ``LiveViewModel/disconnect()`` first. @@ -93,8 +93,8 @@ class LiveViewModel: ObservableObject { transcriptViewModel.restart() do { - self.liveSession = try await model.connect() - self.audioController = try AudioController() + liveSession = try await model.connect() + audioController = try AudioController() try startRecording() @@ -169,14 +169,14 @@ class LiveViewModel: ObservableObject { private func processServerMessage(_ message: LiveServerMessage) async { switch message.payload { - case .content(let content): + case let .content(content): await processServerContent(content) - case .toolCall(let toolCall): + case let .toolCall(toolCall): await processFunctionCalls(functionCalls: toolCall.functionCalls ?? []) - case .toolCallCancellation(_): + case .toolCallCancellation: // we don't have any long running functions to cancel return - case .goingAwayNotice(let goingAwayNotice): + case let .goingAwayNotice(goingAwayNotice): let time = goingAwayNotice.timeLeft?.description ?? "soon" logger.warning("Going away in: \(time)") } @@ -219,9 +219,9 @@ class LiveViewModel: ObservableObject { let responses = functionCalls.map { functionCall in switch functionCall.name { case "changeBackgroundColor": - return changeBackgroundColor(args: functionCall.args, id: functionCall.functionId) + return changeBackgroundColor(args: functionCall.args, id: functionCall.functionId) case "clearBackgroundColor": - return clearBackgroundColor(id: functionCall.functionId) + return clearBackgroundColor(id: functionCall.functionId) default: logger.debug("Function call: \(String(describing: functionCall))") fatalError("Unknown function named \"\(functionCall.name)\".") @@ -256,7 +256,7 @@ class LiveViewModel: ObservableObject { ) } - private func clearBackgroundColor(id: String?) -> FunctionResponsePart { + private func clearBackgroundColor(id: String?) -> FunctionResponsePart { withAnimation { backgroundColor = nil } @@ -286,10 +286,10 @@ extension Color { g = CGFloat((rgb & 0x00FF00) >> 8) / 255.0 b = CGFloat(rgb & 0x0000FF) / 255.0 } else if hex.count == 8 { - r = CGFloat((rgb & 0xFF000000) >> 24) / 255.0 - g = CGFloat((rgb & 0x00FF0000) >> 16) / 255.0 - b = CGFloat((rgb & 0x0000FF00) >> 8) / 255.0 - a = CGFloat(rgb & 0x000000FF) / 255.0 + r = CGFloat((rgb & 0xFF00_0000) >> 24) / 255.0 + g = CGFloat((rgb & 0x00FF_0000) >> 16) / 255.0 + b = CGFloat((rgb & 0x0000_FF00) >> 8) / 255.0 + a = CGFloat(rgb & 0x0000_00FF) / 255.0 } else { return nil } diff --git a/firebaseai/LiveAudioExample/ViewModels/TranscriptViewModel.swift b/firebaseai/LiveAudioExample/ViewModels/TranscriptViewModel.swift index 04bed3f1e..1f443903d 100644 --- a/firebaseai/LiveAudioExample/ViewModels/TranscriptViewModel.swift +++ b/firebaseai/LiveAudioExample/ViewModels/TranscriptViewModel.swift @@ -34,7 +34,7 @@ class TranscriptViewModel: ObservableObject { var audioTranscripts: [TranscriptLine] = [] private var pendingText = [Character]() - private var processTextTask: Task? = nil + private var processTextTask: Task? init() { processTask() @@ -80,7 +80,7 @@ class TranscriptViewModel: ObservableObject { private func processNextCharacter() -> Int { guard !pendingText.isEmpty else { - return CharDelayMS // Default delay if no text is pending + return CharDelayMS // Default delay if no text is pending } let char = pendingText.removeFirst() @@ -102,7 +102,8 @@ class TranscriptViewModel: ObservableObject { /// punctuation; as this helps avoid weird situations where words are split across lines. /// /// - Returns: The MS delay before working on the next character in the queue. - private func determineNextDelayAndFinalize(for char: Character, in line: inout TranscriptLine) -> Int { + private func determineNextDelayAndFinalize(for char: Character, + in line: inout TranscriptLine) -> Int { if char.isWhitespace || char.isEndOfSentence { if line.message.count >= LineCharacterLength { line.isFinal = true @@ -123,7 +124,7 @@ class TranscriptViewModel: ObservableObject { if audioTranscripts.count > MaxLines { // fade out the removal; makes it less jumpy during rendering when lines are moved up withAnimation { - let _ = audioTranscripts.removeFirst() + _ = audioTranscripts.removeFirst() } } } diff --git a/firebaseai/LiveAudioExample/Views/ConnectButton.swift b/firebaseai/LiveAudioExample/Views/ConnectButton.swift index 8d446a544..48189ce36 100644 --- a/firebaseai/LiveAudioExample/Views/ConnectButton.swift +++ b/firebaseai/LiveAudioExample/Views/ConnectButton.swift @@ -16,8 +16,8 @@ import SwiftUI struct ConnectButton: View { var state: LiveViewModelState - var onConnect: () async -> () - var onDisconnect: () async -> () + var onConnect: () async -> Void + var onDisconnect: () async -> Void @State private var gradientAngle: Angle = .zero @@ -51,7 +51,7 @@ struct ConnectButton: View { switch state { case .connected: [] case .connecting: [.secondary, .white] - case .idle: [.red, .blue, .green, .yellow, .red] + case .idle: [.red, .blue, .green, .yellow, .red] } } diff --git a/firebaseai/LiveAudioExample/Views/LiveErrorDetailsView.swift b/firebaseai/LiveAudioExample/Views/LiveErrorDetailsView.swift index e492efd28..4f325d774 100644 --- a/firebaseai/LiveAudioExample/Views/LiveErrorDetailsView.swift +++ b/firebaseai/LiveAudioExample/Views/LiveErrorDetailsView.swift @@ -69,7 +69,7 @@ private extension Error { #Preview("Live error") { let cause = NSError(domain: "network.api", code: 1, userInfo: [ - NSLocalizedDescriptionKey: "Network timed out." + NSLocalizedDescriptionKey: "Network timed out.", ]) let error = LiveSessionLostConnectionError(underlyingError: cause) @@ -78,7 +78,7 @@ private extension Error { #Preview("Unexpected error") { let error = NSError(domain: "network.api", code: 1, userInfo: [ - NSLocalizedDescriptionKey: "Network timed out." + NSLocalizedDescriptionKey: "Network timed out.", ]) LiveErrorDetailsView(error: error) diff --git a/firebaseai/LiveAudioExample/Views/LiveErrorView.swift b/firebaseai/LiveAudioExample/Views/LiveErrorView.swift index f615c6c56..8e3aafaa2 100644 --- a/firebaseai/LiveAudioExample/Views/LiveErrorView.swift +++ b/firebaseai/LiveAudioExample/Views/LiveErrorView.swift @@ -36,7 +36,7 @@ struct LiveErrorView: View { #Preview { let cause = NSError(domain: "network.api", code: 1, userInfo: [ - NSLocalizedDescriptionKey: "Network timed out." + NSLocalizedDescriptionKey: "Network timed out.", ]) let error = LiveSessionLostConnectionError(underlyingError: cause) diff --git a/firebaseai/LiveAudioExample/Views/ModelPhoto.swift b/firebaseai/LiveAudioExample/Views/ModelPhoto.swift index 82f50f373..a2e8a427e 100644 --- a/firebaseai/LiveAudioExample/Views/ModelPhoto.swift +++ b/firebaseai/LiveAudioExample/Views/ModelPhoto.swift @@ -16,7 +16,7 @@ import SwiftUI struct ModelPhoto: View { var isConnected = false - + @State private var gradientAngle: Angle = .zero var colors: [Color] { diff --git a/firebaseai/LiveAudioExample/Views/TranscriptView.swift b/firebaseai/LiveAudioExample/Views/TranscriptView.swift index cb310053f..aa151586c 100644 --- a/firebaseai/LiveAudioExample/Views/TranscriptView.swift +++ b/firebaseai/LiveAudioExample/Views/TranscriptView.swift @@ -33,7 +33,10 @@ struct TranscriptView: View { #Preview { let vm = TranscriptViewModel() - TranscriptView(vm: vm).onAppear() { - vm.appendTranscript("The sky is blue primarily because of a phenomenon called Rayleigh scattering, where tiny molecules of gas (mainly nitrogen and oxygen) in Earth's atmosphere scatter sunlight in all directions.") + TranscriptView(vm: vm).onAppear { + vm + .appendTranscript( + "The sky is blue primarily because of a phenomenon called Rayleigh scattering, where tiny molecules of gas (mainly nitrogen and oxygen) in Earth's atmosphere scatter sunlight in all directions." + ) } } From 9b818ff52b8de064ecec0f1313d3a020c8357f99 Mon Sep 17 00:00:00 2001 From: Daymon Date: Tue, 7 Oct 2025 18:06:58 -0500 Subject: [PATCH 06/10] Fix typo --- .../LiveAudioExample/ViewModels/TranscriptViewModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firebaseai/LiveAudioExample/ViewModels/TranscriptViewModel.swift b/firebaseai/LiveAudioExample/ViewModels/TranscriptViewModel.swift index 1f443903d..c256b5249 100644 --- a/firebaseai/LiveAudioExample/ViewModels/TranscriptViewModel.swift +++ b/firebaseai/LiveAudioExample/ViewModels/TranscriptViewModel.swift @@ -20,7 +20,7 @@ private let CharDelayMS = 65 /// The intended amount of characters in a line. /// -/// Can exceed this if the line doesn't end in a space of punctuation. +/// Can exceed this if the line doesn't end in a space or punctuation. private let LineCharacterLength = 20 /// The max amount of lines to hold references for at a time. From 8d53bad6e410bb919af6e0b1edfd446a30180aa8 Mon Sep 17 00:00:00 2001 From: Daymon Date: Tue, 7 Oct 2025 18:08:05 -0500 Subject: [PATCH 07/10] Add docs for extension property --- .../LiveAudioExample/ViewModels/TranscriptViewModel.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/firebaseai/LiveAudioExample/ViewModels/TranscriptViewModel.swift b/firebaseai/LiveAudioExample/ViewModels/TranscriptViewModel.swift index c256b5249..4b4c81214 100644 --- a/firebaseai/LiveAudioExample/ViewModels/TranscriptViewModel.swift +++ b/firebaseai/LiveAudioExample/ViewModels/TranscriptViewModel.swift @@ -141,6 +141,9 @@ class TranscriptViewModel: ObservableObject { } extension Character { + /// Marker for punctuation that dictates the end of a sentence. + /// + /// Namely, this checks for `.`, `!` and `?`. var isEndOfSentence: Bool { self == "." || self == "!" || self == "?" } From 74a73496bf19503ba3ecc4a1348da7d96be11597 Mon Sep 17 00:00:00 2001 From: Daymon Date: Wed, 8 Oct 2025 10:43:27 -0500 Subject: [PATCH 08/10] Remove app check import --- firebaseai/FirebaseAIExample/FirebaseAIExampleApp.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/firebaseai/FirebaseAIExample/FirebaseAIExampleApp.swift b/firebaseai/FirebaseAIExample/FirebaseAIExampleApp.swift index 1d4be15bd..e1714ce4d 100644 --- a/firebaseai/FirebaseAIExample/FirebaseAIExampleApp.swift +++ b/firebaseai/FirebaseAIExample/FirebaseAIExampleApp.swift @@ -13,7 +13,6 @@ // limitations under the License. import FirebaseCore -import FirebaseAppCheck import SwiftUI class AppDelegate: NSObject, UIApplicationDelegate { From 4bdeea4e9243081118e484b3f0c4125587cadc2e Mon Sep 17 00:00:00 2001 From: Daymon Date: Wed, 8 Oct 2025 10:49:34 -0500 Subject: [PATCH 09/10] Make int16Data not nullable --- firebaseai/LiveAudioExample/Audio/AudioBufferHelpers.swift | 2 +- firebaseai/LiveAudioExample/ViewModels/LiveViewModel.swift | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/firebaseai/LiveAudioExample/Audio/AudioBufferHelpers.swift b/firebaseai/LiveAudioExample/Audio/AudioBufferHelpers.swift index 3f02c8678..e61d6512c 100644 --- a/firebaseai/LiveAudioExample/Audio/AudioBufferHelpers.swift +++ b/firebaseai/LiveAudioExample/Audio/AudioBufferHelpers.swift @@ -42,7 +42,7 @@ extension AVAudioPCMBuffer { /// Gets the underlying `Data` in this buffer. /// /// Will throw an error if this buffer doesn't hold int16 data. - func int16Data() -> Data? { + func int16Data() -> Data { guard let bufferPtr = audioBufferList.pointee.mBuffers.mData else { fatalError("Missing audio buffer list") } diff --git a/firebaseai/LiveAudioExample/ViewModels/LiveViewModel.swift b/firebaseai/LiveAudioExample/ViewModels/LiveViewModel.swift index 3e70b55c9..4051077bb 100644 --- a/firebaseai/LiveAudioExample/ViewModels/LiveViewModel.swift +++ b/firebaseai/LiveAudioExample/ViewModels/LiveViewModel.swift @@ -130,11 +130,7 @@ class LiveViewModel: ObservableObject { let stream = try audioController.listenToMic() microphoneTask = Task { for await audioBuffer in stream { - guard let data = audioBuffer.int16Data() else { - logger.error("Failed to convert audio buffer to int16 Data.") - continue - } - await liveSession.sendAudioRealtime(data) + await liveSession.sendAudioRealtime(audioBuffer.int16Data()) } } } From 7a2e3eacbfb56e3c987e45f272376f8724b0ebfe Mon Sep 17 00:00:00 2001 From: Daymon Date: Wed, 8 Oct 2025 11:04:46 -0500 Subject: [PATCH 10/10] Make audio controller an actor --- .../Audio/AudioController.swift | 47 +++++++++++++------ .../ViewModels/LiveViewModel.swift | 14 +++--- 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/firebaseai/LiveAudioExample/Audio/AudioController.swift b/firebaseai/LiveAudioExample/Audio/AudioController.swift index b6baaccd8..27ebec979 100644 --- a/firebaseai/LiveAudioExample/Audio/AudioController.swift +++ b/firebaseai/LiveAudioExample/Audio/AudioController.swift @@ -15,7 +15,7 @@ import AVFoundation /// Controls audio playback and recording. -class AudioController { +actor AudioController { /// Data processed from the microphone. private let microphoneData: AsyncStream private let microphoneDataQueue: AsyncStream.Continuation @@ -23,6 +23,7 @@ class AudioController { private var audioEngine: AVAudioEngine? private var microphone: Microphone? private var listenTask: Task? + private var routeTask: Task? /// Port types that are considered "headphones" for our use-case. /// @@ -40,7 +41,7 @@ class AudioController { private var stopped = false - public init() throws { + public init() async throws { let session = AVAudioSession.sharedInstance() try session.setCategory( .playAndRecord, @@ -80,7 +81,25 @@ class AudioController { } deinit { - stop() + stopped = true + listenTask?.cancel() + // audio engine needs to be stopped before disconnecting nodes + audioEngine?.pause() + audioEngine?.stop() + if let audioEngine { + do { + // the VP IO leaves behind artifacts, so we need to disable it to properly clean up + if audioEngine.inputNode.isVoiceProcessingEnabled { + try audioEngine.inputNode.setVoiceProcessingEnabled(false) + } + } catch { + print("Failed to disable voice processing: \(error.localizedDescription)") + } + } + microphone?.stop() + audioPlayer?.stop() + microphoneDataQueue.finish() + routeTask?.cancel() } /// Kicks off audio processing, and returns a stream of recorded microphone audio data. @@ -96,11 +115,7 @@ class AudioController { stopped = true stopListeningAndPlayback() microphoneDataQueue.finish() - NotificationCenter.default.removeObserver( - self, - name: AVAudioSession.routeChangeNotification, - object: nil - ) + routeTask?.cancel() } /// Queues audio for playback. @@ -206,15 +221,17 @@ class AudioController { /// When the output device changes, ensure the audio playback and recording classes are properly restarted. private func listenForRouteChange() { - NotificationCenter.default.addObserver( - self, - selector: #selector(handleRouteChange), - name: AVAudioSession.routeChangeNotification, - object: nil - ) + routeTask?.cancel() + routeTask = Task { [weak self] in + for await notification in NotificationCenter.default.notifications( + named: AVAudioSession.routeChangeNotification + ) { + await self?.handleRouteChange(notification: notification) + } + } } - @objc private func handleRouteChange(notification: Notification) { + private func handleRouteChange(notification: Notification) { guard let userInfo = notification.userInfo, let reasonValue = userInfo[AVAudioSessionRouteChangeReasonKey] as? UInt, let reason = AVAudioSession.RouteChangeReason(rawValue: reasonValue) else { diff --git a/firebaseai/LiveAudioExample/ViewModels/LiveViewModel.swift b/firebaseai/LiveAudioExample/ViewModels/LiveViewModel.swift index 4051077bb..84ed1802f 100644 --- a/firebaseai/LiveAudioExample/ViewModels/LiveViewModel.swift +++ b/firebaseai/LiveAudioExample/ViewModels/LiveViewModel.swift @@ -94,9 +94,9 @@ class LiveViewModel: ObservableObject { do { liveSession = try await model.connect() - audioController = try AudioController() + audioController = try await AudioController() - try startRecording() + try await startRecording() state = .connected try await startProcessingResponses() @@ -111,7 +111,7 @@ class LiveViewModel: ObservableObject { /// /// Will stop any pending playback, and the recording of the mic. func disconnect() async { - audioController?.stop() + await audioController?.stop() await liveSession?.close() microphoneTask.cancel() state = .idle @@ -124,10 +124,10 @@ class LiveViewModel: ObservableObject { } /// Starts recording data from the user's microphone, and sends it to the model. - private func startRecording() throws { + private func startRecording() async throws { guard let audioController, let liveSession else { return } - let stream = try audioController.listenToMic() + let stream = try await audioController.listenToMic() microphoneTask = Task { for await audioBuffer in stream { await liveSession.sendAudioRealtime(audioBuffer.int16Data()) @@ -190,7 +190,7 @@ class LiveViewModel: ObservableObject { if content.wasInterrupted { logger.warning("Model was interrupted") - audioController?.interrupt() + await audioController?.interrupt() transcriptViewModel.clearPending() // adds an em dash to indiciate that the model was cutoff transcriptViewModel.appendTranscript("— ") @@ -203,7 +203,7 @@ class LiveViewModel: ObservableObject { for part in content.parts { if let part = part as? InlineDataPart { if part.mimeType.starts(with: "audio/pcm") { - audioController?.playAudio(audio: part.data) + await audioController?.playAudio(audio: part.data) } else { logger.warning("Received non audio inline data part: \(part.mimeType)") }