为什么此音频单元远程初始化在iPhone上可用,而在模拟器中不起作用?
-
25-09-2019 - |
题
我正在使用音频单元服务来设置输出渲染回调,以便我可以将合成的音频混合在一起。我似乎在拥有的设备(iPod Touch,iPhone 3G和iPad)上可以完美工作的代码,但无法在模拟器上使用。
在模拟器上,音频函数失败并返回-10851的值(根据Apple文档,Kaudiouniterr_invalidPropertyValue)。
这是我的初始化代码..任何拥有此API经验的人都比我在这里看到的不正确的事情更多吗?
#define kOutputBus 0
#define kInputBus 1
...
static OSStatus playbackCallback(void *inRefCon,
AudioUnitRenderActionFlags* ioActionFlags,
const AudioTimeStamp* inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList* ioData)
{
// Mix audio here - but it never gets here on the simulator
return noErr;
}
...
{
OSStatus status;
// Describe audio component
AudioComponentDescription desc;
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_RemoteIO;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
// Get component
AudioComponent inputComponent = AudioComponentFindNext(NULL, &desc);
// Get audio units
status = AudioComponentInstanceNew(inputComponent, &m_audio_unit);
if(status != noErr) {
NSLog(@"Failed to get audio component instance: %d", status);
}
// Enable IO for playback
UInt32 flag = 1;
status = AudioUnitSetProperty(m_audio_unit,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Output,
kOutputBus,
&flag,
sizeof(flag));
if(status != noErr) {
NSLog(@"Failed to enable audio i/o for playback: %d", status);
}
// Describe format
AudioStreamBasicDescription audioFormat;
audioFormat.mSampleRate = 44100.00;
audioFormat.mFormatID = kAudioFormatLinearPCM;
audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audioFormat.mFramesPerPacket = 1;
audioFormat.mChannelsPerFrame = 2;
audioFormat.mBitsPerChannel = 16;
audioFormat.mBytesPerPacket = 4;
audioFormat.mBytesPerFrame = 4;
// Apply format
status = AudioUnitSetProperty(m_audio_unit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
kOutputBus,
&audioFormat,
sizeof(audioFormat));
if(status != noErr) {
NSLog(@"Failed to set format descriptor: %d", status);
}
// Set output callback
AURenderCallbackStruct callbackStruct;
callbackStruct.inputProc = playbackCallback;
callbackStruct.inputProcRefCon = self;
status = AudioUnitSetProperty(m_audio_unit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Global,
kOutputBus,
&callbackStruct,
sizeof(callbackStruct));
if(status != noErr) {
NSLog(@"Failed to set output callback: %d", status);
}
// Initialize (This is where it fails on the simulator)
status = AudioUnitInitialize(m_audio_unit);
if(status != noErr) {
NSLog(@"Failed to initialise audio unit: %d", status);
}
}
我的Xcode版本是3.2.2(64位)我的模拟器版本是3.2(尽管相同的问题发生在3.1.3调试或发布中)
谢谢,我很感激!
解决方案
为设备和模拟器编译完全不同。最常见的事情具有相同的预期结果。例如,在它们播放声音之间加载视图开关等。但是,当涉及其他事情时,例如使用开放式加载10个缓冲区播放声音,然后在它们之间切换模拟器无法处理,但是设备可以。
我看到的方式就是我所关心的设备上的工作方式。尽量不要将头发拔出,只是在设备上正常工作时使其在模拟器上工作。
希望有帮助
PK
其他提示
您是否在调用远程初始化代码之前配置和启用音频会话?
将流属性设置为输入总线时,您正在使用 kOutputBus
对于您的输入范围。那可能不好。另外,您可能不需要将渲染回调应用于全局范围,因为您只需要输出即可。此外,我认为您的定义 kOutputBus
和 kInputBus
是错误的...当我查看工作iPhone音频代码时,它使用0用于输入总线,而输出总线为1。
关于AudioStreamBasicDescription,我还可以想到一些次要的事情,尽管我认为这些不会有很大的不同:
- 添加
kAudioFormatFlagsNativeEndian
属性到您的格式标志 - 明确设置
mReserved
字段到0。
不隶属于 StackOverflow