QT-从QbyTearray获取音频振幅



我正在尝试使用QT(C )创建一个程序,该程序可以使用QaudioInput和Qiodevice从我的麦克风记录音频。我进行了一项研究,并提出了此页面上的一个示例。这个示例可以做我需要的。

现在,我正在尝试创建录制声音的音频波形。我想提取音频振幅并将其保存在Qlist上。为此,我使用以下代码:

//Check the number of samples in input buffer
qint64 len = m_audioInput->bytesReady();
//Limit sample size
if(len > 4096)
    len = 4096;
//Read sound samples from input device to buffer
qint64 l = m_input->read(m_buffer.data(), len);
if(l > 0)
{
    //Assign sound samples to short array
    short* resultingData = (short*)m_buffer.data();
     for ( i=0; i < len; i++ )
     {
         btlist.append( resultingData[ i ]);
     }
}

m_audiostut是qaudiointup |m_buffer是qbytearray |m_input是qiodevice |btlist是qlist

我使用以下QaudioFormat:

m_format.setFrequency(44100); //set frequency to 44100
m_format.setSampleRate(44100); //set sample rate to 44100
m_format.setChannels(1); //set channels to mono
m_format.setSampleSize(16); //set sample sze to 16 bit
m_format.setSampleType(QAudioFormat::SignedInt ); //signed integer sample
m_format.setByteOrder(QAudioFormat::LittleEndian); //Byte order
m_format.setCodec("audio/pcm"); //set codec as simple audio/pcm

当我打印Qlist时,使用Qwarning()&lt;&lt;btlist.at(int),我得到了一些正面和负数,代表我的音频振幅。我使用Microsoft Excel绘制数据并将其与实际的声波形进行比较。

(根据OP评论进行编辑)我正在使用qt中的qpainter绘制波形

  for(int i = 1; i < btlist.size(); i++){ 
       double x1 = (i-(i/1.25))-0.2;
       double y1 = btlist.at(i-1);
       double x2 = i-(i/1.25);
       double y2 = btlist.at(i);
       painter.drawLine(x1,y1,x2, y2); 
  }

问题是我在振幅数据之间的Qlist中也得到了很多零(0),如果我作为波形绘制,它们是直线,这不是正常的直线因为它会导致我的波形腐败。我的问题是为什么会发生这种情况?这些零(0)代表什么?难道我做错了什么?另外,是否有更好的方法从QbyTearray提取音频振幅?

谢谢。

您正在使用的绘制方法整数值。这意味着大多数时间的x索引都相同。通过简化您的公式,给定i处的x值是(i/5.0)。就本身而言,这不是问题,因为这些线条将被超级插入,这是一种完美的绘画方式(只是确保这是您想做的)。

您看到的零可以是完全有效的。它们代表 silence

真正的问题是您的16位PCM值的范围是[-32767 , 32768]。我怀疑您使用的油漆设备覆盖了此范围。您需要将Y轴标准化。此外,似乎Taht QT协调系统没有负值(编辑:永无止境,它的逻辑坐标已转换为转换)。

例如,使用:

转换您的PCM值
  ((btlist.at(i) / MAX_AMPLITUDE + 1.0) / 2) * paintDevice.height();

编辑:

顺便说一句,您不使用l,这是您阅读的实际数据。如果它不如len,您将在缓冲区结束时读取无效的值,可能会读取垃圾 read red Zeros crash。

您的缓冲区是字节缓冲区。然后您使用简短指针进行迭代。因此,无论您使用l还是len最大尺寸都需要除以两个。这可能是您图片中零线的原因。

 for ( i=0; i < l/2; i++ )
 {
     btlist.append( resultingData[ i ]);
 }

最新更新