我已经读取音频文件AudioBufferList
与ExtAudioFileRead
函数。
这是和ASBD的音频:ios核心音频:如何从音频缓冲区获得采样与交错音频
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 = [[AVAudioSession sharedInstance] sampleRate];
因此,我们得到和交错的音频,2个通道,16位有符号整数为每个通道
AudioBufferList
初始化:
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[0].mNumberChannels = 2;
bufferList->mBuffers[0].mDataByteSize = totalFramesInFile * sizeof(UInt32);
bufferList->mBuffers[0].mData = audioData;
并读入缓冲区:
CheckError(ExtAudioFileRead (
audioFileObject,
&numberOfPacketsToRead,
bufferList), "error ExtAudioFileRead");
audioFileObject
是和的实例这是在代码中启动的,我没有在这里粘贴以节省空间。
我试图完成的是修改我的渲染回调中的音频样本。
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[i];
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
// from audioData[sampleNumber], modify them
// and write into frameBuffer
frameBuffer[frame] = audioData[sampleNumber];
sampleNumber++;
if(sampleNumber > frameTotalForSound) {
soundStruct->isPlaying = false;
AudioOutputUnitStop(soundStruct->outputUnit);
}
}
}
soundStruct->sampleNumber = sampleNumber;
return noErr;
}
是否有可能从UInt32阵列音频数据获取Sint16左右声道采样?
我不知道如果我理解你的问题:您的程序是以交错的“UInt32”格式生成音频数据,并希望将其转换为非交错的“SInt16”,以进行实时播放? – user3078414
@ user3078414,不完全。我根本不想转换。我有一个音频文件,每个通道都有交错的音频和“SInt16”值。目标是将其写入'AudioBufferList'并保存在内存中。当RemoteIO AudioUnit请求新的声音部分时,会触发此呈现回调,并且我希望实时修改每个通道的采样。由于有2个通道 - 我将样品存储在'UInt32'阵列中。我不确定这是否是一个正确的电话,因为我不知道如何在稍后的回调中抽取样本。 – jangofett
这是我的[答案](http://stackoverflow.com/questions/37670071/using-extaudiofilewriteasync-in-callback-function-cant-get-to-run/37684811#37684811)到一个类似的,但稍有不同的问题:输出 - 写入文件需要一个交错缓冲区,而AU产生非交错缓冲区。我还看到了你的问题的答案 - 对最内层实时循环中的索引乘法要小心......''[2 *(n-1)+1]'对演示的清晰度很好 - 我宁愿使用[n + n-1]'代替。 ( - : – user3078414