kAudioSessionOverrideAudioRoute_Speaker问题

时间:2012-11-10 02:28:24

标签: iphone audio-recording speaker

我需要非常快速地从扬声器到正常模式来回触发iphone音频路径。我创建了一个类似于这个网站的音频会话:

http://atastypixel.com/blog/using-remoteio-audio-unit/

我正在创建一个可以进行VOIP的应用。

让我解释一下这个简单的问题。我有一个按钮,可以从扬声器切换到正常模式,如下所示:

if(speakerState){
        value = kAudioSessionOverrideAudioRoute_None;
        error = AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(value), &value);
        speakerState = false;
}
else {
        value = kAudioSessionOverrideAudioRoute_Speaker;
        error = AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(value), &value);
        speakerState = true;
}

...你明白只是打开和关闭扬声器。

问题在于:当最终用户快速按下按钮以在大约10次按下后切换扬声器时,应用程序会冻结一段时间,好像它会释放一些东西并在30秒后回来。我需要最终用户能够根据需要不断地打开/关闭此按钮。

更新:我尝试在后台线程中调用扬声器但仍然如果我按下扬声器太多次它会冻结或我松开音频这里是代码:

- (void)manageSpeakerState {

OSStatus error;
UInt32 value;

if(speakerState){
    value = kAudioSessionOverrideAudioRoute_None;
    error = AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(value), &value);

    speakerBtn.selected = false;
    speakerState = false;
}
else {

    value = kAudioSessionOverrideAudioRoute_Speaker;
    error = AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(value), &value);

    speakerBtn.selected = true;
    speakerState = true;
}

}

//只要按下扬声器按钮,就会调用此按钮..打开/关闭扬声器 - (IBAction)演讲者 {

[self performSelectorInBackground:@selector(manageSpeakerState) withObject:nil ]; 


}

更新:我的音频会话在一个单独的线程上运行,使用pthread及其在.c文件中。它可能是一个并发问题,因为当主线程被绑定时,这个问题就出现了。如何更新运行音频会话的线程上的音频路由?

更新:我遇到与此相同的问题:http://lists.apple.com/archives/coreaudio-api/2012/Jul/msg00129.html

每当我改变路线(即扬声器或耳机)时,我的audioUnit都会暂停,所以我会把空的东西读进缓冲区。它几乎就像硬件制造商的问题。我怎么能绕过这个?仍在调用回叫,但切换路由时没有音频单元。

2 个答案:

答案 0 :(得分:0)

点击按钮,只需更改按钮的背景图片和标签。在后台线程中更改音频会话属性。

答案 1 :(得分:0)

在您的应用程序委托中添加这段代码。我希望它能正常工作。

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
UIBackgroundTaskIdentifier newTaskId = UIBackgroundTaskInvalid;
newTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];