OSStatus错误-50(无效参数)AudioQueueNewInput在iOS上录制音频 [英] OSStatus error -50 (invalid parameters) AudioQueueNewInput recording audio on iOS

查看:155
本文介绍了OSStatus错误-50(无效参数)AudioQueueNewInput在iOS上录制音频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

多年来,我一直在互联网上搜寻,试图找出造成此错误的原因,但我一直陷于困境.我一直在遵循Apple Developer文档中的有关使用Audio Services记录音频的内容,无论如何我都会不断收到此错误.

I've been trawling the internet for ages trying to find the cause of this error but I'm stuck. I've been following the Apple Developer documentation for using Audio Services to record audio and I keep getting this error whatever I do.

我可以使用 AVAudioRecorder 将音频很好地记录为任何格式,但是我的最终结果是从输入数据中获取标准化的浮点数组,以便对其应用FFT(对不起,短语不对.我是音频编程的新手.)

I can record audio fine using AVAudioRecorder into any format but my end game is to obtain a normalised array of floats from the input data in order to apply an FFT to it (sorry for the noob phrasing I'm very new to audio programming).

这是我的代码:

- (void)beginRecording
{
    // Initialise session
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
    [[AVAudioSession sharedInstance] setActive:YES error:nil];

    state.dataFormat.mFormatID = kAudioFormatLinearPCM;
    state.dataFormat.mSampleRate = 8000.0f;
    state.dataFormat.mChannelsPerFrame = 1;
    state.dataFormat.mBitsPerChannel = 16;
    state.dataFormat.mBytesPerPacket = state.dataFormat.mChannelsPerFrame * sizeof(SInt16);
    state.dataFormat.mFramesPerPacket = 1;

    //AudioFileTypeID fileID = kAudioFileAIFFType;

    state.dataFormat.mFormatFlags = kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;

    OSStatus err = AudioQueueNewInput(&state.dataFormat, handleInputBuffer, &state, CFRunLoopGetMain(), kCFRunLoopCommonModes, 0, &state.queue);
    printf("%i", err); // this is always -50 i.e. invalid parameters error

    deriveBufferSize(state.queue, state.dataFormat, 0.5, &state.bufferByteState);

    for (int i = 0; i < kNumberOfBuffers; i++) {
        AudioQueueAllocateBuffer(state.queue, state.bufferByteState, &state.buffers[i]);
        AudioQueueEnqueueBuffer(state.queue, state.buffers[i], 0, NULL);
    }

    state.currentPacket = 0;
    state.isRunning = YES;

    AudioQueueStart(state.queue, NULL);
}

- (void)endRecording
{
    AudioQueueStop(state.queue, YES);
    state.isRunning = NO;

    AudioQueueDispose(state.queue, YES);

    // Close the audio file here...
}

#pragma mark - CoreAudio

// Core Audio Callback Function
static void handleInputBuffer(void *agData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer, const AudioTimeStamp *inStartTime, UInt32 inNumPackets, const AudioStreamPacketDescription *inPacketDesc) {

    AQRecorderState *state = (AQRecorderState *)agData;

    if (inNumPackets == 0 && state->dataFormat.mBytesPerPacket != 0) {
        inNumPackets = inBuffer->mAudioDataByteSize / state->dataFormat.mBytesPerPacket;
    }

    printf("Called");

    /*
    if (AudioFileWritePackets(state->audioFile, false, inBuffer->mAudioDataByteSize, inPacketDesc, state->currentPacket, &inNumPackets, inBuffer->mAudioData) == noErr) {
        state->currentPacket += inNumPackets;
    }
     */

    if (state->isRunning) {
        AudioQueueEnqueueBuffer(state->queue, inBuffer, 0, NULL);
    }
}

void deriveBufferSize(AudioQueueRef audioQueue, AudioStreamBasicDescription ABSDescription, Float64 secs, UInt32 *outBufferSize) {

    static const int maxBufferSize = 0x50000;

    int maxPacketSize = ABSDescription.mBytesPerPacket;
    if (maxPacketSize == 0) {
        UInt32 maxVBRPacketSize = sizeof(maxPacketSize);
        AudioQueueGetProperty(audioQueue, kAudioConverterPropertyMaximumOutputPacketSize, &maxPacketSize, &maxVBRPacketSize);
    }

    Float64 numBytesForTime = ABSDescription.mSampleRate * maxPacketSize * secs;
    UInt32 x = (numBytesForTime < maxBufferSize ? numBytesForTime : maxBufferSize);
    *outBufferSize = x;
}

如果有人知道这里发生了什么,我将非常感激.这是苹果文档中的错误

If anyone knows what's going on here I'd be very grateful. Here is the apple docs for the error

推荐答案

由于未初始化 AudioStreamBasicDescription mBytesPerFrame 字段:

asbd.mBytesPerFrame = asbd.mFramesPerPacket*asbd.mBytesPerPacket;

其中, asbd state.dataFormat 的缩写.在您的情况下, mBytesPerFrame = 2 .

where asbd is short for state.dataFormat. In your case mBytesPerFrame = 2.

我也不会指定 kLinearPCMFormatFlagIsBigEndian ,而是让记录器返回您本机字节顺序的样本.

I also wouldn't specify the kLinearPCMFormatFlagIsBigEndian, let the recorder return you native byte order samples.

这篇关于OSStatus错误-50(无效参数)AudioQueueNewInput在iOS上录制音频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆