ios - 随时间获取两个频率的幅度

标签 ios objective-c audio signal-processing

我正在使用这个名为“The Amazing Audio Engine”的 GitHub 项目来从麦克风捕获音频。所以我使用这个方法:

id<AEAudioReceiver> receiver = [AEBlockAudioReceiver audioReceiverWithBlock: ^(void *source, const AudioTimeStamp *time, UInt32 frames, AudioBufferList *audio) {
 // Do something with 'audio'
}];

此方法每 23 毫秒触发一次,传送一个 audio 数组,其中包含 23 毫秒间隔内声波的所有振幅。

这就是问题所在。我正在处理的这个音频声音是一个 FM 信号,由两个频率组成,一个频率为 1000 Hz,另一个频率是数字流的 0 和 1 的两倍。

这是我的问题。此时我有一系列超过 0.23 毫秒的音频幅度。

所以我想我可以进行 FFT 将信号转换为频率电平。我使用了这段代码:

 // Setup the length
 vDSP_Length log2n = log2f(numFrames);

 // Calculate the weights array. This is a one-off operation.
 FFTSetup fftSetup = vDSP_create_fftsetup(log2n, FFT_RADIX2);

 // For an FFT, numSamples must be a power of 2, i.e. is always even
 int nOver2 = numFrames/2;

 // Populate *window with the values for a hamming window function
 float *window = (float *)malloc(sizeof(float) * numFrames);
 vDSP_hamm_window(window, numFrames, 0);
 // Window the samples
 vDSP_vmul(data, 1, window, 1, data, 1, numFrames);

 // Define complex buffer
 COMPLEX_SPLIT A;
 A.realp = (float *) malloc(nOver2*sizeof(float));
 A.imagp = (float *) malloc(nOver2*sizeof(float));

 // Pack samples:
 // C(re) -> A[n], C(im) -> A[n+1]
 vDSP_ctoz((COMPLEX*)data, 2, &A, 1, numFrames/2);


 // RUN THE FFT
 //Perform a forward FFT using fftSetup and A
 //Results are returned in A
 vDSP_fft_zrip(fftSetup, &A, 1, log2n, FFT_FORWARD);

因为每个间隔是 172 Hz,我想隔离 1000Hz,我认为 FFT 结果的第 6 个“桶”就是那个,所以我有这个代码:

 //Convert COMPLEX_SPLIT A result to magnitudes
 float amp[numFrames];
 amp[0] = A.realp[0]/(numFrames*2);

 for(int i=1; i<numFrames; i++) {
   amp[i]=A.realp[i]*A.realp[i]+A.imagp[i]*A.imagp[i];
 }

 // I need the 6th and the 12th bucket, so I need a[5] and a[11]

但后来我开始认为 FFT 不是我想要的,因为 a[5] 和 a[11] 会在 0.23 毫秒内给出 ~1000Hz 和 ~2000Hz 的幅度,但实际上我需要的都是1000 Hz 和 2000 Hz 声音的变化在 0.23ms 时间内发生。事实上我需要获取数组,而不是单个值。

总的来说,我应该怎样做才能获得两个频率(1000 和 2000 Hz)随时间变化的幅度?

最佳答案

如果您知道所需的时间分辨率,那么两个滑动该长度的 Goertzel 滤波器将使您能够以比使用 FFT 少得多的开销来测量两个频率的幅度。过滤器或 FFT 的长度不需要(通常不应该)与每个音频回调的帧数相同。您可以使用循环缓冲区或 fifo 来解耦长度。 (在 iOS 中,numFrames 在不同的设备型号上可能不同,并且可能会突然改变,具体取决于应用程序无法控制的其他因素)。

关于ios - 随时间获取两个频率的幅度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34263870/

相关文章:

ios - Swift 动画 UITableViewCell 扩展高度约束

android - 在 View 页面上播放简单的 .wav?

javascript - 用javascript的媒体流识别歌曲

ios - 合并:如何在不完成原始发布者的情况下替换/捕获错误?

ios - 在 React Native 前台设置 PushNotificationIOS 时发出警告

插入 : warning: Unable to load class for entity 时的 iOS Swift CoreData 错误

ios - 使用共享实例方法禁用 UIButton

ios - 在 iOS 7 中搜索显示 Controller 。出现键盘时缺少栏

objective-c - 将新 pod 添加到现有项目时“无法发出预编译 header ”

python - Raspberry Pi 的轻量级音频播放和图像显示