使用音频队列播放PCM数据 [英] Playing PCM data using Audio Queues

查看:236
本文介绍了使用音频队列播放PCM数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已转至播放使用音频队列的PCM文件. 代码如下:

I have reffered to this to play a PCM file using Audio Queues. 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文件是PCM编码的每个样本16位,采样率为44100赫兹,立体声. 我可以成功创建音频队列并读取文件,但是我听到的只是嘶哑的声音. 有人可以告诉我这是什么问题吗?

test1.wav file is PCM encoded 16 bits per sample, sampling rate 44100 Hertz, stereo. 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?

推荐答案

准备了更多的音频队列缓冲区之后,就不再发出嘶哑的声音.

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];
...

这篇关于使用音频队列播放PCM数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆