OStack程序员社区-中国程序员成长平台

标题: ios - OSStatus 错误 -50(无效参数)AudioQueueNewInput 在 iOS 上录制音频 [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-12 15:21
标题: ios - OSStatus 错误 -50(无效参数)AudioQueueNewInput 在 iOS 上录制音频

多年来,我一直在互联网上搜寻这个错误的原因,但我被困住了。我一直在关注使用音频服务录制音频的 Apple 开发人员文档,无论我做什么,我都会不断收到此错误。

我可以使用 AVAudioRecorder 将音频很好地录制成任何格式,但我的最终目标是从输入数据中获取一个标准化的 float 组,以便对其应用 FFT(对于菜鸟的措辞感到抱歉我对音频编程很陌生)。

这是我的代码:

- (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;
}

如果有人知道这里发生了什么,我将不胜感激。 Here is the apple docs for the error



Best Answer-推荐答案


你得到一个 -50 (kAudio_ParamError) 因为你还没有初始化 AudioStreamBasicDescriptionmBytesPerFrame 字段:

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

其中 asbdstate.dataFormat 的缩写。在您的情况下 mBytesPerFrame = 2.

我也不会指定 kLinearPCMFormatFlagIsBigEndian,让记录器返回您的原生字节顺序样本。

关于ios - OSStatus 错误 -50(无效参数)AudioQueueNewInput 在 iOS 上录制音频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30413180/






欢迎光临 OStack程序员社区-中国程序员成长平台 (https://ostack.cn/) Powered by Discuz! X3.4