Description
As of iOS 18, AVAudioSession.setPreferredIOBufferDuration ignores the requested buffer size when Sound Recognition or Vocal Shortcuts is enabled. This results in 1) much larger buffer sizes and 2) mismatched buffer sizes between input and output buffers, which causes ‘glitchy’ audio and increased latency.
Additionally, when this issue occurs AVAudioSession.setPreferredIOBufferDuration continues to return ‘true’ and no error is produced.
Steps to Reproduce:
Enable Vocal Shortcuts on a device running iOS 18. Enable at least one shortcut (e.g. Control Center).
Open or clone the example project (https://github.com/cwalo/SoundRecognitionBug)
Build and install the example project
Attach a headset and launch the application
Observe console logs showing
a requested buffer size of 0.005805 (256 samples @ 48k)
an actual buffer size of 0.023220 (1104 samples @48k - this is regularly the resulting buffer size in all of our tests)
Quit the app and detach the headset. Enable mutesOutput in AudioSystem.mm (to avoid feedback)
Launch the application
Observe
Same result from step 4
Mismatched hardware buffer size of 1104 and recorded frame count of 1024
Mismatched playbackCount and recordCount
Quit the app and disable vocal shortcuts
Launch the app
Observe IOBufferDuration matching the requested duration and matched buffer sizes (expected behavior)
Expected results:
Requested IOBufferDuration is respected or AVAudioSession returns false or error is produced
Input and output buffer sizes match
Device(s): iPhone 11 Pro, iPad Pro
OS: iOS 18.0.1
Environment: Xcode 16.1
FB: FB15715421
Related to: https://forums.developer.apple.com/forums/thread/765477
Audio
RSS for tagIntegrate music and other audio content into your apps.
Posts under Audio tag
80 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
I’m working on a memo app that records audio from the iPhone’s microphone (and other devices like MacBook or iPad) and processes it in 10-second chunks at a target sample rate of 16 kHz. However, I’ve encountered limitations with installTap in AVAudioEngine, which doesn’t natively support configuring a target sample rate on the mic input (the default being 44.1 kHz).
To address this, I tried using AVAudioMixerNode to downsample the mic input directly. Although everything seems correctly configured, no audio is recorded—just a flat signal with zero levels. There are no errors, and all permissions are granted, so it seems like an issue with downsampling rather than the mic setup itself.
To make progress, I implemented a workaround by tapping and resampling each chunk tapped using installTap (every 50ms in my case) with AVAudioConverter. While this works, it can introduce artifacts at the beginning and end of each chunk, likely due to separate processing instead of continuous downsampling.
Here are the key issues and questions I have:
1. Can we change the mic input sample rate directly using AVAudioSession or another native API in AVAudio? Setting up the desired sample rate initially would be ideal for my use case.
2. Are there alternatives to installTap for recording audio at a different sample rate or for continuously downsampling the live input without chunk-based artifacts?
This issue seems longstanding, as noted in a 2018 forum post:
https://forums.developer.apple.com/forums/thread/111726
Any guidance on configuring or processing mic input at a lower sample rate in real-time would be greatly appreciated. Thank you!
Hi, I'm facing an issuer with audio worklet in safari. This issue is clearly an iOS bug (it doesn't occur on iPad or Mac)
Here's the minimal reproduction:
Go to https://googlechromelabs.github.io/web-audio-samples/audio-worklet/basic/hello-audio-worklet/
Press start
Audio will not be playing
Open YouTube on another tab and start any video
Audio from the worklet will start playing
Is this a known issue? Any plans to address that? Any workaround available?
Has anyone else noticed that there are two different volume levels now ?
When I call for an advisor, the IVR (AI introduction sounds fine.
When the advisor or any other call speaks, i'ts so low I have to put it to my ear.
Hello, I've been working to implement PTT in the way recommended by the documentation. The main issue is that the bluetooth methods are opaque, so I cannot solve for what I need. The result will be that I will have to resort to hacky approaches that the PTT framework seems to be intended to solve (playing silent clips, playing custom notification sounds, having long running background audio sessions).
I am testing with Anker soundcore mini as well as airpod pro.
Here's the issue: there are 2 very different behaviours depending on whether I'm using a call/fullDuplex session and a halfDuplex session.
halfDuplex
Anchor mini
Current behaviour
long press activates siri
pressing again after siri is active, starts transmission
long press activates siri again
pressing again after siri is active, stops transmission
pause/play routes to the ongoing media session and plays music
Expected behaviour
play/pause should map to transmit/stopTransmit
IF I have to use long press, it should at least not trigger siri
AirPod pro
Current behaviour
long press changes noise cancellation
pause/play routes to the ongoing media session and plays music
Expected behaviour
play/pause should map to transmit/stopTransmit
fullDuplex/call
Anchor mini:
Current behaviour
long press activates siri
pressing again after siri is active, starts transmission
long press activates siri again
pressing again after siri is active, stops transmission
pause/play routes to the ongoing media session and plays music
Expected behaviour
play/pause should map to transmit/stopTransmit
IF I have to use long press, it should at least not trigger siri
AirPod pro
Current behaviour
long press changes noise cancellation
pause/play maps to mute/unmute (even if media is playing)
Expected behaviour
This makes sense for call behaviour, I wish it worked this well for PTT
The intention here is to be able to fully interact with a channel hands-free. The current API seems to make that impossible. Is that by design? Reading all the docs seems to suggest its intended for transmit/stopTransmit to be doable just with the play/pause buttons, but even apple hardware seems to not support that.
Hey,
I am fairly new to working with AVFoundation etc. As far as I could research on my own, if I want to get metadata from let's say a .m4a audio file, I have to get the data and then create an AVAsset. My files are all on local servers and therefore I would not be able to just pass in the URL.
The extraction of the metadata works fine - however those AVAssets create a huge overhead in storage consumption. To my knowledge the data instances of each audio file and AVAsset should only live inside the function I call to extract the metadata, however those data/AVAsset instances still live on on storage as I can clearly see that the app's file size increases by multiple Gigabytes (equal to the library size I test with). However, the only data that I purposefully save with SwiftData is the album artwork.
Is this normal behavior for AVAssets or am I missing some detail?
PS. If I forgot to mention something important, please ask. This is my first ever post, so I'm not too sure what is worth mentioning.
Thank you in advance!
Denis
Hello,
I am setting up macMinis as CI machines (using gitlab-runner) for my team. We are developing mostly audio stuff, and some of our unit tests imply using audio inputs with AVAudioSession/AVAudioEngine.
These CI jobs trigger a microphone authorization pop-up on the macMinis, asking for permission to give gitlab-runner access to the microphone. Once the authorization is given, subsequent jobs run fine.
My issue is that the macMinis are updated on a regular basis with scripts, and since the path of the gitlab-runner binary, installed with homebrew, changes on every version, the pop-up is triggered again every time gitlab-runner gets updated.
Since we are having more and more CI runners, maintaining this manually is becoming impossible.
Is there a way to either deactivate this security or scripting the authorization for a binary to access the microphone?
Thank you for your help!
Tom
Hello.
We are trying to get audio volume from microphone.
We have 2 questions.
1. Can anyone tell me about AVAudioEngine.InputNode.volume?
AVAudioEngine.InputNode.volume
Return 0 in the silence, Return float type value within 1.0 depending on the
volume are expected work, but it looks 1.0 (default value) is returned at any time.
Which case does it return 0.5 or 0?
Sample code is below. Microphone works correctly.
// instance member
private var engine: AVAudioEngine!
private var node: AVAudioInputNode!
// start method
self.engine = .init()
self.node = engine.inputNode
engine.prepare()
try! engine.start()
// volume getter
print(\(self.node.volume))
2. What is the best practice to get audio volume from microphone?
Requirements are:
Without AVAudioRecorder. We use it for streaming audio.
it should withstand high frequency access.
Testing info
device: iPhone XR
OS version: iOS 18
Best Regards.
The new iPhone 16 supports spatial audio recordings in the camera app when recording videos. Is it possible to also record spatial audio without video, and is it possible for 3rd party developers to do so? If so, how do I need to configure AVAudioSession and/or AVAudioEngine to record spatial audio in my audio recording app on iPhone 16?
Technical Issue Report for Maple Tale App - Audio Format Compatibility
Dear Apple Technical Support Team,
I hope this message finds you well. My name is [Your Name], and I am part of the development team behind the Maple Tale app. We have encountered an issue with audio format compatibility within our app that we believe requires your assistance.
The issue pertains to the audio formats supported by our app. Currently, our app only supports WAV and OGG formats, which has led to a limitation in user experience. We are looking to expand our support to include additional formats such as MP3 and AAC, which are widely used by our user base.
To provide a clear understanding of the issue, I have outlined the steps to reproduce the problem:
Launch the Maple Tale app.
Proceed with the game normally.
Upon picking up equipment within the game, a warning box pops up indicating the audio format compatibility issue.
This warning box appears due to the app's inability to process audio files in formats other than WAV and OGG. We understand that this can be a significant hindrance to the user experience, and we are eager to resolve this as quickly as possible.
We have reviewed the documentation available on the official Apple Developer website but are still seeking clarification on the best practices for supporting a wider range of audio formats within our app. We would greatly appreciate any official recommendations or guidelines that could assist us in this endeavor.
Additionally, we are considering updating our app to inform users about the current audio format requirements and provide guidance on how to optimize their audio files for the best performance within our app. If there are any official documents or resources that we should reference when crafting this update, please let us know.
We appreciate your time and assistance in this matter and look forward to your guidance on how to best implement audio format support on the iOS platform.
Thank you once again for your support.
Warm regards,
I'm seeking information about the original file schema for an m4a file recorded directly on an iPhone (iPhone 5 running iOS 9.2.0).
I currently have two files from which I extracted metadata using ExifTool.
The first file was provided to me by someone who claims it was recorded on an iPhone 5 with iOS 9.2.0. I would like to verify whether this file has been edited.
File Permissions: -rwx------
Content Create Date: 2016:03:01 14:21:08+07:00
The second file was recorded by me on the same device model and iOS version.
File Permissions: -rw-r--r--
Date/Time Original: 2024:10:03 11:44:16+07:00
As you can see, the file permissions differ, and the key for the recording date also differs: one uses "Content Create Date" while the other uses "Date/Time Original." I would like to determine if the first file was edited, but I haven't been able to find any official documentation on the m4a schema or metadata structure from audio recorder apps. I reached out to support, and they directed me to this forum. Any insights or help would be appreciated.
Can it please be explained why the voice memo layers is exclusive to iPhone 16 pro models?
I was told by apple support that if it was possible on older models Apple would have implemented it.
This type of functionality has been in technology for tens of years and has a proven track record of being implemented across so many different platforms and even apps in Apples on App Store. So that response from apple support is just rubbish to be honest. Even if the response is “so we can sell the iPhone 16 pro“ then so be it. ive noticed Apple locking software features to new devices lately and it’s genuinely making me think about buying my first even android phone.. because I really don’t support these kind of scummy tactics.
many thanks,
I’m working on a macOS app, written in Swift. My goal is to record audio from an external microphone, e.g., one connected via USB.
For this, I’m using an AVCaptureSession and recording its output with an AVAssetWriter. This works perfectly in principle (and reliably with internal microphones, for example).
The problem occurs after my app has successfully completed the first recording and I then want to make additional recordings (which makes me think it might be process-dependent, because it works again after restarting the app).
The problem: Noisy or distorted-sounding audio files. In addition, the following error message appears in the Console from CoreAudio / its AudioConverter:
Input data proc returned inconsistent 512 packets for 2048 bytes; at 3 bytes per packet, that is actually 682 packets
It is easy to reproduce. This problem is reproducible even if I don’t configure the AVAssetWriter manually and instead let it receive its audioSettings using a preset from an AVOutputSettingsAssistant. I’m running on macOS 15.0 (24A335).
I’ve filed a feedback including a demo project → FB15333298 🎟️
I would greatly appreciate any help!
Have a great day,
Martin
Hi, I've recently been working with the Apple Music API and have had success in loading all the playlists on my account, loading songs from each playlist, and adding songs to the ApplicationMusicPlayer.share.queue. The problem I'm running into is that not all songs from the playlist are being added to the queue, despite confirming all the songs are being based on the PlaybackView.swift I'm about to share with you. I would also like to answer other underlying questions if possible. I am also open to any other suggestions. In this scenario were also assuming isShuffled is true every time.
How can I determine when a song has ended?
How can I get the album title information?
How can I get the current song title, album information, and artist information without pressing play? I can only seem to update the screen when I select my play meaning ApplicationMusicPlayer.shared.play() is being called.
How do I get the endTime of the song? I believe it should be ApplicationMusicPlayer.shared.queue.currentEntry.endTime but this doesn't seem to work.
//
// PlayBackView.swift
//
// Created by Justin on 8/16/24.
//
import SwiftUI
import MusicKit
import Foundation
enum PlayState {
case play
case pause
}
struct PlayBackView: View {
@State var song: Track
@Binding var songs: [Track]?
@State var isShuffled = false
@State private var playState: PlayState = .pause
@State private var isFirstPlay = true
private let player = ApplicationMusicPlayer.shared
private var isPlaying: Bool {
return (player.state.playbackStatus == .playing)
}
var body: some View {
VStack {
// Album Cover
HStack(spacing: 20) {
if let artwork = player.queue.currentEntry?.artwork {
ArtworkImage(artwork, height: 100)
} else {
Image(systemName: "music.note")
.resizable()
.frame(width: 100, height: 100)
}
VStack(alignment: .leading) {
// Song Title
Text(player.queue.currentEntry?.title ?? "Song Title Not Found")
.font(.title)
.fixedSize(horizontal: false, vertical: true)
// How do I get AlbumTitle from here??
// Artist Name
Text(player.queue.currentEntry?.subtitle ?? "Artist Name Not Found")
.font(.caption)
}
}
.padding()
Spacer()
// Progress View
// endTime doesn't work and not sure why.
ProgressView(value: player.playbackTime, total: player.queue.currentEntry?.endTime ?? 1.00)
.progressViewStyle(.linear)
.tint(.red.opacity(0.5))
// Duration View
HStack {
Text(durationStr(from: player.playbackTime))
.font(.caption)
Spacer()
if let duration = player.queue.currentEntry?.endTime {
Text(durationStr(from: duration))
.font(.caption)
}
}
Spacer()
Button {
Task {
do {
try await player.skipToNextEntry()
} catch {
print(error.localizedDescription)
}
}
} label: {
Label("", systemImage: "forward.fill")
.tint(.white)
}
Spacer()
// Play/Pause Button
Button(action: {
handlePlayButton()
isFirstPlay = false
}, label: {
Text(playState == .play ? "Pause" : isFirstPlay ? "Play" : "Resume")
.frame(maxWidth: .infinity)
})
.buttonStyle(.borderedProminent)
.padding()
.font(.largeTitle)
.tint(.red)
}
.padding()
.onAppear {
if isShuffled {
songs = songs?.shuffled()
if let songs, let firstSong = songs.first {
player.queue = .init(for: songs, startingAt: firstSong)
player.state.shuffleMode = .songs
}
}
}
.onDisappear {
player.stop()
player.queue = []
player.playbackTime = .zero
}
}
private func handlePlayButton() {
Task {
if isPlaying {
player.pause()
playState = .pause
} else {
playState = .play
await playTrack()
}
}
}
@MainActor
private func playTrack() async {
do {
try await player.play()
} catch {
print(error.localizedDescription)
}
}
private func durationStr(from duration: TimeInterval) -> String {
let seconds = Int(duration)
let minutes = seconds / 60
let remainder = seconds % 60
// Format the string to ensure two digits for the remainder (seconds)
return String(format: "%d:%02d", minutes, remainder)
}
}
//#Preview {
// PlayBackView()
//}
Since the iOS 18 update, there's been a bug that always occurs when listening to music through Apple Music. When music is playing and the iPhone enters or exits standby mode, the music pauses by itself for 1 second. The initial conditions were the same as when this problem didn’t exist.
Dear Developers,
Am facing this issue on my production app.
Tried everything. Removed almost everything and tested the app. Even then this issue happens.
The unity games, am talking about are the slow and sluggish types, which feel like 30 fps and after returning from them, my app sounds slow and feels a little bit sluggish. As soon as i lock/unlock the device , it becomes perfectly fine.
Even i was debugging with xcode, i had the issue, then i rebuild the app in xcode and opening it on device, the same issue. As soon as i locked the device or opened siri with lockbutton or moved to a native app, and came back, app is completely fine.
Craziest issue, i have ever seen.
Though killing the app and opening it again on iphone also works.
Only anxiety is that maybe my users when returning from other slow 3rd party games which are my competitors might slow down the experience.
I have tried almost everything in my app, removed all functions and just ran sounds. Retried with different ways of playing sounds. Nothing works.
Dont know it is a frame rate issue, because i replaced all my animations causing framerate not to cross 60fps even then didnt work.
Device on which am testing is Iphone 14 pro max.
since updating to the newest ios 18 beta last night, my Audio is glitching out, like it is having connection problems while I’m sitting on my bed, with my phone 2 feet away from the AirPods. It sounds like a phone call breaking up when I am listening to music, or watching a video. I have restarted my phone several times, and it has not fixed it, and I have forgotten my AirPods, and reconnected the AirPods after.
I have a recent post kind of outlining a similar question here. This time though I'm confident that inserting an array of Track works when inserting into the ApplicationMusicPlayer.shared.queue but now I'm not sure how I can initialize the queue to display song title and artwork for example. I'm also not sure how to get the current item in the queue's artist information and album information which I feel should be easy to do so maybe I'm missing something obvious. Hope this paints of what I'm trying to do and I'm going to post the neccessary code here to help me debug/figure out this problem.
import SwiftUI
import MusicKit
struct PlayBackView: View {
@Environment(\.scenePhase) var scenePhase
@Environment(\.openURL) private var openURL
// Adding Enum Here for Question Sake
enum PlayState {
case play
case pause
}
@State var song: Track
@Binding var songs: [Track]?
@State var isShuffled = false
@State private var playState: PlayState = .pause
@State private var songTimer: Int = Int.random(in: 5...30)
@State private var roundTimer: Int = 5
@State private var isTimerActive = false
// @State private var volumeValue = VolumeObserver()
@State private var isFirstPlay = true
@State private var isDancing = false
@State private var player = ApplicationMusicPlayer.shared
private var isPlaying: Bool {
return (player.state.playbackStatus == .playing)
}
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
var playPauseImage: String {
switch playState {
case .play:
"pause.fill"
case .pause:
"play.fill"
}
}
var body: some View {
VStack {
// Album Cover
HStack(spacing: 20) {
if let artwork = player.queue.currentEntry?.artwork {
ArtworkImage(artwork, height: 100)
} else {
Image(systemName: "music.note")
.resizable()
.frame(width: 100, height: 100)
}
VStack(alignment: .leading) {
/*
This is where I want to display song title, album title, and artist name for example
*/
// Song Title
Text(player.queue.currentEntry?.title ?? "Unable to Find Song Title")
.font(.title)
.fixedSize(horizontal: false, vertical: true)
// Album Title
// Text(player.queue.currentEntry ?? "Album Title Not Found")
// .font(.caption)
// .fixedSize(horizontal: false, vertical: true)
// I don't know what the subtitle actually grabs
Text(player.queue.currentEntry?.subtitle ?? "Artist Name Not Found")
.font(.caption)
}
}
.padding()
// Play/Pause Button
Button(action: {
handlePlayButton()
isFirstPlay = false
}, label: {
Text(playState == .play ? "Pause" : isFirstPlay ? "Play" : "Resume")
.frame(maxWidth: .infinity)
})
.buttonStyle(.borderedProminent)
.padding()
.font(.largeTitle)
.tint(.red)
}
.padding()
// Maybe I should use the `.task` modifier here?
.onAppear {
// I'm sure this code could be improved but don't think it'll help answer the question at the moment.
Task {
if let songs = songs {
do {
if isShuffled {
let shuffledSongs = songs.shuffled()
try await player.queue.insert(shuffledSongs, position: .tail)
handlePlayButton()
} else {
try await player.queue.insert(songs, position: .tail)
}
} catch {
print(error.localizedDescription)
}
}
}
}
}
private func handlePlayButton() {
Task {
if isPlaying {
player.pause()
playState = .pause
isTimerActive = false
} else {
playState = .play
await playTrack()
isTimerActive = true
}
}
}
@MainActor
private func playTrack() async {
do {
try await player.play()
} catch {
print(error.localizedDescription)
}
}
}
//#Preview {
// PlayBackView()
//}
After upgrading to iOS 18 CarPlay with 2023 Lexus and iPhone 15 Pro Max shows multiple issues:
• speakers reduced to Mono sound (going back to normal after some minutes and then reducing again)
• no speaker sound at all
• touching / moving phone while driving resulting in “on and off” sound
No Reboot / Shutdown helps
No Cable connection works
@Apple: do you test your software professionally or is this outsourced to the community? Doesn’t look at all like a professional approach?
Please solve this dangerous (traffic!) and annoying topic ASAP!
Thanks - Torsten
Hi. I am developing an alarm app. My app plays white noise to help users get into sleep properly. To keep white noise playing in the background, my app uses audio background mode. The problem is that my app sometimes gets suspended few hours after getting into background. I cannot find the exact reason for it.
Doesn't audio background guarantee that app is not suspended by system? Then how can I handle this issue so that my app can keep white noise playing feature?