AudioQueue 录制音频样本

Posted

技术标签:

【中文标题】AudioQueue 录制音频样本【英文标题】:AudioQueue Recording Audio Sample 【发布时间】:2012-06-03 23:57:58 【问题描述】:

我目前正在构建一个应用程序,该应用程序可以从我的 iPhone 麦克风中读取音频,然后进行一些处理和视觉处理。当然,我首先从音频开始,但遇到了一个小问题。

我将我的采样率定义为 44100 Hz,并将我的缓冲区定义为容纳 4096 个样本。确实如此。但是,当我将这些数据打印出来时,将其复制到 MATLAB 中以再次检查准确性,我必须使用的采样率是我的 iPhone 定义速率的一半,即 22050 Hz,以确保它是正确的。

我认为它与以下代码以及它如何为每个数据包放置 2 个字节有关,当我循环通过缓冲区时,缓冲区吐出整个数据包,我的代码假定它是一个数字.所以我想知道的是如何拆分这些数据包并将它们作为单独的数字读取。

- (void)setupAudioFormat 
    memset(&dataFormat, 0, sizeof(dataFormat));
    dataFormat.mSampleRate = kSampleRate;
    dataFormat.mFormatID = kAudioFormatLinearPCM;
    dataFormat.mFramesPerPacket = 1;
    dataFormat.mChannelsPerFrame = 1;
    //  dataFormat.mBytesPerFrame = 2;
    //  dataFormat.mBytesPerPacket = 2;
    dataFormat.mBitsPerChannel = 16;
    dataFormat.mReserved = 0;

    dataFormat.mBytesPerPacket = dataFormat.mBytesPerFrame = (dataFormat.mBitsPerChannel / 8) * dataFormat.mChannelsPerFrame;
    dataFormat.mFormatFlags = 
    kLinearPCMFormatFlagIsSignedInteger |
    kLinearPCMFormatFlagIsPacked;

如果我的描述不清楚,请告诉我。谢谢!

编辑

添加我用来打印数据的代码

float *audioFloat =  (float *)malloc(numBytes * sizeof(float));
int *temp = (int*)inBuffer->mAudioData;
int i;
float power = pow(2, 31);
for (i = 0;i<numBytes;i++) 
    audioFloat[i] = temp[i]/power;
    printf("%f ",audioFloat[i]);

【问题讨论】:

您是如何遍历缓冲区并打印每个样本的?发布该代码以查看问题是否存在。 我猜你会收到立体声数据流,例如左声道 16 位,右声道 16 位。 添加了一些打印代码。让我知道这是否可以解决任何问题 【参考方案1】:

我发现我正在做的事情有问题。这是一个 c 指针问题,因为我以前从未真正用 C 编程过,所以我当然弄错了。

您不能直接将 inBuffer->mAudioData 转换为 int 数组。所以我只是做了以下

SInt16 *buffer = malloc(sizeof(SInt16)*kBufferByteSize);
buffer = inBuffer->mAudioData;

结果很好,现在我的数据长度正确并且数据表示正确。

【讨论】:

上述不是内存泄漏吗? (malloc 但没有免费的) 假设你会释放必要的内存【参考方案2】:

我看到了你的回答,还有一个潜在的问题,它给出了错误的样本数据字节,这是因为字节交换的字节序问题。

-(void)feedSamplesToEngine:(UInt32)audioDataBytesCapacity audioData:(void *)audioData int sampleCount = audioDataBytesCapacity / sizeof(SAMPLE_TYPE);

SAMPLE_TYPE *samples = (SAMPLE_TYPE*)audioData;
//SAMPLE_TYPE *sample_le = (SAMPLE_TYPE *)malloc(sizeof(SAMPLE_TYPE)*sampleCount );//for swapping endians

std::string shorts;
double power = pow(2,10);
for(int i = 0; i < sampleCount; i++)

    SAMPLE_TYPE sample_le =  (0xff00 & (samples[i] << 8)) | (0x00ff & (samples[i] >> 8)) ; //Endianess issue
    char dataInterim[30];
    sprintf(dataInterim,"%f ", sample_le/power); // normalize it.
    shorts.append(dataInterim);

【讨论】:

以上是关于AudioQueue 录制音频样本的主要内容,如果未能解决你的问题,请参考以下文章

在 iPhone 上使用 AudioQueue 录制/播放

使用 AudioQueue 在 iOS 上进行失真(机器人)音频录制

在 AudioQueue 录制时播放警报声音(振动)

AudioQueue 样本值错误

音频队列 |在 audioQueue 运行时更改音频设备

使用 AudioQueue 和 Monotouch 静态声音录制