如何像Audacity那样绘制波形图

时间:2022-02-06 10:24:27
有点不同,我手上有个mp3文件,像绘出Audacity那样的静态波形图(它是录音时的波形图),因为要继承到别的系统里,UI是不需要的,最好可以输出一组波形的x,y值。我对媒体程序不熟,x,y到底应该代表什么?然后过程思路是什么样的?有源码最好。谢谢

12 个解决方案

#1


帮顶

#2


看SDK  有例子

#3


x:时间
y:幅度

#4


请问楼上的朋友,幅度是什么呢?采样率,音量?

#5


就是sample的值

#6




 哈,同样遇到这样的问题,对于只是显示音量波形图的话,做法有几种.
 一种就是以filter方式封装波形,一种就是以mixerxxx系列api来处理

 对于这个问题,本来以为是个简单的问题,以为调用api即可,而查了下资料,
 竟然发现好多人说不出所以然,不过,要想只是简单的显示左右声道电平,则
 有部分资料可以处理,也有直接在pcm上进行波峰计算的说法,正在研究中,
 不过有人说在directshow的例子中有几个音频filter可以拿来参考,
 和你同样关注和研究中.

#7


后来我自己做了个render filter 来输出y值。
三楼的朋友讲,y就是sample的值,我参考了sdk的scope,把sample buffer里的值加起来,见下面:
pMediaSample->GetPointer(&pdata);
int nbytes = pMediaSample->GetActualDataLength();
int nSamplesPerChan = nbytes/m_nBlockAlign;
//the calculate result
LONG finalValue = 0;

while (nSamplesPerChan--)
{
finalValue += (long)*pdata;
pdata++;
}

return WriteLong(finalValue);
发现值大多在2700000-2900000直接,对噪音和静音也几乎没什么变化。不晓得对不对。

现在最烦的就是搞不清每个sample的y值如何确定,期待高手!

#8


render出来的格式是什么?

#9


to gamedragon

就是文本文件啦,以\n为界输出每个y值,最后就是一串数字

#10


波形数据应该表现的是解压后的数据,也就是PCM格式的数据。和音频格式也有关,通常16位双声道的音频,一个数据项占4个字节,前两个字节(short)表示左声道的幅度,后两个字节表示右声道的幅度,范围土2^15.
对于8位的音频,是用一个字节来表示幅度,范围0-256.

#11



做了一个demo,是解析8位单声道的,不过是用的delphi搞的,供参考。
[img=http://hiphotos.baidu.com/kenlistian/pic/item/0d182424d5ab502d8644f902.jpg?v=1][/img]

关于取波形,就是取wavehead 中的lpdata的值,至于如何显示,就需要搞些变化。

自己也总结了下关于waveform的格式研究,翻开俺的博克http://www.cppblog.com/kenlistian/archive/2009/01/05/71221.html。

源码参考在(http://www.pudn.com/dl.asp?id=624346)

#12


至于想在filter里抓音频波形,
的确是调用sample,这个就是样本数据。

读取format属性,判断该获取的音频wave格式是
8位,还是16位,
如果是16位,
直接读取头2个字节即可。

如果想对整个样本来判定哪个最大,
则要循环整个样本字节。
如下的delphi的源码处理:

       size := Sample.GetActualDataLength();

       //for i := 0 to Size - 1 do 
       begin
         //if (i mod 4) = 0 then
         begin
           i := 0;
           nTemp_LVal := (PByte(Integer(PBuffer) + i)^ );

           if nTemp_LVal = 0 then nTemp_LVal := 1;
           nLVal := round(( 20 * log10(nTemp_LVal /32767) + 96)* (100 / 96));

           nTemp_RVal := Round( PByte(Integer(PBuffer) + i + 2)^ );
           if nTemp_RVal = 0 then nTemp_RVal := 1;
           nRVal := round(( 20 * log10(nTemp_RVal /32767) + 96)* (100 / 96));

         end;
       end;

这是我抓16位音频波形波形参考代码

#1


帮顶

#2


看SDK  有例子

#3


x:时间
y:幅度

#4


请问楼上的朋友,幅度是什么呢?采样率,音量?

#5


就是sample的值

#6




 哈,同样遇到这样的问题,对于只是显示音量波形图的话,做法有几种.
 一种就是以filter方式封装波形,一种就是以mixerxxx系列api来处理

 对于这个问题,本来以为是个简单的问题,以为调用api即可,而查了下资料,
 竟然发现好多人说不出所以然,不过,要想只是简单的显示左右声道电平,则
 有部分资料可以处理,也有直接在pcm上进行波峰计算的说法,正在研究中,
 不过有人说在directshow的例子中有几个音频filter可以拿来参考,
 和你同样关注和研究中.

#7


后来我自己做了个render filter 来输出y值。
三楼的朋友讲,y就是sample的值,我参考了sdk的scope,把sample buffer里的值加起来,见下面:
pMediaSample->GetPointer(&pdata);
int nbytes = pMediaSample->GetActualDataLength();
int nSamplesPerChan = nbytes/m_nBlockAlign;
//the calculate result
LONG finalValue = 0;

while (nSamplesPerChan--)
{
finalValue += (long)*pdata;
pdata++;
}

return WriteLong(finalValue);
发现值大多在2700000-2900000直接,对噪音和静音也几乎没什么变化。不晓得对不对。

现在最烦的就是搞不清每个sample的y值如何确定,期待高手!

#8


render出来的格式是什么?

#9


to gamedragon

就是文本文件啦,以\n为界输出每个y值,最后就是一串数字

#10


波形数据应该表现的是解压后的数据,也就是PCM格式的数据。和音频格式也有关,通常16位双声道的音频,一个数据项占4个字节,前两个字节(short)表示左声道的幅度,后两个字节表示右声道的幅度,范围土2^15.
对于8位的音频,是用一个字节来表示幅度,范围0-256.

#11



做了一个demo,是解析8位单声道的,不过是用的delphi搞的,供参考。
[img=http://hiphotos.baidu.com/kenlistian/pic/item/0d182424d5ab502d8644f902.jpg?v=1][/img]

关于取波形,就是取wavehead 中的lpdata的值,至于如何显示,就需要搞些变化。

自己也总结了下关于waveform的格式研究,翻开俺的博克http://www.cppblog.com/kenlistian/archive/2009/01/05/71221.html。

源码参考在(http://www.pudn.com/dl.asp?id=624346)

#12


至于想在filter里抓音频波形,
的确是调用sample,这个就是样本数据。

读取format属性,判断该获取的音频wave格式是
8位,还是16位,
如果是16位,
直接读取头2个字节即可。

如果想对整个样本来判定哪个最大,
则要循环整个样本字节。
如下的delphi的源码处理:

       size := Sample.GetActualDataLength();

       //for i := 0 to Size - 1 do 
       begin
         //if (i mod 4) = 0 then
         begin
           i := 0;
           nTemp_LVal := (PByte(Integer(PBuffer) + i)^ );

           if nTemp_LVal = 0 then nTemp_LVal := 1;
           nLVal := round(( 20 * log10(nTemp_LVal /32767) + 96)* (100 / 96));

           nTemp_RVal := Round( PByte(Integer(PBuffer) + i + 2)^ );
           if nTemp_RVal = 0 then nTemp_RVal := 1;
           nRVal := round(( 20 * log10(nTemp_RVal /32767) + 96)* (100 / 96));

         end;
       end;

这是我抓16位音频波形波形参考代码