[英]Playing PCM data using Audio Queues
I have reffered to this to play a PCM file using Audio Queues. 我曾下文称来此玩使用音频队列一个PCM文件。 The code is as follows:
代码如下:
#import "PlayPCM.h"
AudioFileID audioFile;
SInt64 inStartingPacket = 0;
AudioQueueRef audioQueue;
@implementation PlayPCM
void AudioOutputCallback(
void* inUserData,
AudioQueueRef outAQ,
AudioQueueBufferRef outBuffer)
{
AudioStreamPacketDescription* packetDescs;
UInt32 bytesRead;
UInt32 numPackets = 8000;
OSStatus status;
status = AudioFileReadPackets(audioFile,
false,
&bytesRead,
packetDescs,
inStartingPacket,
&numPackets,
outBuffer->mAudioData);
if(numPackets)
{
outBuffer->mAudioDataByteSize = bytesRead;
status = AudioQueueEnqueueBuffer(audioQueue,
outBuffer,
0,
packetDescs);
inStartingPacket += numPackets;
}
else
{
NSLog(@"number of packets = null ") ;
AudioQueueFreeBuffer(audioQueue, outBuffer);
}
}
-(id)init{
if (self = [super init]) {
}
return self;
}
- (void)setupAudioFormat
{
NSLog(@"setting format");
format.mFormatID = kAudioFormatLinearPCM;
format.mSampleRate = 44100;
format.mFramesPerPacket = 1;
format.mChannelsPerFrame = 1;
format.mBytesPerFrame = 2;
format.mBytesPerPacket = 2;
format.mBitsPerChannel = 16;
format.mFormatFlags = kLinearPCMFormatFlagIsBigEndian |
kLinearPCMFormatFlagIsSignedInteger |
kLinearPCMFormatFlagIsPacked;
}
- (void)startPlayback
{
int counter = 0;
[self setupAudioFormat];
OSStatus status;
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@ "test1.wav"];
NSLog(@"file path = %@",filePath);
//fUrl = [NSURL URLWithPath:@"file:///Users/Inscripts/Desktop/test1.wav"];
fUrl = [NSURL fileURLWithPath:filePath];
//CFURLRef fileURL = (__bridge CFURLRef)(fUrl);
CFURLRef fileURL = CFURLCreateWithString(NULL, (CFStringRef) filePath, NULL);
status = AudioFileOpenURL(fileURL, kAudioFileReadPermission, 0,&audioFile);
NSLog(@"file opening status = %d",(int)status);
if(status == 0)
{ NSLog(@"file opened");
status = AudioQueueNewOutput(&(format),
AudioOutputCallback,
(__bridge void *)(self),
CFRunLoopGetCurrent(),
kCFRunLoopCommonModes,
0,
&audioQueue);
NSLog(@"audio queue create status = %d",(int)status);
if(status == 0)
{
AudioQueueAllocateBuffer(audioQueue, 1600000, &audioQueueBuffer);
AudioOutputCallback((__bridge void *)(self), audioQueue, audioQueueBuffer);
[self performSelector:@selector(startQueue) withObject:self afterDelay:50];
}
}
if(status != 0)
{
NSLog(@"failed");
// labelStatus.text = @"Play failed";
}
}
-(void)startQueue{
NSLog(@"start queue called");
OSStatus status = AudioQueueStart(audioQueue, NULL);
if(status == 0)
{
NSLog(@"ok");
// labelStatus.text = @"Playing";
}
}
test1.wav file is PCM encoded 16 bits per sample, sampling rate 44100 Hertz, stereo. test1.wav文件是PCM编码的每个采样16位,采样率为44100赫兹,立体声。 I can successfully create audio queue and read the file but all I can hear is crackling noise.
我可以成功创建音频队列并读取文件,但是我听到的只是嘶哑的声音。 Can someone tell me what's the issue?
有人可以告诉我这是什么问题吗?
Is the sound really big endian data - i doubt with WAVE files. 声音真的是很大的字节序数据吗-我怀疑使用WAVE文件。
See your format flags, and change them to use little endian data, so: !kLinearPCMFormatFlagIsBigEndian
查看您的格式标志,并将其更改为使用小端数据,因此:
!kLinearPCMFormatFlagIsBigEndian
Also consider using AudioFileOpenURL
or related since that will read the actual wave format and you don't have to rely on your audio stream description. 还应考虑使用
AudioFileOpenURL
或相关文件,因为这将读取实际的波形格式,并且您不必依赖于音频流描述。
After preparing more audio queue buffers, no more crackling noise. 准备了更多的音频队列缓冲区后,就不再发出啪啪声。 please refer to apple's doc
请参考苹果的文档
...
/* AudioQueueAllocateBuffer(audioQueue, 1600000, &audioQueueBuffer);
AudioOutputCallback((__bridge void *)(self), audioQueue, audioQueueBuffer);*/
/* add more audio queue buffers, ex:3 */
int kNumberOfBuffers = 3;
AudioQueueBufferRef audioQueueBuffer[kNumberOfBuffers];
for (int i = 0; i<kNumberOfBuffers; i++) {
AudioQueueAllocateBuffer(audioQueue, 1600000, &audioQueueBuffer[i]);
AudioOutputCallback((__bridge void *)(self), audioQueue, audioQueueBuffer[i]);
}
[self performSelector:@selector(startQueue) withObject:self afterDelay:50];
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.