Posts

Post not yet marked as solved
3 Replies
2.3k Views
Good day to everyone.For the past 3 weeks, I've been trying to resolve issues I'm having with Equalizing a simple Audio Stream on macOS through Bluetooth.The setup is basically this:Player -> EQ Unit -> Mixer -> Bluetooth Audio DeviceWhenever I use a wired audio device (HDMI, Internal Speaker, 3.5mm Jack etc.) everything works brilliantly.If I try and use a Bluetooth device (tried many, cheap and super expensive headphones) at first glance everything works fine, but when you start to increase the gain on the Bands, the resulting Audio becomes very distorted. On a wired connection with the same gain values, everything works great and the gain increases properly and sounds great.At first, I thought it's something to do with Sampling Rate, but after playing around with it for a while I can it's definitely not the problem.I have assembled a quick example in a Swift Playground that anyone can try out (you will need to add a track.mp3 file to the Playground resources):import Cocoa import AVFoundation func getCurrentOutputDeviceId () -> AudioDeviceID { var addr = AudioObjectPropertyAddress( mSelector: kAudioHardwarePropertyDefaultOutputDevice, mScope: kAudioObjectPropertyScopeGlobal, mElement: kAudioObjectPropertyElementMaster) var id: AudioObjectID = kAudioDeviceUnknown var size = UInt32(MemoryLayout.size(ofValue: id)) AudioObjectGetPropertyData( AudioObjectID(kAudioObjectSystemObject), &addr, 0, nil, &size, &id ) return id } let engine = AVAudioEngine() // File let path = Bundle.main.path(forResource: "track", ofType: "mp3")! let url = URL(fileURLWithPath: path) let file = try! AVAudioFile(forReading: url) let fileFormat = file.processingFormat let frameCount = UInt32(file.length) let buffer = AVAudioPCMBuffer(pcmFormat: fileFormat, frameCapacity: frameCount)! try! file.read(into: buffer, frameCount: frameCount) let player = AVAudioPlayerNode() let eq = AVAudioUnitEQ(numberOfBands: 3) eq.globalGain = 0 eq.bypass = false let gain = Float32(23.0) let band1 = eq.bands[0] band1.filterType = .parametric band1.bandwidth = 0.5 band1.gain = gain band1.frequency = 32.0 band1.bypass = false let band2 = eq.bands[1] band2.filterType = .parametric band2.bandwidth = 0.5 band2.gain = gain band2.frequency = 64.0 band2.bypass = false let band3 = eq.bands[2] band3.filterType = .parametric band3.bandwidth = 0.5 band3.gain = gain band3.frequency = 125.0 band3.bypass = false var converter = AVAudioMixerNode() // Why do I have to do this to force playback through an already selected device? // I don't need to do this on Non Bluetooth Devices. // Also sometimes works if you switch to internal Microphone rather than the Bluetooth Device Mic in System Preferences try! engine.outputNode.auAudioUnit.setDeviceID(getCurrentOutputDeviceId()) let deviceFormat = engine.outputNode.outputFormat(forBus: 0) engine.attach(player) engine.attach(eq) engine.attach(converter) engine.connect(player, to: eq, format: fileFormat) engine.connect(eq, to:converter, format: fileFormat) engine.connect(converter, to: engine.mainMixerNode, format: deviceFormat) engine.prepare() try! engine.start() print(engine) player.play() player.scheduleBuffer(buffer, at: AVAudioTime(hostTime: 0), options:.loops, completionHandler: nil)Please try it on a Wired vs. Wireless device and you will instantly see the difference.A couple of things I've noticed along my painful debugging process:1. Look at lines 66-69, I only have to do this when using a Bluetooth device, otherwise, there is a microphone feedback loop for half a second and no Sound after that.2. If I go to System Preferences -> Sound and switch to the Input Tab, whenever I have my Bluetooth headphones selected I can head a Microphone feedback loop (only when the same Bluetooth device Microphone Input is selected) My setup:macOS 10.14 (18A391)Xcode 10.1 (10B61)macOS SDK 10.14I'm trying to rewrite my https://github.com/nodeful/eqMac2 app to Swift and AVAudioEngine, as AUGraph is being deprecated (I heard?).This bug is holding me back big time, would love to get this resolved. Kind Regards,Roman
Posted Last updated
.