菜鸟教程小白 发表于 2022-12-12 15:21:11

ios - OSStatus 错误 -50(无效参数)AudioQueueNewInput 在 iOS 上录制音频


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

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

<p>这是我的代码:</p>

<pre><code>- (void)beginRecording
{
    // Initialise session
    [ setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
    [ 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(&amp;state.dataFormat, handleInputBuffer, &amp;state, CFRunLoopGetMain(), kCFRunLoopCommonModes, 0, &amp;state.queue);
    printf(&#34;%i&#34;, err); // this is always -50 i.e. invalid parameters error

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

    for (int i = 0; i &lt; kNumberOfBuffers; i++) {
      AudioQueueAllocateBuffer(state.queue, state.bufferByteState, &amp;state.buffers);
      AudioQueueEnqueueBuffer(state.queue, state.buffers, 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 &amp;&amp; state-&gt;dataFormat.mBytesPerPacket != 0) {
      inNumPackets = inBuffer-&gt;mAudioDataByteSize / state-&gt;dataFormat.mBytesPerPacket;
    }

    printf(&#34;Called&#34;);

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

    if (state-&gt;isRunning) {
      AudioQueueEnqueueBuffer(state-&gt;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, &amp;maxPacketSize, &amp;maxVBRPacketSize);
    }

    Float64 numBytesForTime = ABSDescription.mSampleRate * maxPacketSize * secs;
    UInt32 x = (numBytesForTime &lt; maxBufferSize ? numBytesForTime : maxBufferSize);
    *outBufferSize = x;
}
</code></pre>

<p>如果有人知道这里发生了什么,我将不胜感激。 <a href="https://developer.apple.com/library/ios/documentation/Security/Reference/keychainservices/index.html#//apple_ref/c/econst/errSecParam" rel="noreferrer noopener nofollow">Here is the apple docs for the error</a> </p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>你得到一个 -50 (<code>kAudio_ParamError</code>) 因为你还没有初始化 <code>AudioStreamBasicDescription</code> 的 <code>mBytesPerFrame</code> 字段:</p>

<pre><code>asbd.mBytesPerFrame = asbd.mFramesPerPacket*asbd.mBytesPerPacket;
</code></pre>

<p>其中 <code>asbd</code> 是 <code>state.dataFormat</code> 的缩写。在您的情况下 <code>mBytesPerFrame = 2</code>.</p>

<p>我也不会指定 <code>kLinearPCMFormatFlagIsBigEndian</code>,让记录器返回您的原生字节顺序样本。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - OSStatus 错误 -50(无效参数)AudioQueueNewInput 在 iOS 上录制音频,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/30413180/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/30413180/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - OSStatus 错误 -50(无效参数)AudioQueueNewInput 在 iOS 上录制音频