为啥麦克风关闭时基频和幅度不为零?

Posted

技术标签:

【中文标题】为啥麦克风关闭时基频和幅度不为零?【英文标题】:why fundamental Frequency and magnitude are not null when microphone is off?为什么麦克风关闭时基频和幅度不为零? 【发布时间】:2014-07-28 22:06:07 【问题描述】:

我想使用 Qt 进行实时音频处理并使用 FFTW3 显示频谱。

我在步骤中做了什么:

我从计算机设备捕获任何声音并将其填充到缓冲区中。 我将声音样本分配给双数组 我计算基频。 当我在麦克风打开但没有信号(静音)时显示基频和磁力时,基频不是我所期望的,代码并不总是返回零,有时代码返回 1500Hz,2000hz 作为频率 当麦克风关闭(静音)时,代码不会返回零作为基本频率,而是返回一个介于 0 和 9000Hz 之间的数字。任何帮助将不胜感激 这是我的代码

  QByteArray *buffer;
 QAudioInput *audioInput;
 audioInput = new QAudioInput(format, this);

 //Check the number of samples in input buffer
  qint64 len = audioInput->bytesReady();

 //Limit sample size
 if(len > 4096)
 len = 4096;

 //Read sound samples from input device to buffer
 qint64 l = input->read(buffer.data(), len);
 int input_size= BufferSize;
 int output_size = input_size; //input_size/2+1;
  fftw_plan p3;
 double in[output_size];
  fftw_complex out[output_size];

 short *outdata = (short*)m_buffer.data();// assign sample into short array
 int data_size = size_t(outdata);
  int data_size1 = sizeof(outdata);

 int count = 0;
  double w = 0;

 for(int i(chanelNumber); i < output_size/2; i= i + 2) //fill array in
 

w= 0.5 * (1 - cos(2*M_PI*i/output_size)); // Hann Windows 
double x = 0;
if(i < data_size)
    x = outdata[i];

if(count < output_size)
  in[count] = x;// fill Array In with sample from buffer 
  count++;



for(int i=count; i<output_size; i++)
in[i] = 0;

p3 = fftw_plan_dft_r2c_1d(output_size, in, out, FFTW_ESTIMATE);// create Plan 
 fftw_execute(p3);// FFT
 for (int i = 0; i < (output_size/2); i++) 
 long peak=0;
 double Amplitudemax=0;
double r1 = out[i][0] * out[i][0];
double im1 = out[i][3] * out[i][4];
double t1 = r1 + im1;
//double t = 20*log(sqrt(t1));
double t = sqrt(t1)/(double)(output_size/2);
double f = (double)i*8000  / ((double)output_size/2);
   if(Magnitude > AmplitudeMax)
           
               AmplitudeMax = Magnitude;
               Peak =2* i;
            
 

fftw_destroy_plan(p3);

 return Peak*(static_cast<double>(8000)/output_Size);

【问题讨论】:

您没有使用真实信号,而是对文件中的“标准”信号(sin @ xHz)进行了任何测试? 首先你的沉默是真正的沉默吗?即没有输入信号时音频输入是否用零填充? @KillaKem,当麦克风关闭(静音)时,这意味着真正的静音音频输入填充了很多零,但它也填充了一个大数字,如 4000、6000 oder 或数字 -1。我不知道这么大的数字来自哪里 你在哪里初始化 AmplitudeMaxPeak ?另请注意,出于性能考虑,您不应继续创建和破坏您的 FFTW 计划 - 这是一项昂贵的操作,对于给定的 FFT 大小,您应该只执行一次。 @PaulR,我已经编辑了代码,我在第二秒内初始化 AmplitudeMax 和 Peak 以进行迭代。每次调用函数 peak 时,我都会创建并销毁我的 FFTW,这是错的吗?或者当你说我必须为给定的 FFT 大小销毁和创建一次时是什么意思? 【参考方案1】:

您认为的沉默可能包含少量噪音。随机噪声的 FFT 也会出现随机的,因此具有随机幅度峰值。但噪声可能来自环境中的设备或电子设备(风扇、反激式变压器等),或者您的 ADC 或麦克风的电源,从而显示出一些频率偏差。

如果噪声水平足够低,通常会检查幅度峰值的水平,将其与阈值进行比较,并在低于该阈值的情况下切断频率估计报告。

【讨论】:

当麦克风关闭(静音)时,这意味着真正的静音音频输入填充了很多零,但它也填充了一个大数字,如 4000、6000 oder 或数字 -1。我不知道这么大的数字是从哪里来的

以上是关于为啥麦克风关闭时基频和幅度不为零?的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 上分析来自麦克风的声音(谐波、分音、泛音)[关闭]

为啥当 Interstitial 关闭时先前输入的文本会从 TextView 中消失

为啥我在录屏时会出现无声?

iOS SDK 禁用内置麦克风

如何在不录制的情况下在 Android 上对麦克风进行采样以获得实时幅度/电平?

打开打开录制声音后,为啥录屏还是没声音?