AudioKit v5 输出问题,使用 AVAudioSession defaultToSpeaker 时没有声音
AudioKit v5 output problems, no sound when AVAudioSession defaultToSpeaker is used
编辑#2:好的,我在这里漏掉了一些重要的东西,但我仍然有一个问题。声音柔和而我必须放大它的原因是它来自听筒,而不是扬声器。当我将选项 .defaultToSpeaker 添加到 setCategory 时,我根本听不到任何声音。
所以,这才是真正的问题,当我将类别设置为 .playbackAndRecord 并将选项设置为 .defaultToSpeaker 时,为什么我在真实 phone 上根本听不到声音?除了没有声音,我也没有收到来自麦克风的输入。模拟器里声音没问题
编辑 #3:我开始观察路由变化,当包含 .defaultToSpeaker 选项时,我的代码报告以下内容。
2020-12-26 12:17:56.212366-0700 SST[13807:3950195] Current route:
2020-12-26 12:17:56.213275-0700 SST[13807:3950195] <AVAudioSessionRouteDescription: 0x2816af8e0,
inputs = (
"<AVAudioSessionPortDescription: 0x2816af900, type = MicrophoneBuiltIn; name = iPhone Microphone; UID = Built-In Microphone; selectedDataSource = Bottom>"
);
outputs = (
"<AVAudioSessionPortDescription: 0x2816af990, type = Speaker; name = Speaker; UID = Speaker; selectedDataSource = (null)>"
)>
输出设置为扬声器。 selectedDataSource 是 (null) 是否重要?在添加 .defaultToSpeaker 选项之前,此报告的输出设置为 Receiver,也带有 selectedDataSource = (null),所以我猜不会。
编辑:我添加了设置音频会话类别的代码。新代码如下所示。目前看来没有效果。如果我把它留在里面或把它注释掉,我看不出有什么区别。我还有修改 microphone 模式的代码(为简单起见,我在此处删除了)。那也没有明显的效果。不过,也许这是可以预料的?
除了以下症状外,如果我使用 Settings/Bluetooth 到 select AirPods,即使我移除了 AirPods,应用程序也没有任何输出。
我在这里错过了什么?
/编辑
在模拟器上运行良好后,我开始在我的 11 Pro Max 上进行调试。在 MandolinString 上弹奏音符时,来自(11 Pro Max 或 8)模拟器的声音响亮而清晰。在真正的 phone 上,声音几乎听不见,只能从扬声器中听到。它不会转到连接的音频扬声器,无论是 HomePod 还是 AirPods。这是 v5 错误吗?我需要对输出做些什么吗?
第二个不太重要的问题是,当我实例化此对象时,MandolinString 会在我没有调用任何东西的情况下触发。延迟后额外的推子和增益从 0 到 1 的重置抑制了这种声音。
private let engine = AudioEngine()
private let mic : AudioEngine.InputNode
private let micAmp : Fader
private let mixer1 : Mixer
private let mixer2 : Mixer
private let silence : Fader
private let stringAmp : Fader
private var pitchTap : PitchTap
private var tockAmp : Fader
private var metro = Timer()
private let sampler = MIDISampler(name: "click")
private let startTime = NSDate.timeIntervalSinceReferenceDate
private var ampThreshold: AUValue = 0.12
private var ampJumpSize: AUValue = 0.05
private var samplePause = 0
private var trackingNotStarted = true
private var tracking = false
private var ampPrev: AUValue = 0.0
private var freqArray: [AUValue] = []
init() {
// Set up mic input and pitchtap
mic = engine.input!
micAmp = Fader(mic, gain: 1.0)
mixer1 = Mixer(micAmp)
silence = Fader(mixer1, gain: 0)
mixer2 = Mixer(silence)
pitchTap = PitchTap(mixer1, handler: {_ , _ in })
// All sound is fed into mixer2
// Mic input is faded to zero
// Now add String sound to Mixer2 with a Fader
pluckedString = MandolinString()
stringAmp = Fader(pluckedString, gain: 4.0)
mixer2.addInput(stringAmp)
// Create a sound for the metronome (tock), add as input to mixer2
try! sampler.loadWav("Click")
tockAmp = Fader(sampler, gain: 1.0)
mixer2.addInput(tockAmp)
engine.output = mixer2
self.pitchTap = PitchTap(micAmp,
handler:
{ freq, amp in
if (self.samplePause <= 0 && self.tracking) {
self.samplePause = 0
self.sample(freq: freq[0], amp: amp[0])
}
})
do {
//try audioSession.setCategory(AVAudioSession.Category.playAndRecord, mode: AVAudioSession.Mode.measurement)
try audioSession.setCategory(AVAudioSession.Category.playAndRecord)
//, options: AVAudioSession.CategoryOptions.defaultToSpeaker)
try audioSession.setActive(true)
} catch let error as NSError {
print("Unable to create AudioSession: \(error.localizedDescription)")
}
do {
try engine.start()
akStartSucceeded = true
} catch {
akStartSucceeded = false
}
} // init
XCode 12,iOS 14,SPM。一切都是最新的
这很可能不是 AudioKit 本身的问题,它与 AVAudioSession 有关,您可能需要在设备上将其设置为 DefaultToSpeaker。与版本 4 相比,AudioKit 5 的自动会话管理更少,选择做出更少的假设并让开发人员拥有控制权。
答案确实是为AVAudioSession添加代码。但是,它在我最初放置它的地方不起作用。当我把它放在应用程序委托 didFInishLauchWithOptions 中时,它只对我有用。我在 AudioKit Cookbook 中找到了这个。这有效:
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
#if os(iOS)
self.audioSetup()
#endif
return true
}
#if os(iOS)
func audioSetup() {
let session = AVAudioSession.sharedInstance()
do {
Settings.bufferLength = .short
try session.setPreferredIOBufferDuration(Settings.bufferLength.duration)
try session.setCategory(.playAndRecord,
options: [.defaultToSpeaker, .mixWithOthers])
try session.setActive(true)
} catch let err {
print(err)
}
// Other AudioSession stuff here
do {
try session.setActive(true)
} catch let err {
print(err)
}
}
#endif
}
编辑#2:好的,我在这里漏掉了一些重要的东西,但我仍然有一个问题。声音柔和而我必须放大它的原因是它来自听筒,而不是扬声器。当我将选项 .defaultToSpeaker 添加到 setCategory 时,我根本听不到任何声音。
所以,这才是真正的问题,当我将类别设置为 .playbackAndRecord 并将选项设置为 .defaultToSpeaker 时,为什么我在真实 phone 上根本听不到声音?除了没有声音,我也没有收到来自麦克风的输入。模拟器里声音没问题
编辑 #3:我开始观察路由变化,当包含 .defaultToSpeaker 选项时,我的代码报告以下内容。
2020-12-26 12:17:56.212366-0700 SST[13807:3950195] Current route:
2020-12-26 12:17:56.213275-0700 SST[13807:3950195] <AVAudioSessionRouteDescription: 0x2816af8e0,
inputs = (
"<AVAudioSessionPortDescription: 0x2816af900, type = MicrophoneBuiltIn; name = iPhone Microphone; UID = Built-In Microphone; selectedDataSource = Bottom>"
);
outputs = (
"<AVAudioSessionPortDescription: 0x2816af990, type = Speaker; name = Speaker; UID = Speaker; selectedDataSource = (null)>"
)>
输出设置为扬声器。 selectedDataSource 是 (null) 是否重要?在添加 .defaultToSpeaker 选项之前,此报告的输出设置为 Receiver,也带有 selectedDataSource = (null),所以我猜不会。
编辑:我添加了设置音频会话类别的代码。新代码如下所示。目前看来没有效果。如果我把它留在里面或把它注释掉,我看不出有什么区别。我还有修改 microphone 模式的代码(为简单起见,我在此处删除了)。那也没有明显的效果。不过,也许这是可以预料的?
除了以下症状外,如果我使用 Settings/Bluetooth 到 select AirPods,即使我移除了 AirPods,应用程序也没有任何输出。
我在这里错过了什么?
/编辑
在模拟器上运行良好后,我开始在我的 11 Pro Max 上进行调试。在 MandolinString 上弹奏音符时,来自(11 Pro Max 或 8)模拟器的声音响亮而清晰。在真正的 phone 上,声音几乎听不见,只能从扬声器中听到。它不会转到连接的音频扬声器,无论是 HomePod 还是 AirPods。这是 v5 错误吗?我需要对输出做些什么吗?
第二个不太重要的问题是,当我实例化此对象时,MandolinString 会在我没有调用任何东西的情况下触发。延迟后额外的推子和增益从 0 到 1 的重置抑制了这种声音。
private let engine = AudioEngine()
private let mic : AudioEngine.InputNode
private let micAmp : Fader
private let mixer1 : Mixer
private let mixer2 : Mixer
private let silence : Fader
private let stringAmp : Fader
private var pitchTap : PitchTap
private var tockAmp : Fader
private var metro = Timer()
private let sampler = MIDISampler(name: "click")
private let startTime = NSDate.timeIntervalSinceReferenceDate
private var ampThreshold: AUValue = 0.12
private var ampJumpSize: AUValue = 0.05
private var samplePause = 0
private var trackingNotStarted = true
private var tracking = false
private var ampPrev: AUValue = 0.0
private var freqArray: [AUValue] = []
init() {
// Set up mic input and pitchtap
mic = engine.input!
micAmp = Fader(mic, gain: 1.0)
mixer1 = Mixer(micAmp)
silence = Fader(mixer1, gain: 0)
mixer2 = Mixer(silence)
pitchTap = PitchTap(mixer1, handler: {_ , _ in })
// All sound is fed into mixer2
// Mic input is faded to zero
// Now add String sound to Mixer2 with a Fader
pluckedString = MandolinString()
stringAmp = Fader(pluckedString, gain: 4.0)
mixer2.addInput(stringAmp)
// Create a sound for the metronome (tock), add as input to mixer2
try! sampler.loadWav("Click")
tockAmp = Fader(sampler, gain: 1.0)
mixer2.addInput(tockAmp)
engine.output = mixer2
self.pitchTap = PitchTap(micAmp,
handler:
{ freq, amp in
if (self.samplePause <= 0 && self.tracking) {
self.samplePause = 0
self.sample(freq: freq[0], amp: amp[0])
}
})
do {
//try audioSession.setCategory(AVAudioSession.Category.playAndRecord, mode: AVAudioSession.Mode.measurement)
try audioSession.setCategory(AVAudioSession.Category.playAndRecord)
//, options: AVAudioSession.CategoryOptions.defaultToSpeaker)
try audioSession.setActive(true)
} catch let error as NSError {
print("Unable to create AudioSession: \(error.localizedDescription)")
}
do {
try engine.start()
akStartSucceeded = true
} catch {
akStartSucceeded = false
}
} // init
XCode 12,iOS 14,SPM。一切都是最新的
这很可能不是 AudioKit 本身的问题,它与 AVAudioSession 有关,您可能需要在设备上将其设置为 DefaultToSpeaker。与版本 4 相比,AudioKit 5 的自动会话管理更少,选择做出更少的假设并让开发人员拥有控制权。
答案确实是为AVAudioSession添加代码。但是,它在我最初放置它的地方不起作用。当我把它放在应用程序委托 didFInishLauchWithOptions 中时,它只对我有用。我在 AudioKit Cookbook 中找到了这个。这有效:
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
#if os(iOS)
self.audioSetup()
#endif
return true
}
#if os(iOS)
func audioSetup() {
let session = AVAudioSession.sharedInstance()
do {
Settings.bufferLength = .short
try session.setPreferredIOBufferDuration(Settings.bufferLength.duration)
try session.setCategory(.playAndRecord,
options: [.defaultToSpeaker, .mixWithOthers])
try session.setActive(true)
} catch let err {
print(err)
}
// Other AudioSession stuff here
do {
try session.setActive(true)
} catch let err {
print(err)
}
}
#endif
}