目前,我正在做一个小测试项目,看看是否可以从AVAssetReader获取样本,以便在iOS上使用AudioQueue回放。
我读过这个:( Play raw uncompressed sound with AudioQueue, no sound )和这个:( How to correctly read decoded PCM samples on iOS using AVAssetReader -- currently incorrect decoding )
这两种方法实际上都有帮助。在阅读之前,我根本听不到任何声音。现在,我得到了声音,但音频播放得非常快。这是我第一次尝试音频编程,所以非常感谢您的帮助。
我这样初始化阅读器:
NSDictionary * outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey,
[NSNumber numberWithFloat:44100.0], AVSampleRateKey,
[NSNumber numberWithInt:2], AVNumberOfChannelsKey,
[NSNumber numberWithInt:16], AVLinearPCMBitDepthKey,
[NSNumber numberWithBool:NO], AVLinearPCMIsNonInterleaved,
[NSNumber numberWithBool:NO], AVLinearPCMIsFloatKey,
[NSNumber numberWithBool:NO], AVLinearPCMIsBigEndianKey,
nil];
output = [[AVAssetReaderAudioMixOutput alloc] initWithAudioTracks:uasset.tracks audioSettings:outputSettings];
[reader addOutput:output];
...我就这样抓取数据:
CMSampleBufferRef ref= [output copyNextSampleBuffer];
// NSLog(@"%@",ref);
if(ref==NULL)
return;
//copy data to file
//read next one
AudioBufferList audioBufferList;
NSMutableData *data = [NSMutableData data];
CMBlockBufferRef blockBuffer;
CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(ref, NULL, &audioBufferList, sizeof(audioBufferList), NULL, NULL, 0, &blockBuffer);
// NSLog(@"%@",blockBuffer);
if(blockBuffer==NULL)
{
[data release];
return;
}
if(&audioBufferList==NULL)
{
[data release];
return;
}
//stash data in same object
for( int y=0; y<audioBufferList.mNumberBuffers; y++ )
{
// NSData* throwData;
AudioBuffer audioBuffer = audioBufferList.mBuffers[y];
[self.delegate streamer:self didGetAudioBuffer:audioBuffer];
/*
Float32 *frame = (Float32*)audioBuffer.mData;
throwData = [NSData dataWithBytes:audioBuffer.mData length:audioBuffer.mDataByteSize];
[self.delegate streamer:self didGetAudioBuffer:throwData];
[data appendBytes:audioBuffer.mData length:audioBuffer.mDataByteSize];
*/
}这最终将我们带到音频队列,以这种方式设置:
//Apple's own code for canonical PCM
audioDesc.mSampleRate = 44100.0;
audioDesc.mFormatID = kAudioFormatLinearPCM;
audioDesc.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical;
audioDesc.mBytesPerPacket = 2 * sizeof (AudioUnitSampleType); // 8
audioDesc.mFramesPerPacket = 1;
audioDesc.mBytesPerFrame = 1 * sizeof (AudioUnitSampleType); // 8
audioDesc.mChannelsPerFrame = 2;
audioDesc.mBitsPerChannel = 8 * sizeof (AudioUnitSampleType); // 32
err = AudioQueueNewOutput(&audioDesc, handler_OSStreamingAudio_queueOutput, self, NULL, NULL, 0, &audioQueue);
if(err){
#pragma warning handle error
//never errs, am using breakpoint to check
return;
}我们就这样排队了
while (inNumberBytes)
{
size_t bufSpaceRemaining = kAQDefaultBufSize - bytesFilled;
if (bufSpaceRemaining < inNumberBytes)
{
AudioQueueBufferRef fillBuf = audioQueueBuffer[fillBufferIndex];
fillBuf->mAudioDataByteSize = bytesFilled;
err = AudioQueueEnqueueBuffer(audioQueue, fillBuf, 0, NULL);
}
bufSpaceRemaining = kAQDefaultBufSize - bytesFilled;
size_t copySize;
if (bufSpaceRemaining < inNumberBytes)
{
copySize = bufSpaceRemaining;
}
else
{
copySize = inNumberBytes;
}
if (bytesFilled > packetBufferSize)
{
return;
}
AudioQueueBufferRef fillBuf = audioQueueBuffer[fillBufferIndex];
memcpy((char*)fillBuf->mAudioData + bytesFilled, (const char*)(inInputData + offset), copySize);
bytesFilled += copySize;
packetsFilled = 0;
inNumberBytes -= copySize;
offset += copySize;
}
}我试着尽可能地包含代码,以便让每个人都能很容易地指出我是个笨蛋。也就是说,我有一种感觉,我的问题要么出现在轨迹阅读器的输出设置声明中,要么出现在AudioQueue的实际声明中(我向队列描述我将发送什么样的音频)。事实是,我真的不知道如何在数学上实际生成这些数字(每个数据包的字节数,每个数据包的帧数,诸如此类)。对此的解释将非常感谢,并提前感谢您的帮助。
发布于 2012-07-11 01:29:55
由于某种原因,尽管我所见过的使用LPCM的音频队列的每个示例都有
ASBD.mBitsPerChannel = 8* sizeof (AudioUnitSampleType);对我来说,我需要
ASBD.mBitsPerChannel = 2*bytesPerSample;有关以下内容的说明:
ASBD.mFormatID = kAudioFormatLinearPCM;
ASBD.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical;
ASBD.mBytesPerPacket = bytesPerSample;
ASBD.mBytesPerFrame = bytesPerSample;
ASBD.mFramesPerPacket = 1;
ASBD.mBitsPerChannel = 2*bytesPerSample;
ASBD.mChannelsPerFrame = 2;
ASBD.mSampleRate = 48000;我不知道为什么会这样,这让我很困扰……但希望我最终能弄清楚这一切。
如果有人能向我解释为什么这样做,我将非常感激。
发布于 2012-07-10 00:34:18
不确定这是一个多大的答案,但评论中会有太多的文本和链接,希望它会有所帮助(也许会引导你找到答案)。
首先,我知道在我目前的项目中,调整采样率会影响声音的速度,所以你可以尝试使用这些设置。但是44k是我在大多数默认实现中看到的,包括苹果示例SpeakHere。但是,我会花一些时间将您的代码与该示例进行比较,因为其中有相当多的差异。就像入队前的检查。
首先看看这篇文章https://stackoverflow.com/a/4299665/530933,它谈到了如何了解音频格式,特别是一帧中有多少字节,并适当地进行了造型
也祝你好运。我在这里、苹果论坛和ios论坛(不是官方论坛)上有很多问题。几乎没有响应/帮助。为了走到今天这一步(录音和流媒体),我最终不得不开了一张Apple Dev支持票证。在处理音频之前,我从来不知道它的存在(开发支持)。一件好事是,如果你有一个有效的开发帐户,你可以免费获得2个事件!CoreAudio并不好玩。文档很稀疏,除了SpeakHere之外,也没有太多示例。我确实发现了一件事,就是框架头确实有一些好的信息和this book。不幸的是,我才刚开始写这本书,否则我可能会进一步帮助你。
你也可以查看我自己的一些帖子,我已经尽我所能地回答了这些帖子。This is my main audio question which I have spent alot of time on to compile all pertinent links and code.
using AQRecorder (audioqueue recorder example) in an objective c class
https://stackoverflow.com/questions/11398997
复制相似问题