Tôi nhận được lỗi -50 (thông số không hợp lệ) từ AudioUnitRender trong ngữ cảnh sau. Tôi đang sử dụng ứng dụng mẫu Pitch Detector này làm điểm xuất phát của tôi và nó hoạt động tốt. Sự khác biệt lớn duy nhất trong dự án của tôi là tôi cũng đang sử dụng đơn vị I/O từ xa cho đầu ra âm thanh. Đầu ra âm thanh hoạt động tốt. Đây là lời gọi lại đầu vào của tôi và mã khởi tạo của tôi (với kiểm tra lỗi đã bị loại bỏ trong ngắn gọn). Tôi biết nó rất nhiều nhưng lỗi -50 thực sự mang lại cho tôi rất ít thông tin về nơi mà vấn đề có thể xảy ra.Lỗi -50 từ AudioUnitRender
callback Input:
OSStatus inputCallback(void* inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData) {
WBAudio* audioObject= (WBAudio*)inRefCon;
AudioUnit rioUnit = audioObject->m_audioUnit;
OSStatus renderErr;
UInt32 bus1 = 1;
renderErr = AudioUnitRender(rioUnit, ioActionFlags,
inTimeStamp, bus1, inNumberFrames, audioObject->m_inBufferList);
if (renderErr < 0) {
return renderErr; // breaks here
}
return noErr;
} // end inputCallback()
khởi:
- (id) init {
self= [super init];
if(!self) return nil;
OSStatus result;
//! Initialize a buffer list for rendering input
size_t bytesPerSample;
bytesPerSample = sizeof(SInt16);
m_inBufferList = (AudioBufferList *)malloc(sizeof(AudioBuffer));
m_inBufferList->mNumberBuffers = 1;
m_inBufferList->mBuffers[0].mNumberChannels = 1;
m_inBufferList->mBuffers[0].mDataByteSize = 512*bytesPerSample;
m_inBufferList->mBuffers[0].mData = calloc(512, bytesPerSample);
//! Initialize an audio session to get buffer size
result = AudioSessionInitialize(NULL, NULL, NULL, NULL);
UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord;
result = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory);
// Set preferred buffer size
Float32 preferredBufferSize = static_cast<float>(m_pBoard->m_uBufferSize)/m_pBoard->m_fSampleRate;
result = AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, sizeof(preferredBufferSize), &preferredBufferSize);
// Get actual buffer size
Float32 audioBufferSize;
UInt32 size = sizeof (audioBufferSize);
result = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareIOBufferDuration, &size, &audioBufferSize);
result = AudioSessionSetActive(true);
//! Create our Remote I/O component description
AudioComponentDescription desc;
desc.componentType= kAudioUnitType_Output;
desc.componentSubType= kAudioUnitSubType_RemoteIO;
desc.componentFlags= 0;
desc.componentFlagsMask= 0;
desc.componentManufacturer= kAudioUnitManufacturer_Apple;
//! Find the corresponding component
AudioComponent outputComponent = AudioComponentFindNext(NULL, &desc);
//! Create the component instance
result = AudioComponentInstanceNew(outputComponent, &m_audioUnit);
//! Enable audio output
UInt32 flag = 1;
result = AudioUnitSetProperty(m_audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputBus, &flag, sizeof(flag));
//! Enable audio input
result= AudioUnitSetProperty(m_audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &flag, sizeof(flag));
//! Create our audio stream description
m_audioFormat.mSampleRate= m_pBoard->m_fSampleRate;
m_audioFormat.mFormatID= kAudioFormatLinearPCM;
m_audioFormat.mFormatFlags= kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
m_audioFormat.mFramesPerPacket= 1;
m_audioFormat.mChannelsPerFrame= 1;
m_audioFormat.mBitsPerChannel= 16;
m_audioFormat.mBytesPerPacket= 2;
m_audioFormat.mBytesPerFrame= 2;
//! Set the stream format
result = AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &m_audioFormat, sizeof(m_audioFormat));
result = AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
kInputBus, &m_audioFormat, sizeof(m_audioFormat));
//! Set the render callback
AURenderCallbackStruct renderCallbackStruct= {0};
renderCallbackStruct.inputProc= renderCallback;
renderCallbackStruct.inputProcRefCon= m_pBoard;
result = AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, kOutputBus, &renderCallbackStruct, sizeof(renderCallbackStruct));
//! Set the input callback
AURenderCallbackStruct inputCallbackStruct = {0};
inputCallbackStruct.inputProc= inputCallback;
inputCallbackStruct.inputProcRefCon= self;
result= AudioUnitSetProperty(m_audioUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Input, kOutputBus, &inputCallbackStruct, sizeof(inputCallbackStruct));
//! Initialize the unit
result = AudioUnitInitialize(m_audioUnit);
return self;
}
Kiểm tra để đảm bảo bus1 và inBusNumber của bạn đều giống nhau. Ngoài ra, trang web mà bạn đề cập không có mã cho trình phát hiện độ cao, chỉ có trình phát hiện tần số cao được ghi nhãn sai, thường sẽ không đạt được ước tính cao độ. – hotpaw2
Chúng giống nhau. Và tôi chắc chắn sẽ phát hiện sân với một hạt muối. – Luke
Bạn có thể giải quyết nó không? Tôi có vấn đề mà bình thường các cuộc gọi đến AudioUnitRender thành công, nhưng khi ứng dụng của tôi trở lại từ nền nó không thành công, bởi vì các yêu cầu gọi lại đầu vào nhiều byte. Suy nghĩ đầu tiên của tôi là nó có cái gì đó để làm với kích thước bộ đệm của tôi, nhưng tăng chúng không giúp đỡ – tomk