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->mNumberBuffers = 1;
bufferList->mBuffers.mNumberChannels= 2;
bufferList->mBuffers.mDataByteSize = totalFramesInFile * sizeof(UInt32);
bufferList->mBuffers.mData = audioData;
</code></pre>
<p>并读入缓冲区:</p>
<pre><code>CheckError(ExtAudioFileRead (
audioFileObject,
&numberOfPacketsToRead,
bufferList), "error ExtAudioFileRead");
</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 *) &view->mys;
SInt64 frameTotalForSound = soundStruct->frameCount;
soundStruct->isPlaying = true;
UInt32 *audioData = soundStruct->audioData;
UInt32 sampleNumber = soundStruct->sampleNumber;
for( int i = 0; i < ioData->mNumberBuffers; i++){
AudioBuffer buffer = ioData->mBuffers;
UInt32 *frameBuffer = buffer.mData;
for(UInt32 frame = 0; frame < 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 > frameTotalForSound) {
soundStruct->isPlaying = false;
AudioOutputUnitStop(soundStruct->outputUnit);
}
}
}
soundStruct->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]