请教关于声音波形处理方法

时间:2021-12-09 10:24:05
经常听利用傅里叶变换处理波形。

傅里叶变换具体如何应用,网上是否有代码可以利用?

对一个音频文件局部,需要调高8度,如何实现?

对一个音频文件局部,需要音量放大,又如何如何实现?

一个笛子的音频,与一个清唱的歌曲音频,又如何叠加到一起,达到伴奏的效果?

语音识别中比对声音波形有哪些方法?

问题比较多,请朋友们就各自所知给予指教。

12 个解决方案

#1


网上是否有代码可以利用?
搜了就有了

局部,需要调高8度,如何实现?
傅里叶变换再调整高频部分, 再变换回去, 注意两端

局部,需要音量放大,又如何如何实现?
直接把取样数据乘以倍数, 注意两端, 尖峰失真

又如何叠加到一起,达到伴奏的效果?
取样数据两个相加, 取平均值(比例)

比对声音波形有哪些方法?
比较专业, 一般是频谱指纹

#2


matlab中的fft就是傅里叶变换,还有一些类似的函数,傅里叶变换可以用来进行特征提取

#3


貌似DirectMusic可以满足LZ一些需求。

#4


建议找找开源的代码吧,看看有没有可以用的。也可以研究下DirectX
感觉DirectX与底层交互做的很强!可以试试吧。

#5


我上传了一个sound FFT资源,但不知为何,上传后没有显示,可能得等等,等可以下载了,你下载学习一下,或许会有参考价值

#6


感谢各位朋友的指点,我这几天努力的在网上找。

引用 5 楼 swandream 的回复:
我上传了一个sound FFT资源,但不知为何,上传后没有显示,可能得等等,等可以下载了,你下载学习一下,或许会有参考价值


如果有时间,请给我的邮箱发一个: hztj2005 # yahoo.com.cn

非常感谢!

#7


www.speex.org开源的语音通讯项目,傅里叶啥的我不懂,不过那里面肯定有。

以前做过语音通讯,简单的处理还是知道的。
1、音量放大,把PCM数据直接乘以一个数就行了,减小同理,其实就是把波形在Y轴上放大、缩小。
2、声音叠加,把两段PCM数据直接相加就行了,相当于波形重叠。

#8


 1、音量放大,把PCM数据直接乘以一个数就行了    
好象不行吧

贴一个我画波形文件的代码
//-----------------------------------------------------------------------------
// 绘制声音波形
//  pBuffer  PCM数据
//  dwSize   PCM数据长度
//  dwPos    数据开始的位置       为了使MP3解码一帧,输出一帧波形图, POS就是表示当前帧在MP3中的位置 
//-----------------------------------------------------------------------------
void CWaveBar::DrawWaveGraph(BYTE* pBuffer, DWORD dwSize, DWORD dwPos)
{
iframecount++;                 //第几帧,,这个函数做为回调函数用,
if(dwPos>m_dwDataSize) m_dwDataSize=dwPos;
if(m_dwDataSize>=m_dwSize && m_dwSize==0) return; 
if(m_MDC.m_hDC !=NULL)  //  
{
CPen penLine,penWhite,penCursor,*oldpen;  //各种COLOR的PEN

penLine.CreatePen (PS_SOLID,0,RGB(0,90,180));
penWhite.CreatePen (PS_SOLID,1,RGB(255,255,255));
penCursor.CreatePen (PS_SOLID,1,RGB(255,0,0));
oldpen=m_MDC.SelectObject (&penLine);

DWORD size, perSize, totalSize;
    size=m_wfx.wBitsPerSample ==16?dwSize/2:dwSize;
perSize=m_wfx.wBitsPerSample ==16?m_dwDataSize/2:m_dwDataSize;
totalSize=m_wfx.wBitsPerSample ==16?m_dwSize/2:m_dwSize; 
int b=0; 
int time=m_dwSize/m_wfx.nAvgBytesPerSec ;   
b=time<10 ? memrec.Width()-((memrec.Width()/10)*time):0;// if the time<10 calculate the wave width

int pps=(memrec.Width ()*15)/time; 
int n= m_wfx.nSamplesPerSec /pps;    

int yy=memrec.Height ()/4; 
int h=yy;    
short sample;
int register x=0; 
int nLastX = int(((float)(perSize)/totalSize)*(memrec.Width()-b));
int px;
int Index=nLastX/10; 
int nLastY = yy;
for(x=0;x<(long)size;x=x+n) //画第1 channel 的波形
{
//难道下面两句就是FFT变换的算法么????
sample=m_wfx.wBitsPerSample ==8?( (*(pBuffer+x)-128)*h)/128:((*((short*)pBuffer+x))*h)/(65535/2);
 px = int(((float)(perSize+x)/totalSize)*(memrec.Width()-b));
int py = yy-sample;
 
m_MDC.SelectObject (&penLine);
m_MDC.MoveTo(nLastX, nLastY);
m_MDC.LineTo (px, py);
nLastX = px;
nLastY = py;
}

if(m_wfx.nChannels>1) // 如果是立体专用
{
yy= yy+h+h/2;
m_MDC.SelectObject (&penLine);
m_MDC.MoveTo (int(((float)(perSize)/totalSize)*(memrec.Width()-b)),yy); // move to the orgin

for( x=1;x<=(long)size;x=x+n) //画第二通道的波形
{
//难道下面两句就是FFT变换的算法么????
sample=m_wfx.wBitsPerSample ==8?( (*(pBuffer+x)-128)*h)/128:((*((short*)pBuffer+x))*h)/(65535/2);
px=int(((float)(perSize+x)/totalSize)*(memrec.Width()-b)) ; 
m_MDC.LineTo (px,yy-sample);
}
}
m_MDC.SelectObject (oldpen);
if (Index<1000 && m_OffsetIndex[Index]==0)
{
m_OffsetIndex[Index]=g_pMp3Current-g_pMp3Begin ;
if (Index>0)
{
//画向屏
int x1,x2 ; 
x1= (float)((Index-1)*10) / m_fZoom- m_XAmount ; 
x2= (float)(Index*10) / m_fZoom- m_XAmount ; 
CDC *pDc = GetDC();
CRect rc; 
GetClientRect(&rc);
StretchBlt(pDc->m_hDC,x1,WAVE_SCALE_TOP,x2-x1,rc.Height()-WAVE_SCALE_TOP,m_MDC.GetSafeHdc(),
(Index-1)*10,0,10,memrec.Height(),SRCCOPY);
pDc->DeleteDC();
}

}

}
m_dwDataSize += dwSize;
}

#9


引用 5 楼 swandream 的回复:
我上传了一个sound FFT资源,但不知为何,上传后没有显示,可能得等等,等可以下载了,你下载学习一下,或许会有参考价值


谢谢!
我下载了,代码没有中文注释,可能得些时间看懂。

我在CodeProject也下了一个:

http://www.codeproject.com/KB/audio-video/DirectSound_Spectrum2.aspx

#10


推荐一本书:
孙鹤泉《实用Fourier变换及C++实现》,这本书有说明,光盘有C++代码,很难得。

#11


虽然还没有完全弄懂,但最近看下面这些书,有希望弄懂了,我就把贴结了。

1、潘文杰的傅里叶变换,是理论基础,看看有帮助,但有点难懂,不求甚解也是种方法。
2、程乾生《数字信号处理》,不错。
3、《小波与傅里叶分析基础》,芮国胜译。不错。
4、孙鹤泉《实用Fourier变换及C++实现》,这本书光盘有C++代码。难得。

感谢大家!

#12


请教关于声音波形处理方法

#1


网上是否有代码可以利用?
搜了就有了

局部,需要调高8度,如何实现?
傅里叶变换再调整高频部分, 再变换回去, 注意两端

局部,需要音量放大,又如何如何实现?
直接把取样数据乘以倍数, 注意两端, 尖峰失真

又如何叠加到一起,达到伴奏的效果?
取样数据两个相加, 取平均值(比例)

比对声音波形有哪些方法?
比较专业, 一般是频谱指纹

#2


matlab中的fft就是傅里叶变换,还有一些类似的函数,傅里叶变换可以用来进行特征提取

#3


貌似DirectMusic可以满足LZ一些需求。

#4


建议找找开源的代码吧,看看有没有可以用的。也可以研究下DirectX
感觉DirectX与底层交互做的很强!可以试试吧。

#5


我上传了一个sound FFT资源,但不知为何,上传后没有显示,可能得等等,等可以下载了,你下载学习一下,或许会有参考价值

#6


感谢各位朋友的指点,我这几天努力的在网上找。

引用 5 楼 swandream 的回复:
我上传了一个sound FFT资源,但不知为何,上传后没有显示,可能得等等,等可以下载了,你下载学习一下,或许会有参考价值


如果有时间,请给我的邮箱发一个: hztj2005 # yahoo.com.cn

非常感谢!

#7


www.speex.org开源的语音通讯项目,傅里叶啥的我不懂,不过那里面肯定有。

以前做过语音通讯,简单的处理还是知道的。
1、音量放大,把PCM数据直接乘以一个数就行了,减小同理,其实就是把波形在Y轴上放大、缩小。
2、声音叠加,把两段PCM数据直接相加就行了,相当于波形重叠。

#8


 1、音量放大,把PCM数据直接乘以一个数就行了    
好象不行吧

贴一个我画波形文件的代码
//-----------------------------------------------------------------------------
// 绘制声音波形
//  pBuffer  PCM数据
//  dwSize   PCM数据长度
//  dwPos    数据开始的位置       为了使MP3解码一帧,输出一帧波形图, POS就是表示当前帧在MP3中的位置 
//-----------------------------------------------------------------------------
void CWaveBar::DrawWaveGraph(BYTE* pBuffer, DWORD dwSize, DWORD dwPos)
{
iframecount++;                 //第几帧,,这个函数做为回调函数用,
if(dwPos>m_dwDataSize) m_dwDataSize=dwPos;
if(m_dwDataSize>=m_dwSize && m_dwSize==0) return; 
if(m_MDC.m_hDC !=NULL)  //  
{
CPen penLine,penWhite,penCursor,*oldpen;  //各种COLOR的PEN

penLine.CreatePen (PS_SOLID,0,RGB(0,90,180));
penWhite.CreatePen (PS_SOLID,1,RGB(255,255,255));
penCursor.CreatePen (PS_SOLID,1,RGB(255,0,0));
oldpen=m_MDC.SelectObject (&penLine);

DWORD size, perSize, totalSize;
    size=m_wfx.wBitsPerSample ==16?dwSize/2:dwSize;
perSize=m_wfx.wBitsPerSample ==16?m_dwDataSize/2:m_dwDataSize;
totalSize=m_wfx.wBitsPerSample ==16?m_dwSize/2:m_dwSize; 
int b=0; 
int time=m_dwSize/m_wfx.nAvgBytesPerSec ;   
b=time<10 ? memrec.Width()-((memrec.Width()/10)*time):0;// if the time<10 calculate the wave width

int pps=(memrec.Width ()*15)/time; 
int n= m_wfx.nSamplesPerSec /pps;    

int yy=memrec.Height ()/4; 
int h=yy;    
short sample;
int register x=0; 
int nLastX = int(((float)(perSize)/totalSize)*(memrec.Width()-b));
int px;
int Index=nLastX/10; 
int nLastY = yy;
for(x=0;x<(long)size;x=x+n) //画第1 channel 的波形
{
//难道下面两句就是FFT变换的算法么????
sample=m_wfx.wBitsPerSample ==8?( (*(pBuffer+x)-128)*h)/128:((*((short*)pBuffer+x))*h)/(65535/2);
 px = int(((float)(perSize+x)/totalSize)*(memrec.Width()-b));
int py = yy-sample;
 
m_MDC.SelectObject (&penLine);
m_MDC.MoveTo(nLastX, nLastY);
m_MDC.LineTo (px, py);
nLastX = px;
nLastY = py;
}

if(m_wfx.nChannels>1) // 如果是立体专用
{
yy= yy+h+h/2;
m_MDC.SelectObject (&penLine);
m_MDC.MoveTo (int(((float)(perSize)/totalSize)*(memrec.Width()-b)),yy); // move to the orgin

for( x=1;x<=(long)size;x=x+n) //画第二通道的波形
{
//难道下面两句就是FFT变换的算法么????
sample=m_wfx.wBitsPerSample ==8?( (*(pBuffer+x)-128)*h)/128:((*((short*)pBuffer+x))*h)/(65535/2);
px=int(((float)(perSize+x)/totalSize)*(memrec.Width()-b)) ; 
m_MDC.LineTo (px,yy-sample);
}
}
m_MDC.SelectObject (oldpen);
if (Index<1000 && m_OffsetIndex[Index]==0)
{
m_OffsetIndex[Index]=g_pMp3Current-g_pMp3Begin ;
if (Index>0)
{
//画向屏
int x1,x2 ; 
x1= (float)((Index-1)*10) / m_fZoom- m_XAmount ; 
x2= (float)(Index*10) / m_fZoom- m_XAmount ; 
CDC *pDc = GetDC();
CRect rc; 
GetClientRect(&rc);
StretchBlt(pDc->m_hDC,x1,WAVE_SCALE_TOP,x2-x1,rc.Height()-WAVE_SCALE_TOP,m_MDC.GetSafeHdc(),
(Index-1)*10,0,10,memrec.Height(),SRCCOPY);
pDc->DeleteDC();
}

}

}
m_dwDataSize += dwSize;
}

#9


引用 5 楼 swandream 的回复:
我上传了一个sound FFT资源,但不知为何,上传后没有显示,可能得等等,等可以下载了,你下载学习一下,或许会有参考价值


谢谢!
我下载了,代码没有中文注释,可能得些时间看懂。

我在CodeProject也下了一个:

http://www.codeproject.com/KB/audio-video/DirectSound_Spectrum2.aspx

#10


推荐一本书:
孙鹤泉《实用Fourier变换及C++实现》,这本书有说明,光盘有C++代码,很难得。

#11


虽然还没有完全弄懂,但最近看下面这些书,有希望弄懂了,我就把贴结了。

1、潘文杰的傅里叶变换,是理论基础,看看有帮助,但有点难懂,不求甚解也是种方法。
2、程乾生《数字信号处理》,不错。
3、《小波与傅里叶分析基础》,芮国胜译。不错。
4、孙鹤泉《实用Fourier变换及C++实现》,这本书光盘有C++代码。难得。

感谢大家!

#12


请教关于声音波形处理方法