首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

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

2012-12-31 
请教关于声音波形处理方法经常听利用傅里叶变换处理波形。傅里叶变换具体如何应用,网上是否有代码可以利用?

请教关于声音波形处理方法
经常听利用傅里叶变换处理波形。

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

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

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

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

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

问题比较多,请朋友们就各自所知给予指教。
[解决办法]
网上是否有代码可以利用?
搜了就有了

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

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

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

比对声音波形有哪些方法?
比较专业, 一般是频谱指纹
[解决办法]
matlab中的fft就是傅里叶变换,还有一些类似的函数,傅里叶变换可以用来进行特征提取
[解决办法]
貌似DirectMusic可以满足LZ一些需求。
[解决办法]
建议找找开源的代码吧,看看有没有可以用的。也可以研究下DirectX
感觉DirectX与底层交互做的很强!可以试试吧。
[解决办法]
我上传了一个sound FFT资源,但不知为何,上传后没有显示,可能得等等,等可以下载了,你下载学习一下,或许会有参考价值
[解决办法]
www.speex.org开源的语音通讯项目,傅里叶啥的我不懂,不过那里面肯定有。

以前做过语音通讯,简单的处理还是知道的。
1、音量放大,把PCM数据直接乘以一个数就行了,减小同理,其实就是把波形在Y轴上放大、缩小。
2、声音叠加,把两段PCM数据直接相加就行了,相当于波形重叠。
[解决办法]
 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;
}

热点排行