菜鸟教程小白 发表于 2022-12-12 20:51:40

ios核心音频: how to get samples from AudioBuffer with interleaved audio


                                            <p><p>我已使用 <code>ExtAudioFileRead</code> 函数将音频文件读入 <code>AudioBufferList</code>。
<br/>这是音频的ASBD:</p>

<pre><code>AudioStreamBasicDescription importFormat;

importFormat.mFormatID          = kAudioFormatLinearPCM;
importFormat.mFormatFlags       = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
importFormat.mBytesPerPacket    = 4;
importFormat.mFramesPerPacket   = 1;
importFormat.mBytesPerFrame   = 4;
importFormat.mChannelsPerFrame= 2;
importFormat.mBitsPerChannel    = 16;
importFormat.mSampleRate = [ sampleRate];
</code></pre>

<p>所以我们得到了 2 个 channel 的交错音频,每个 channel 有 16 位有符号整数<br/>
<code>AudioBufferList</code> 初始化:</p>

<pre><code>UInt32 *audioData = (UInt32 *) calloc (totalFramesInFile, sizeof (UInt32));

AudioBufferList *bufferList;
bufferList = (AudioBufferList *) malloc (sizeof (AudioBufferList));

// buffers amount is 1 because audio is interleaved
bufferList-&gt;mNumberBuffers = 1;

bufferList-&gt;mBuffers.mNumberChannels= 2;
bufferList-&gt;mBuffers.mDataByteSize    = totalFramesInFile * sizeof(UInt32);
bufferList-&gt;mBuffers.mData            = audioData;
</code></pre>

<p>并读入缓冲区:</p>

<pre><code>CheckError(ExtAudioFileRead (
                           audioFileObject,
                           &amp;numberOfPacketsToRead,
                           bufferList), &#34;error ExtAudioFileRead&#34;);
</code></pre>

<p><code>audioFileObject</code> 是 <code>ExtAudioFileRef</code> 的实例,它在前面的代码中启动,我没有粘贴到这里以节省空间。
<br/>
我想要完成的是在我的渲染回调中修改音频样本。</p>

<pre><code>OSStatus MyCallback (void *inRefCon,
               AudioUnitRenderActionFlags *ioActionFlags,
               const AudioTimeStamp *inTimeStamp,
               UInt32 inBusNumber,
               UInt32 inNumberFrames,
               AudioBufferList *ioData){


    ViewController *view = (__bridge ViewController *) inRefCon;

    soundStruct *soundStruct = (soundStruct *) &amp;view-&gt;mys;

    SInt64            frameTotalForSound      = soundStruct-&gt;frameCount;

    soundStruct-&gt;isPlaying = true;

    UInt32 *audioData   = soundStruct-&gt;audioData;

    UInt32 sampleNumber = soundStruct-&gt;sampleNumber;

    for( int i = 0; i &lt; ioData-&gt;mNumberBuffers; i++){

      AudioBuffer buffer = ioData-&gt;mBuffers;
      UInt32 *frameBuffer = buffer.mData;

      for(UInt32 frame = 0; frame &lt; inNumberFrames; frame++) {

            // here I fill the buffer with my audio data.
            // i need to get left and right channel samples
            // fromaudioData, modify them
            // and write into frameBuffer

            frameBuffer = audioData;

            sampleNumber++;

            if(sampleNumber &gt; frameTotalForSound) {
                soundStruct-&gt;isPlaying = false;
                AudioOutputUnitStop(soundStruct-&gt;outputUnit);
            }
      }
    }

    soundStruct-&gt;sampleNumber = sampleNumber;

    return noErr;

}
</code></pre>

<p>是否可以从 UInt32 音频数据数组中获取 Sint16 左右声道样本?</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>让<code>audioData</code>和<code>frameBuffer</code>都是<code>SInt16</code>s:</p>

<pre><code>SInt16 *audioData;
// ...
SInt16 *frameBuffer;
</code></pre>

<p>您的缓冲区大小计算应该是 <code>n * 2 * sizeof(SInt16) 并且您需要更改</code>soundStruct` 或添加类型转换。</p>

<p>然后你可以像这样访问交错的样本:</p>

<pre><code>frameBuffer = modify(audioData);    // left sample 1
frameBuffer = modify(audioData);    // right sample 1
frameBuffer = modify(audioData);    // left sample 2
frameBuffer = modify(audioData);    // right sample 2
// ...
frameBuffer = modify(audioData);    // left sample n
frameBuffer = modify(audioData); // right sample n
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios核心音频: how to get samples from AudioBuffer with interleaved audio,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/38038822/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/38038822/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios核心音频: how to get samples from AudioBuffer with interleaved audio