天天看點

優秀的音頻EQ均衡器音效源碼

不多說,直接上圖:這是一款客戶定制的播放器,播放器功能很強大,比如變速,變調,BPM節拍響應,淡入淡出,音量管家,EQ均衡器音效調節等等個性化功能:

優秀的音頻EQ均衡器音效源碼

我們着重推薦下EQ均衡器音效調節功能:

優秀的音頻EQ均衡器音效源碼

此款EQ均衡器音效調節效果,效果不遜于市面上大部分音效效果,如QQ音樂,酷狗,酷我,百度音樂等。支援各種音效個性化調節,由于客戶需求,沒有預設更多音效,完全可以實作如QQ均衡器界面功能:

優秀的音頻EQ均衡器音效源碼

我們的均衡器優勢在于,頻率段數可以定制,比如10段,15段,20段,30段均可,每段的頻點可以設定,可以預設更多效果。

貼點調用代碼吧

// EQDlg.cpp : 實作檔案
//

#include "stdafx.h"
#include "DanceMusic.h"
#include "EQDlg.h"
#include "DanceMusic.h"
#include "DanceMusicDlg.h"
#include "MusicDlg.h"
// CEQDlg 對話框

IMPLEMENT_DYNAMIC(CEQDlg, CDialog)

CEQDlg::CEQDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CEQDlg::IDD, pParent)
{

}

CEQDlg::~CEQDlg()
{
}

void CEQDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_SLIDER1, m_eq[0]);
	DDX_Control(pDX, IDC_SLIDER2, m_eq[1]);
	DDX_Control(pDX, IDC_SLIDER3, m_eq[2]);
	DDX_Control(pDX, IDC_SLIDER4, m_eq[3]);
	DDX_Control(pDX, IDC_SLIDER5, m_eq[4]);
	DDX_Control(pDX, IDC_SLIDER6, m_eq[5]);
	DDX_Control(pDX, IDC_SLIDER7, m_eq[6]);
	DDX_Control(pDX, IDC_SLIDER8, m_eq[7]);
	DDX_Control(pDX, IDC_SLIDER9, m_eq[8]);
	DDX_Control(pDX, IDC_SLIDER10, m_eq[9]);
	DDX_Control(pDX, IDC_SLIDER11, m_eq[10]);
	DDX_Control(pDX, IDC_SLIDER12, m_eq[11]);
	DDX_Control(pDX, IDC_SLIDER13, m_eq[12]);
	DDX_Control(pDX, IDC_SLIDER14, m_eq[13]);
	DDX_Control(pDX, IDC_SLIDER15, m_eq[14]);
	DDX_Control(pDX, IDC_SLIDER16, m_eq[15]);
	DDX_Control(pDX, IDC_SLIDER17, m_eq[16]);
	DDX_Control(pDX, IDC_SLIDER18, m_eq[17]);

	DDX_Control(pDX, IDC_ST19, m_eqshow[0]);
	DDX_Control(pDX, IDC_ST20, m_eqshow[1]);
	DDX_Control(pDX, IDC_ST21, m_eqshow[2]);

	DDX_Control(pDX, IDC_ST22, m_eqshow[3]);
	DDX_Control(pDX, IDC_ST23, m_eqshow[4]);
	DDX_Control(pDX, IDC_ST24, m_eqshow[5]);

	DDX_Control(pDX, IDC_ST25, m_eqshow[6]);
	DDX_Control(pDX, IDC_ST26, m_eqshow[7]);
	DDX_Control(pDX, IDC_ST27, m_eqshow[8]);

	DDX_Control(pDX, IDC_ST28, m_eqshow[9]);
	DDX_Control(pDX, IDC_ST29, m_eqshow[10]);
	DDX_Control(pDX, IDC_ST30, m_eqshow[11]);

	DDX_Control(pDX, IDC_ST31, m_eqshow[12]);
	DDX_Control(pDX, IDC_ST32, m_eqshow[13]);
	DDX_Control(pDX, IDC_ST33, m_eqshow[14]);

	DDX_Control(pDX, IDC_ST34, m_eqshow[15]);
	DDX_Control(pDX, IDC_ST35, m_eqshow[16]);
	DDX_Control(pDX, IDC_ST36, m_eqshow[17]);

	DDX_Control(pDX, IDC_CHECK1, m_check);

}


BEGIN_MESSAGE_MAP(CEQDlg, CDialog)
	ON_BN_CLICKED(IDC_BUTTON1, &CEQDlg::OnBnClickedButton1)
	ON_BN_CLICKED(IDC_CHECK1, &CEQDlg::OnBnClickedCheck1)
	ON_WM_VSCROLL()
	ON_BN_CLICKED(IDC_BUTTON2, &CEQDlg::OnBnClickedButton2)
	ON_BN_CLICKED(IDC_BUTTON3, &CEQDlg::OnBnClickedButton3)
END_MESSAGE_MAP()


// CEQDlg 消息處理程式


 
BOOL CEQDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	for(int i=0;i<MACEQ;i++)
	{
		if(i==3||i==4||i==5||i==6||i==7)
			m_eqshow[i].SetFontSize2(10);
	}

	CString szDefault="40,60,80,100,120,150,200,250,300,400,500,600,1000,1800,3100,5300,9200,15800";
	CString szEQ=theApp.m_main->m_inifile.GetValue("EQSet","Frequency","40,60,80,100,120,150,200,250,300,400,500,600,1000,1800,3100,5300,9200,15800");
	CStringArray tempEQs;
	int nTempCount=GetStringsFromSpace(szEQ,tempEQs,",");
	if(nTempCount<MACEQ)
		szEQ=szDefault;

	CString szDefaultDB="0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0";
	CString szDB=theApp.m_main->m_inifile.GetValue("EQSet","DBSave","0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0");
	CStringArray tempDBs;
	int nTempCount2=GetStringsFromSpace(szDB,tempDBs,",");
	if(nTempCount2<MACEQ)
		szDB=szDefaultDB;
	GetStringsFromSpace(szDB,tempDBs,",");

	m_pmain->m_player.m_x.EQInitString(szEQ);
	m_check.SetCheck(1);
	m_pmain->m_player.m_x.EQEnable(m_check.GetCheck());
	for(int i=0;i<MACEQ;i++)
	{
		int nDB=atof(tempDBs[i]);
		m_eq[i].SetRange(-12,12);
		m_eq[i].SetPos(1);
		m_eq[i].SetPos(0-nDB);
		m_pmain->m_player.m_x.EQSet(i,nDB);
		this->GetDlgItem(IDC_ST1+i)->SetWindowTextA(ItoA(nDB));
	}
	CStringArray EQs;
	int nCount=GetStringsFromSpace(szEQ,EQs,",");
	for(int i=0;i<nCount;i++)
	{
		m_eqshow[i].SetWindowTextA(FormatFrequency(atof(EQs[i]))/*+"Hz"*/);
		//this->GetDlgItem(IDC_ST19+i)->SetWindowTextA(FormatFrequency(atof(EQs[i]))/*+"Hz"*/);
	}
	return TRUE;  // return TRUE unless you set the focus to a control
	// 異常: OCX 屬性頁應傳回 FALSE
}

void CEQDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	for(int i=0;i<MACEQ;i++)
	{
		if(pScrollBar->GetSafeHwnd()==m_eq[i].GetSafeHwnd())
		{
			int nPos=0-m_eq[i].GetPos();
			TRACE("pos:%d\n",nPos);
			m_pmain->m_player.m_x.EQSet(i,nPos);
			this->GetDlgItem(IDC_ST1+i)->SetWindowTextA(ItoA(nPos)/*+"db"*/);
			SaveDBs();
			break;
		}
	}


	CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
}

void CEQDlg::OnCancel()
{
	ShowWindow(SW_HIDE);
}

void CEQDlg::OnOK()
{
	ShowWindow(SW_HIDE);
}

void CEQDlg::OnBnClickedButton1()
{
	for(int i=0;i<MACEQ;i++)
	{
		m_eq[i].SetPos(0);
		m_pmain->m_player.m_x.EQSet(i,0);
		this->GetDlgItem(IDC_ST1+i)->SetWindowTextA(ItoA(0));
	}

	SaveDBs();

}

void CEQDlg::SaveDBs()
{
	CString szF;
	for(int i=0;i<MACEQ;i++)
	{
		int nPos=0-m_eq[i].GetPos();
		szF+=ItoA(nPos);
		if(i!=MACEQ-1)
			szF+=",";
	}
	theApp.m_main->m_inifile.SetValue("EQSet","DBSave",szF);

}

void CEQDlg::OnBnClickedCheck1()
{
	m_pmain->m_player.m_x.EQEnable(m_check.GetCheck());
}

void CEQDlg::OnBnClickedButton2()//自定義頻點
{
	m_pmain->m_player.m_x.EQEnable(0);
	CEQSetDlg dlg;
	if(dlg.DoModal()==IDOK)
	{
		CStringArray EQs;
		int nCount=GetStringsFromSpace(dlg.m_szFs,EQs,",");
		for(int i=0;i<nCount;i++)
		{
			m_eqshow[i].SetWindowTextA(FormatFrequency(atof(EQs[i]))/*+"Hz"*/);
			//this->GetDlgItem(IDC_ST19+i)->SetWindowTextA(FormatFrequency(atof(EQs[i]))/*+"Hz"*/);
		}
		m_pmain->m_player.m_x.EQInitString(dlg.m_szFs);
		m_pmain->m_player.m_x.EQEnable(m_check.GetCheck());	
		OnBnClickedButton1();//修改後複位
	}
	else
		m_pmain->m_player.m_x.EQEnable(m_check.GetCheck());	
}

void CEQDlg::OnBnClickedButton3()
{
	ShowWindow(SW_HIDE);
}
           

這是調用代碼段:

實際上,封裝好的EQ設定方法就3個函數:

typedef void(*pEQInitString)(CString szEQ);
typedef void(*pEQEnable)(int nEnableEQ);
typedef void(*pEQSet)(int nIndex,double dbDB); 
CString szDefault="40,60,80,100,120,150,200,250,300,400,500,600,1000,1800,3100,5300,9200,15800";
EQInitString(szDefault);    
for(int i=0;i<MACEQ;i++)   
{       
 int nDB=atof(tempDBs[i]);       
 EQSet(i,nDB);    
}
           

調用挺簡單的是吧。

如果大家有這方面需求,可以交流合作的,有需要發DEMO的也可以聯系我。這個代碼可以出售,由于代碼是純C++編寫,可以移植應用到各個平台。歡迎騷擾:QQ35744025,謝謝大家!

https://download.csdn.net/download/xjb2006/13459807

應讀者強烈要求做了一個簡單的DEMO,歡迎大家免費下載下傳品鑒,謝謝大家!