我正在使用AUGraphAudio Units API在我的iOS应用中播放和录制音频.现在,当一个AUGraph无法启动以下错误时,我遇到了一个罕见的问题:
result = kAUGraphErr_CannotDoInCurrentContext(-10863)
当我们尝试调用AUGraphStart为音频播放设置的时间时,错误发生了不可预测的错误:
(BOOL)startRendering
{
if (playing) {
return YES;
}
playing = YES;
if (NO == [self setupAudioForGraph:&au_play_graph playout:YES]) {
print_error("Failed to create play AUGraph",0);
playing = NO;
return NO;
}
//result = kAUGraphErr_CannotDoInCurrentContext (-10863)
OSStatus result = AUGraphStart(au_play_graph);
if (noErr != result) {
print_error("AUGraphStart", result);
playing = NO;
}
return playing;
}
Run Code Online (Sandbox Code Playgroud)
这是我们从文档中得到的:
为了避免在渲染线程中旋转或等待(一个坏主意!),许多对AUGraph的调用都可以返回:kAUGraphErr_CannotDoInCurrentContext.仅当从其渲染回调调用AUGraph API时才会生成此结果.这意味着它所需的锁在那时由另一个线程保持.如果您看到此结果代码,通常可以再次尝试操作 - 通常是NEXT渲染周期(因此同时可以清除锁定),或者您可以将该调用委托给应用程序中的另一个线程.你不应该旋转或暂停渲染线程.
此结果代码只是一种暂时状态,只要您的其他线程对AUGraph(具有锁定)的调用完成,它就会通过.
在我的情况下,我只是开始AUGraph,它是新的,刚刚创建.如何调试案例以及可能存在的潜在问题?
我正在尝试编写一个可以添加声音效果的iOS应用.我试图在auconverter和remoteIO之间放置一个效果音频单元(例如,失真和混响).设置完AU后,没有声音.
NewAUGraph(&mAuGraph);
AUGraphOpen(mAuGraph);
AUNode remoteOutputNode, converterNode, effectNode;
AudioUnit remoteIOAudioUnit, converterUnit, effectUnit;
AudioComponentDescription cd;
cd.componentManufacturer = kAudioUnitManufacturer_Apple;
cd.componentFlags = cd.componentFlagsMask = 0;
// remote io
cd.componentType = kAudioUnitType_Output;
cd.componentSubType = kAudioUnitSubType_RemoteIO;
AUGraphAddNode(mAuGraph, &cd, &remoteOutputNode);
// converter
cd.componentType = kAudioUnitType_FormatConverter;
cd.componentSubType = kAudioUnitSubType_AUConverter;
AUGraphAddNode(mAuGraph, &cd, &converterNode);
// ipodeq
cd.componentType = kAudioUnitType_Effect;
cd.componentSubType = kAudioUnitSubType_Distortion;
AUGraphAddNode(mAuGraph, &cd, &effectNode);
//callback
AURenderCallbackStruct callbackStruct;
callbackStruct.inputProc = renderCallback;
callbackStruct.inputProcRefCon = &audioDataInfo;
AUGraphSetNodeInputCallback(mAuGraph, converterNode, 0, &callbackStruct);
// set audio unit asbd
AudioStreamBasicDescription audioFormat = AUCanonicalASBD(44100.0, audioDataInfo.inputFormat.mChannelsPerFrame);
AUGraphNodeInfo(mAuGraph, converterNode, …Run Code Online (Sandbox Code Playgroud) 有人可以向我解释一下OpenAL如何适应iPhone上的声音架构?
似乎有不同级别的API用于处理声音.较高级别的人很容易理解.
但是我的理解变得模糊不清.有Core Audio,Audio Units,OpenAL.
这些之间的联系是什么?openAL是基础,它取决于Core Audio(其中包含作为其低级对象之一的Audio Units)?
XAL似乎没有记录OpenAL,但我可以运行使用其功能的代码.
我在iOS 6.1.3 iPad2和新iPad上运行SIP音频流应用程序.
我在iPad上启动了我的应用程序(没有插入任何内容).
音频工作.
我插上耳机.
应用程序崩溃:malloc:对象0x的错误....:没有分配被释放的指针或EXC_BAD_ACCESS
或者:
我在iPad上启动了我的应用程序(耳机已插入).
音频来自耳机.
我拔下耳机.
应用程序崩溃:malloc:对象0x的错误....:没有分配被释放的指针或EXC_BAD_ACCESS
应用代码采用基于http://code.google.com/p/ios-coreaudio-example/示例代码的AudioUnit api (见下文).
我使用kAudioSessionProperty_AudioRouteChange回调来获得更改感知.因此,OS声音管理器有三个回调:
1)处理录制的麦克风样本
2)为扬声器提供样本
3)通知音频硬件存在
经过大量测试后,我的感觉是棘手的代码是执行麦克风捕获的代码.在插入/拔出动作之后,大多数时候在调用RouteChange之前调用记录回调几次导致以后的"分段错误"并且永远不会调用RouteChange回调.更具体地说,我认为AudioUnitRender函数会导致"内存不良访问",而根本不会抛出异常.
我的感觉是,非原子记录回调代码与OS声音设备相关结构的更新竞争.因此,非原子性的记录回调更可能是OS HW更新和记录回调的并发性.
我修改了我的代码以使录制回调尽可能地薄,但我的感觉是我的应用程序的其他线程带来的高处理负载正在为之前描述的并发竞争提供支持.因此,由于AudioUnitRender访问不良,代码的其他部分会出现malloc/free错误.
我试图通过以下方式减少录制回调延迟:
UInt32 numFrames = 256;
UInt32 dataSize = sizeof(numFrames);
AudioUnitSetProperty(audioUnit,
kAudioUnitProperty_MaximumFramesPerSlice,
kAudioUnitScope_Global,
0,
&numFrames,
dataSize);
Run Code Online (Sandbox Code Playgroud)
我试图提出有问题的代码:
dispatch_async(dispatch_get_main_queue(), ^{
Run Code Online (Sandbox Code Playgroud)
有人有提示或解决方案吗?为了重现错误,这里是我的音频会话代码:
//
// IosAudioController.m
// Aruts
//
// Created by Simon Epskamp on 10/11/10.
// Copyright 2010 __MyCompanyName__. All rights reserved.
//
#import "IosAudioController.h"
#import <AudioToolbox/AudioToolbox.h>
#define kOutputBus 0
#define kInputBus 1
IosAudioController* …Run Code Online (Sandbox Code Playgroud) 我正在开发iphone 3GS上的低音吉他音高检测应用程序.我发现使用RemoteIO无法获得低于150Hz的声音数据.然而,低音吉他可能会产生低于50hz的音调.根据报告"iPhone 4耳机输入频率响应",http://blog.faberacoustical.com/2010/iphone/iphone-4-audio-and-frequency-response-limitations/ 150以下急剧下降赫兹.
这里显示了我如何设置AudioUnit.
// set audio unit
{
// create AudioUnit
{
AudioComponentDescription desc;
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_RemoteIO;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
AudioComponent comp = AudioComponentFindNext(NULL, &desc);
OSAssert(AudioComponentInstanceNew(comp, &m_AudioUnit));
}
//enable input on the remote I/O unit (output is default enabled, but input is not)
{
UInt32 one = 1;
OSAssert(AudioUnitSetProperty(m_AudioUnit, kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Input, 1, &one, sizeof(one)));
}
//set render callback function
{
AURenderCallbackStruct callbackInfo;
callbackInfo.inputProc=staticPerformThru;
callbackInfo.inputProcRefCon=this;
OSAssert(AudioUnitSetProperty(m_AudioUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Input,
0, …Run Code Online (Sandbox Code Playgroud) 我在语音聊天应用程序中使用RemoteIO.为了启用回声消除,在将"kAudioSessionCategory_PlayAndRecord"设置为会话类型后,我将"kAudioUnitSubType_RemoteIO"更改为"kAudioUnitSubType_VoiceProcessingIO".现在回声消除工作,但输出音量水平相对于之前的RemoteIO输出水平显着下降.有没有人知道如何在使用VoiceProcessingIO时获得与使用RemoteIO时相同的输出音量?
我有一个使用AudioUnit的VOIP应用程序.在iOS 9上,我看到一条错误消息,说明如下.我在iOS 8中没有看到这个:
mediaserverd [43]:13:16:38.880错误:[0x1f72d000]> va> 500:错误'什么'获取物理格式的客户端格式[16/44100/2; flags:0xc; bytes/packet:4; 帧/包:1; bytes/frame:4; ]
有谁知道这意味着什么?音频似乎工作正常,但我仍然有点厌烦,如果可以,我想解决它.我的AudioUnit设置代码如下.帮助赞赏.谢谢.
CheckError(NewAUGraph(&audioState.graph), "NewAUGraph failed");
AUNode rioNode;
AudioComponentDescription desc;
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_VoiceProcessingIO;
desc.componentFlags = 0; // Documentation states "Set this value to zero"
desc.componentFlagsMask = 0; // Documentation states "Set this value to zero"
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
CheckError(AUGraphAddNode(audioState.graph, &desc, &rioNode), "AUGraphAddNode failed for RIO");
CheckError(AUGraphOpen(audioState.graph),"Failed to open graph");
CheckError(AUGraphNodeInfo(audioState.graph, rioNode, NULL, &audioState.rio),"Failed to get rio node info");
UInt32 flag = 1;
CheckError(AudioUnitSetProperty(audioState.rio,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Input,
1,
&flag, …Run Code Online (Sandbox Code Playgroud) 我有一个AudioFileStream_PacketsProc回调设置,AudioFileStreamOpen用于处理将音频数据包转换为PCM AudioConverterFillComplexBuffer.我遇到的问题是我在AudioConverterFillComplexBuffer调用后得到-50 OSStatus(paramErr).下面是使用了哪些参数AudioConverterFillComplexBuffer以及如何制作参数的片段:
audioConverterRef = AudioConverterRef()
// AudioConvertInfo is a struct that contains information
// for the converter regarding the number of packets and
// which audiobuffer is being allocated
convertInfo? = AudioConvertInfo(done: false, numberOfPackets: numberPackets, audioBuffer: buffer,
packetDescriptions: packetDescriptions)
var framesToDecode: UInt32 = pcmBufferTotalFrameCount! - end
var localPcmAudioBuffer = AudioBuffer()
localPcmAudioBuffer.mData = pcmAudioBuffer!.mData.advancedBy(Int(end * pcmBufferFrameSizeInBytes!))
var localPcmBufferList = AudioBufferList(mNumberBuffers: 1, mBuffers: AudioBuffer(mNumberChannels: 0, mDataByteSize: 0, mData: nil))
localPcmAudioBuffer = localPcmBufferList.mBuffers …Run Code Online (Sandbox Code Playgroud) 我正在尝试录制混音器单元输出产生的声音.
目前,我的代码基于Apple MixerHost iOS应用程序演示:混音器节点连接到音频图形上的远程IO节点.
我尝试在混音器输出上的远程IO节点输入上设置输入回调.
我做错了什么,但我找不到错误.
这是下面的代码.这是在多通道混音器单元设置之后完成的:
UInt32 flag = 1;
// Enable IO for playback
result = AudioUnitSetProperty(iOUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output,
0, // Output bus
&flag,
sizeof(flag));
if (noErr != result) {[self printErrorMessage: @"AudioUnitSetProperty EnableIO" withStatus: result]; return;}
/* can't do that because *** AudioUnitSetProperty EnableIO error: -1073752493 00000000
result = AudioUnitSetProperty(iOUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input,
0, // Output bus
&flag,
sizeof(flag));
if (noErr != result) {[self printErrorMessage: @"AudioUnitSetProperty EnableIO" withStatus: result]; …Run Code Online (Sandbox Code Playgroud) 我正在开发一个iOS应用程序,它使用AVAudioEngine进行各种操作,包括将音频录制到文件,使用音频单元对音频应用效果,以及播放应用效果的音频.我使用tap也将输出写入文件.完成此操作后,它会在播放音频时实时写入文件.
是否可以设置AVAudioEngine图形,该图形从文件读取,使用音频单元处理声音,并输出到文件,但比实时更快(即,与硬件可以处理的速度一样快)?用于此的用例是输出几分钟的音频并应用效果,我当然不希望等待几分钟来处理它.
编辑:这是我用来设置AVAudioEngine图表的代码,并播放声音文件:
AVAudioEngine* engine = [[AVAudioEngine alloc] init];
AVAudioPlayerNode* player = [[AVAudioPlayerNode alloc] init];
[engine attachNode:player];
self.player = player;
self.engine = engine;
if (!self.distortionEffect) {
self.distortionEffect = [[AVAudioUnitDistortion alloc] init];
[self.engine attachNode:self.distortionEffect];
[self.engine connect:self.player to:self.distortionEffect format:[self.distortionEffect outputFormatForBus:0]];
AVAudioMixerNode* mixer = [self.engine mainMixerNode];
[self.engine connect:self.distortionEffect to:mixer format:[mixer outputFormatForBus:0]];
}
[self.distortionEffect loadFactoryPreset:AVAudioUnitDistortionPresetDrumsBitBrush];
NSError* error;
if (![self.engine startAndReturnError:&error]) {
NSLog(@"error: %@", error);
} else {
NSURL* fileURL = [[NSBundle mainBundle] URLForResource:@"test2" withExtension:@"mp3"];
AVAudioFile* file = [[AVAudioFile alloc] initForReading:fileURL error:&error];
if (error) …Run Code Online (Sandbox Code Playgroud) audiounit ×10
ios ×9
core-audio ×5
iphone ×2
audiotoolbox ×1
headphones ×1
ios9 ×1
objective-c ×1
openal ×1
remoteio ×1
swift ×1
swift2 ×1