十段均衡器的设计与实现
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
多媒体实验报告
姓名:李浩日期:2013.6.23
作业二:十段均衡器的设计与实现
一、实验任务
在实现音频IO(作业一)的基础上,编程实现一个具有GUI界面的十段均衡器小软件,实时对播放音乐进行音效调整。
2、
设计出的图形均衡器,通过调节面板上推拉键的上推或下拉,调节后便可以直观地反映出所调出的频响曲线,各个频率的提升和衰减情况被图化的显示出来。图示均衡采用恒定Q值(品质因数)技术,一个推拉键对应一个频点,这个频点对应一个频段,频点为一个带通滤波器的中心频率,带通滤波器通带宽度保持恒定,通带即为这个频段。
pSB->EnableScrollBar(ESB_ENABLE_BOTH );
pSB=(CScrollBar*) GetDlgItem(IDC_SCR7);
pSB->SetScrollRange(nMin, nMax);
pSB=(CScrollBar*) GetDlgItem(IDC_SCR8);
pSB->SetScrollRange(nMin, nMax);
pSB=(CScrollBar*) GetDlgItem(IDC_SCR9);
63Hz,125Hz,250Hz,500Hz,1000Hz,2000Hz,4000Hz,8000Hz,16000Hz,
依据这些频点按倍频程公式计算各个频段的边界频率,然后设计各频段的滤波
器,然后级联增益调节器再并接起来就构成了10 段图示均衡器。
4、
采用二阶IIR 带通滤波器级联实现十段图示均衡器。带通滤波器主要性能指
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
3、
图示均衡器由一个低通滤波器,一个高通滤波器和若干带通滤波器并联而成的滤波器组构成。这些构成均衡器的滤波器中心频率和带宽都是不变的,每个滤波器后接一个增益调节器。总输出为各个滤波器的加权求和。用户通过调节每个滤波器的输出增益,来改变均衡器的整体频响。
图示均衡器的整体实现框图,如下图所示:
对于10 段图示均衡器,1 倍频程图示均衡器的10 个中心频点为:31.5Hz,
// the minimized window.
HCURSOR CEQDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CEQDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
m_editg=-m_scrg;
if(isset)
{
for (int i=0;i<10;i++) bandpow[i]+=m_editg;
mwavefile.SetEQ(bandpow,10);
}
UpdateData(FALSE);
CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
{
// TODO: Add your message handler code here and/or call default
int nTemp1, nTemp2;
nTemp1=pScrollBar->GetScrollPos();
switch(nSBCode)
{
case SB_THUMBPOSITION:
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE);// Set big icon
pSB->SetScrollRange(nMin, nMax);
pSB=(CScrollBar*) GetDlgItem(IDC_SCR10);
pSB->SetScrollRange(nMin, nMax);
pSB=(CScrollBar*) GetDlgItem(IDC_SCRG);
pSB->SetScrollRange(nMin, nMax);
}
void CEQDlg::OnOK() //退出
{
mwavefile.CloseDev();
CDialog::OnOK();
}
void CEQDlg::OnBtnstart() //开始
{
//mwavefile.OpenWavFile((LPSTR)(LPCTSTR)wavname,&nchn, &bitpersmp,&smprate);
bandpow[4]=m_edit5=-m_scr5;
bandpow[5]=m_edit6=-m_scr6;
bandpow[6]=m_edit7=-m_scr7;
bandpow[7]=m_edit8=-m_scr8;
bandpow[8]=m_edit9=-m_scr9;
bandpow[9]=m_edit10=-m_scr10;
}
pScrollBar->SetScrollPos(nTemp1);
break;
case SB_LINERIGHT: //右箭头按钮
nTemp2=(nMax-nMin)/24;
if ((nTemp1+nTemp2)<nMax) { nTemp1+=nTemp2; }
else { nTemp1=nMax; }
mwavefile.PlayWav((LPSTR)(LPCSTR)wavname);
}
void CEQDlg::OnBtnset() //启用均衡
{
// TODO: Add your control notification handler code here
isset=true;
CScrollBar* pSB=(CScrollBar*) GetDlgItem(IDC_SCR1);
for (int i=0;i<10;i++) bandpow[i]=0;
m_PresentEf.SetCurSel(DEFAULT);
return TRUE; // return TRUE unless you set the focus to a control
}
void CEQDlg::OnSysCommand(UINT nID, LPARAM lParam)
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CEQDlg::OnPaint()
{
SetIcon(m_hIcon, FALSE);// Set small icon
// TODO: Add extra initialization here
CScrollBar* pSB=(CScrollBar*) GetDlgItem(IDC_SCR1);
pSB->SetScrollRange(nMin, nMax);
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
pScrollBar->SetScrollPos(nPos);
break;
case SB_LINELEFT: //左按钮
nTemp2=(nMax-nMin) / 24; //划为12等份
if ((nTemp1-nTemp2)>nMin)
{ nTemp1-=nTemp2; }
else
{
nTemp1=nMin;
pSB=(CScrollBar*) GetDlgItem(IDC_SCR2);
pSB->SetScrollRange(nMin, nMax);
pSB=(CScrollBar*) GetDlgItem(IDC_SCR3);
pSB->SetScrollRange(nMin, nMax);
pSB=(CScrollBar*) GetDlgItem(IDC_SCR4);
pSB->EnableScrollBar(ESB_ENABLE_BOTH );
pSB=(CScrollBar*) GetDlgItem(IDC_SCR2);
pSB->EnableScrollBar(ESB_ENABLE_BOTH );
pSB=(CScrollBar*) GetDlgItem(IDC_SCR3);
标包括中心频率、带宽、增益、品质因子等。
中心频率(CF):通带滤波器功率谱的值达到最大值时对应的频率。
带宽(BW):中心频率两边功率衰减3dB 时,对应的两个不同频率,分别为上、下截止频率,上、下截止频率之差为带宽。
增益(G):均衡器对于各种音效的实现依靠的最重要指标为增益曲线,一般以分贝为单位表示。
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
品质因子(Q):中心频率与带宽的比值,用来表征滤波器的锐度。
本实验所用参数列如表1 所示。本实验要求预设十种常见音乐均衡风格,每
种风格对应的滤波器增益如表2 所示。
Байду номын сангаас4、
BOOL CEQDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
pScrollBar->SetScrollPos(nTemp1);
break; }
UpdateData();
bandpow[0]=m_edit1=-m_scr1;
bandpow[1]=m_edit2=-m_scr2;
bandpow[2]=m_edit3=-m_scr3;
bandpow[3]=m_edit4=-m_scr4;
pSB->SetScrollRange(nMin, nMax);
pSB=(CScrollBar*) GetDlgItem(IDC_SCR5);
pSB->SetScrollRange(nMin, nMax);
pSB=(CScrollBar*) GetDlgItem(IDC_SCR6);
pSB->SetScrollRange(nMin, nMax);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
姓名:李浩日期:2013.6.23
作业二:十段均衡器的设计与实现
一、实验任务
在实现音频IO(作业一)的基础上,编程实现一个具有GUI界面的十段均衡器小软件,实时对播放音乐进行音效调整。
2、
设计出的图形均衡器,通过调节面板上推拉键的上推或下拉,调节后便可以直观地反映出所调出的频响曲线,各个频率的提升和衰减情况被图化的显示出来。图示均衡采用恒定Q值(品质因数)技术,一个推拉键对应一个频点,这个频点对应一个频段,频点为一个带通滤波器的中心频率,带通滤波器通带宽度保持恒定,通带即为这个频段。
pSB->EnableScrollBar(ESB_ENABLE_BOTH );
pSB=(CScrollBar*) GetDlgItem(IDC_SCR7);
pSB->SetScrollRange(nMin, nMax);
pSB=(CScrollBar*) GetDlgItem(IDC_SCR8);
pSB->SetScrollRange(nMin, nMax);
pSB=(CScrollBar*) GetDlgItem(IDC_SCR9);
63Hz,125Hz,250Hz,500Hz,1000Hz,2000Hz,4000Hz,8000Hz,16000Hz,
依据这些频点按倍频程公式计算各个频段的边界频率,然后设计各频段的滤波
器,然后级联增益调节器再并接起来就构成了10 段图示均衡器。
4、
采用二阶IIR 带通滤波器级联实现十段图示均衡器。带通滤波器主要性能指
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
3、
图示均衡器由一个低通滤波器,一个高通滤波器和若干带通滤波器并联而成的滤波器组构成。这些构成均衡器的滤波器中心频率和带宽都是不变的,每个滤波器后接一个增益调节器。总输出为各个滤波器的加权求和。用户通过调节每个滤波器的输出增益,来改变均衡器的整体频响。
图示均衡器的整体实现框图,如下图所示:
对于10 段图示均衡器,1 倍频程图示均衡器的10 个中心频点为:31.5Hz,
// the minimized window.
HCURSOR CEQDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CEQDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
m_editg=-m_scrg;
if(isset)
{
for (int i=0;i<10;i++) bandpow[i]+=m_editg;
mwavefile.SetEQ(bandpow,10);
}
UpdateData(FALSE);
CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
{
// TODO: Add your message handler code here and/or call default
int nTemp1, nTemp2;
nTemp1=pScrollBar->GetScrollPos();
switch(nSBCode)
{
case SB_THUMBPOSITION:
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE);// Set big icon
pSB->SetScrollRange(nMin, nMax);
pSB=(CScrollBar*) GetDlgItem(IDC_SCR10);
pSB->SetScrollRange(nMin, nMax);
pSB=(CScrollBar*) GetDlgItem(IDC_SCRG);
pSB->SetScrollRange(nMin, nMax);
}
void CEQDlg::OnOK() //退出
{
mwavefile.CloseDev();
CDialog::OnOK();
}
void CEQDlg::OnBtnstart() //开始
{
//mwavefile.OpenWavFile((LPSTR)(LPCTSTR)wavname,&nchn, &bitpersmp,&smprate);
bandpow[4]=m_edit5=-m_scr5;
bandpow[5]=m_edit6=-m_scr6;
bandpow[6]=m_edit7=-m_scr7;
bandpow[7]=m_edit8=-m_scr8;
bandpow[8]=m_edit9=-m_scr9;
bandpow[9]=m_edit10=-m_scr10;
}
pScrollBar->SetScrollPos(nTemp1);
break;
case SB_LINERIGHT: //右箭头按钮
nTemp2=(nMax-nMin)/24;
if ((nTemp1+nTemp2)<nMax) { nTemp1+=nTemp2; }
else { nTemp1=nMax; }
mwavefile.PlayWav((LPSTR)(LPCSTR)wavname);
}
void CEQDlg::OnBtnset() //启用均衡
{
// TODO: Add your control notification handler code here
isset=true;
CScrollBar* pSB=(CScrollBar*) GetDlgItem(IDC_SCR1);
for (int i=0;i<10;i++) bandpow[i]=0;
m_PresentEf.SetCurSel(DEFAULT);
return TRUE; // return TRUE unless you set the focus to a control
}
void CEQDlg::OnSysCommand(UINT nID, LPARAM lParam)
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CEQDlg::OnPaint()
{
SetIcon(m_hIcon, FALSE);// Set small icon
// TODO: Add extra initialization here
CScrollBar* pSB=(CScrollBar*) GetDlgItem(IDC_SCR1);
pSB->SetScrollRange(nMin, nMax);
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
pScrollBar->SetScrollPos(nPos);
break;
case SB_LINELEFT: //左按钮
nTemp2=(nMax-nMin) / 24; //划为12等份
if ((nTemp1-nTemp2)>nMin)
{ nTemp1-=nTemp2; }
else
{
nTemp1=nMin;
pSB=(CScrollBar*) GetDlgItem(IDC_SCR2);
pSB->SetScrollRange(nMin, nMax);
pSB=(CScrollBar*) GetDlgItem(IDC_SCR3);
pSB->SetScrollRange(nMin, nMax);
pSB=(CScrollBar*) GetDlgItem(IDC_SCR4);
pSB->EnableScrollBar(ESB_ENABLE_BOTH );
pSB=(CScrollBar*) GetDlgItem(IDC_SCR2);
pSB->EnableScrollBar(ESB_ENABLE_BOTH );
pSB=(CScrollBar*) GetDlgItem(IDC_SCR3);
标包括中心频率、带宽、增益、品质因子等。
中心频率(CF):通带滤波器功率谱的值达到最大值时对应的频率。
带宽(BW):中心频率两边功率衰减3dB 时,对应的两个不同频率,分别为上、下截止频率,上、下截止频率之差为带宽。
增益(G):均衡器对于各种音效的实现依靠的最重要指标为增益曲线,一般以分贝为单位表示。
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
品质因子(Q):中心频率与带宽的比值,用来表征滤波器的锐度。
本实验所用参数列如表1 所示。本实验要求预设十种常见音乐均衡风格,每
种风格对应的滤波器增益如表2 所示。
Байду номын сангаас4、
BOOL CEQDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
pScrollBar->SetScrollPos(nTemp1);
break; }
UpdateData();
bandpow[0]=m_edit1=-m_scr1;
bandpow[1]=m_edit2=-m_scr2;
bandpow[2]=m_edit3=-m_scr3;
bandpow[3]=m_edit4=-m_scr4;
pSB->SetScrollRange(nMin, nMax);
pSB=(CScrollBar*) GetDlgItem(IDC_SCR5);
pSB->SetScrollRange(nMin, nMax);
pSB=(CScrollBar*) GetDlgItem(IDC_SCR6);
pSB->SetScrollRange(nMin, nMax);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);