请问如何在VC中实现音频频谱显示?

GDXY 2003-03-20 10:00:09
请问如何在VC中实现捕捉声卡的全部音频输出信号,并且进行音频频谱显示?
能给个实现的思路吗?谢谢!
...全文
439 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
winphoenix 2003-03-21
  • 打赏
  • 举报
回复
程序员大本营上好像有个例子
CCBeyond 2003-03-21
  • 打赏
  • 举报
回复
最近我正在给自己的采集程序加入对音频信号的监视,想通过VFW实现。
有兴趣的话交流交流...
GDXY 2003-03-21
  • 打赏
  • 举报
回复
TO uhlan(uhlan): 这是好像一个混音的代码吧?在我不打开任何wav文件的情况下,比如我只是在播放音乐CD,它能捕捉到声卡的信号吗?

我是想在任何时候捕捉到声卡的信号,这有可能实现吗?

TO CCBeyond(西别_&_钱不够用): 我的邮箱是gdxy1@sina.com 谢谢!
uhlan 2003-03-21
  • 打赏
  • 举报
回复
// wavemix.h : main header file for the WAVEMIX application
//
#if !defined(AFX_WAVEMIX_H__54F4AF66_CE37_11D1_94F8_0000B431BBA1__INCLUDED_)
#define AFX_WAVEMIX_H__54F4AF66_CE37_11D1_94F8_0000B431BBA1__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif

#include "resource.h" // main symbols
/////////////////////////////////////////////////////////////////////////////
#include "windows.h"
#include "mmsystem.h"
#ifdef WIN32
#define WAVDATA BYTE
#else
#define WAVDATA BYTE _huge
#define WAVEFORMATEX PCMWAVEFORMAT
#endif

#ifdef WIN32
#define WAV16DATA WORD
#else
#define WAV16DATA WORD _huge
#endif

class MWAVE
{
private:
BOOL OpenFlage;
DWORD DataSize;
HGLOBAL hData;
WAVDATA* lpData;

PCMWAVEFORMAT pFormat;
WAVEHDR WaveHead;
HWAVEOUT hWaveOut;

public:
MWAVE(){memset(this,0,sizeof(MWAVE));};
~MWAVE(){Close();};
int Open(char*); //打开一个WAV文件
int Play(HWND); //播放一个WAV文件
int Add(char*); //往正在播放的WAV设备中添加WAV 文件
int Stop(); //停止播放
int Close(); //关闭设备
};

#endif // !defined(AFX_WAVEMIX_H__54F4AF66_CE37_11D1_94F8_0000B431BBA1__INCLUDED_)

// wavemix.cpp:Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "wavemix.h"
#include "wavemixDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

///////////////////////////////////////////////////////////////////////
// wavemix Class
//////////////////////////////////////////////////////////////////////

int MWAVE::Open(char* name)
{
HMMIO hMmio;
MMCKINFO pinfo;
MMCKINFO cinfo;

if(hMmio)Close();

//打开WAV文件,返回一个HMMIO句柄
hMmio=mmioOpen(name,NULL,MMIO_READ);
if(!hMmio)return FALSE;
OpenFlage=1;

//查找父块"wave";
pinfo.fccType=mmioFOURCC('W','A','V','E');
if(mmioDescend(hMmio,&pinfo,NULL,MMIO_FINDRIFF))goto FALSE_END;

//查找子块"fmt" parent"riff";
cinfo.ckid=mmioFOURCC('f','m','t',' ');
if(mmioDescend(hMmio,&cinfo,&pinfo,MMIO_FINDCHUNK))
goto FALSE_END;

mmioRead(hMmio,(LPSTR)&pFormat,sizeof(PCMWAVEFORMAT));//cinfo.cksize);
if(pFormat.wf.wFormatTag!=WAVE_FORMAT_PCM)
goto FALSE_END;

//跳入块"FMT"
mmioAscend(hMmio,&cinfo,0);

//查找数据块
cinfo.ckid=mmioFOURCC('d','a','t','a');
if(mmioDescend(hMmio,&cinfo,&pinfo,MMIO_FINDCHUNK))
goto FALSE_END;
DataSize=cinfo.cksize;

//读取数据
hData=GlobalAlloc(GMEM_MOVEABLE
| GMEM_SHARE,DataSize);
lpData=(WAVDATA*)GlobalLock(hData);
if( !hData || !lpData ) goto FALSE_END;
if(mmioRead(hMmio,(HPSTR)lpData,DataSize)
!=(LRESULT)DataSize)
goto FALSE_END;

//close and return
mmioClose(hMmio,MMIO_FHOPEN);
return TRUE;

FALSE_END:
if(hMmio)mmioClose(hMmio,MMIO_FHOPEN);
if(lpData)LocalUnlock(hData);
if(hData)GlobalFree(hData);
memset(this,0,sizeof(MWAVE));
return 0;
}

int MWAVE::Play(HWND hP)
{
if(!OpenFlage)return FALSE;

//检测系统播放功能
if(waveOutOpen(NULL,WAVE_MAPPER,
(WAVEFORMATEX*)&pFormat,NULL,
NULL,WAVE_FORMAT_QUERY))
return Close();

if(waveOutOpen(&hWaveOut,WAVE_MAPPER,
( WAVEFORMATEX*)&pFormat,(DWORD)hP,
0,CALLBACK_WINDOW))
return Close();

WaveHead.lpData=(LPSTR)lpData;
WaveHead.dwBufferLength=DataSize;
WaveHead.dwFlags=0L;
WaveHead.dwLoops=0L;

往WAV设备中添加数据
if(waveOutPrepareHeader(hWaveOut,&WaveHead,
sizeof(WAVEHDR)))
return Close();

if(waveOutWrite(hWaveOut,&WaveHead,sizeof(WAVEHDR)))
return Close();

return TRUE;
}

//#define min(a, b) (((a) < (b)) ? (a) : (b))

int MWAVE::Add(char* name)
{
register int x;
if(!OpenFlage)return Open(name);

MWAVE wav;
if(!wav.Open(name))return FALSE;

MMTIME time;
//获得WAV文件当前播放位置
time.wType=TIME_BYTES;
if(waveOutGetPosition(hWaveOut,&time,sizeof(MMTIME)))
time.u.cb=0;
DWORD start=((time.u.cb>>1)<<1);
DWORD end=min(DataSize_start,wav.DataSize);

register WAVDATA* lpd=lpData+start;
for(register DWORD i=0;i<end;i++)
{
//将两组WAV文件数据相加,并检测数据大小是否合法,如果//数据大小越界,则分别取最大值和最小值
x=(((*(lpd+i))+(*(wav.lpData+i))))_128;
if(x<0)x=0;
if(x>255)x=255;
*(lpd+i)=(BYTE)(x);
}

return TRUE;
}

int MWAVE::Stop()
{return !waveOutReset(hWaveOut);}

int MWAVE::Close()
{
if(hWaveOut)
{
waveOutReset(hWaveOut);
waveOutClose(hWaveOut);
waveOutUnprepareHeader(hWaveOut,&WaveHead,
sizeof(WAVEHDR));
}
if(lpData)LocalUnlock(hData);
if(hData)GlobalFree(hData);
memset(this,0,sizeof(MWAVE));
return 0;
}
CCBeyond 2003-03-21
  • 打赏
  • 举报
回复
我发给你一个
GDXY 2003-03-20
  • 打赏
  • 举报
回复
是www.vcfan.com吧?我去看了,但是那个网站没有搜索功能,我找不到啊?在哪个栏目里面?能不能麻烦说详细一些?谢谢了
9731boy 2003-03-20
  • 打赏
  • 举报
回复
www.vcfan.net有一个例程

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧