⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dg_audio_renderer.cpp

📁 彩信浏览器
💻 CPP
字号:
// This file is part of Ambulant Player, www.ambulantplayer.org.//// Copyright (C) 2003-2007 Stichting CWI, // Kruislaan 413, 1098 SJ Amsterdam, The Netherlands.//// Ambulant Player is free software; you can redistribute it and/or modify// it under the terms of the GNU Lesser General Public License as published by// the Free Software Foundation; either version 2.1 of the License, or// (at your option) any later version.//// Ambulant Player is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public License// along with Ambulant Player; if not, write to the Free Software// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA/*  * @$Id: dg_audio_renderer.cpp,v 1.6 2007/02/12 14:14:50 jackjansen Exp $  */#include "ambulant/gui/dg/dg_audio_renderer.h"#include "ambulant/lib/win32/win32_error.h"#include "ambulant/lib/logger.h"//#define AM_DBG if(1)#ifndef AM_DBG#define AM_DBG if(0)#endifusing namespace ambulant;gui::dg::audio_renderer::audio_renderer():	m_hWaveOut(NULL) {}	gui::dg::audio_renderer::~audio_renderer() {	if(m_hWaveOut) stop();}//static bool gui::dg::audio_renderer::can_play(WAVEFORMATEX& wfx) {		DWORD flags = WAVE_FORMAT_QUERY;	MMRESULT mmres = waveOutOpen(NULL, WAVE_MAPPER, &wfx, 0, 0, flags);	if(mmres != MMSYSERR_NOERROR) {		seterror("waveOutOpen()", mmres);		return false;	}	return true;}bool gui::dg::audio_renderer::open(int nSamplesPerSec, int nChannels, int depth) {	int wBitsPerSample = depth; 	int nBlockAlign = nChannels*wBitsPerSample/8; 	long nAvgBytesPerSec = nBlockAlign*nSamplesPerSec;	WAVEFORMATEX wfx = {WAVE_FORMAT_PCM, // format type		WORD(nChannels), // number of channels		DWORD(nSamplesPerSec), // sample rate		DWORD(nAvgBytesPerSec), // for buffer estimation		WORD(nBlockAlign), // block size of data		WORD(wBitsPerSample), //number of bits per sample of mono data		WORD(0) // the count in bytes of the size of the extra info after this field		};	return open(wfx);}bool gui::dg::audio_renderer::open(WAVEFORMATEX& wfx) {	// waveOutReset() blocks with callbacks 	//MMRESULT mmres = waveOutOpen(&m_hWaveOut, WAVE_MAPPER, &wfx, 	//	reinterpret_cast<DWORD_PTR>(audio_renderer::callback), 	//	reinterpret_cast<DWORD_PTR>(this), CALLBACK_FUNCTION);	if(m_hWaveOut) stop();	MMRESULT mmres = waveOutOpen(&m_hWaveOut, WAVE_MAPPER, &wfx, 		0, 0, CALLBACK_NULL);	if(mmres != MMSYSERR_NOERROR) {		seterror("waveOutOpen()", mmres);		return false;	}	mmres = waveOutPause(m_hWaveOut);	if(mmres != MMSYSERR_NOERROR) {		seterror("waveOutPause()", mmres);		return false;	}	return true;}void gui::dg::audio_renderer::close() {	if(m_hWaveOut == NULL) return;	MMRESULT mmres = waveOutClose(m_hWaveOut);	if(mmres != MMSYSERR_NOERROR)		seterror("waveOutClose()", mmres);	m_hWaveOut = NULL;}void gui::dg::audio_renderer::start() {	resume();}	void gui::dg::audio_renderer::pause() { 	if(m_hWaveOut == NULL) return;	MMRESULT mmres = waveOutPause(m_hWaveOut);	if(mmres != MMSYSERR_NOERROR)		seterror("waveOutPause()", mmres);		}void gui::dg::audio_renderer::resume() { 	if(m_hWaveOut == NULL) return;	MMRESULT mmres = waveOutRestart(m_hWaveOut);	if(mmres != MMSYSERR_NOERROR)		seterror("waveOutRestart()", mmres);}void gui::dg::audio_renderer::stop() {	if(m_hWaveOut == NULL) return;	MMRESULT mmres = waveOutReset(m_hWaveOut);	if(mmres != MMSYSERR_NOERROR)		seterror("waveOutReset()", mmres);	update();	if(!m_audio_data.empty())		lib::logger::get_logger()->warn("NOT DONE BUFFERS: %u", m_audio_data.size());	clear_data();	close();}// static void gui::dg::audio_renderer::seterror(const char *funcname, MMRESULT mmres) {	if(mmres == MMSYSERR_NOERROR) return;	switch(mmres) {		case MMSYSERR_INVALHANDLE:			seterror(funcname, "MMSYSERR_INVALHANDLE, Specified device handle is invalid.");			break;		case MMSYSERR_BADDEVICEID:			seterror(funcname, "MMSYSERR_BADDEVICEID, Specified device identifier is out of range.");			break;		case MMSYSERR_NODRIVER:			seterror(funcname, "MMSYSERR_NODRIVER, No device driver is present");			break;		case MMSYSERR_NOMEM:			seterror(funcname, "MMSYSERR_NOMEM, Unable to allocate or lock memory.");			break;		case WAVERR_BADFORMAT:			seterror(funcname, "WAVERR_BADFORMAT, Attempted to open with an unsupported waveform-audio format.");			break;		case WAVERR_SYNC:			seterror(funcname, "WAVERR_SYNC, Device is synchronous but waveOutOpen was called without using the WAVE_ALLOWSYNC flag");			break;		case WAVERR_STILLPLAYING:			seterror(funcname, "WAVERR_STILLPLAYING, There are still buffers in the queue");			break;		default:			lib::logger::get_logger()->error("%s failed, Error: %u", funcname, mmres);			break;	}}// static void gui::dg::audio_renderer::seterror(const char *funcname, const char *msg) {	lib::logger::get_logger()->error("%s failed, %s", funcname, msg);}// static void gui::dg::audio_renderer::seterror(const char *funcname) {	lib::logger::get_logger()->error("%s failed", funcname);}bool gui::dg::audio_renderer::write(audio_buffer* p) {	m_audio_data.push_back(WAVEHDR());	WAVEHDR& waveHdr = m_audio_data.back();	memset(&waveHdr, 0, sizeof(WAVEHDR));	waveHdr.lpData = const_cast<char*>(p->data());	waveHdr.dwBufferLength = DWORD(p->length());	waveHdr.dwUser = reinterpret_cast<DWORD_PTR>(p);	MMRESULT mmres = waveOutPrepareHeader(m_hWaveOut, &waveHdr, sizeof(WAVEHDR));	if(mmres != MMSYSERR_NOERROR)		seterror("waveOutPrepareHeader()");	mmres = waveOutWrite(m_hWaveOut, &waveHdr, sizeof(WAVEHDR));	if(mmres != MMSYSERR_NOERROR)		seterror("waveOutWrite()");	return (mmres == MMSYSERR_NOERROR);}void gui::dg::audio_renderer::update() {	while(!m_audio_data.empty()) {		WAVEHDR& waveHdr = m_audio_data.front();		if((waveHdr.dwFlags & WHDR_DONE) == WHDR_DONE) {			if(m_hWaveOut) {				MMRESULT mmres = waveOutUnprepareHeader(m_hWaveOut, &waveHdr, sizeof(WAVEHDR));				if(mmres != MMSYSERR_NOERROR)					seterror("waveOutUnprepareHeader()");			}			audio_buffer *p =  reinterpret_cast<audio_buffer*>(waveHdr.dwUser);			delete p;			m_audio_data.pop_front();		} else break;	}}void gui::dg::audio_renderer::unprepare_front() {	if(!m_audio_data.empty()) {		WAVEHDR& waveHdr = m_audio_data.front();		if(m_hWaveOut) {			MMRESULT mmres = waveOutUnprepareHeader(m_hWaveOut, &waveHdr, sizeof(WAVEHDR));			if(mmres != MMSYSERR_NOERROR)				seterror("waveOutUnprepareHeader()");		}		audio_buffer *p =  reinterpret_cast<audio_buffer*>(waveHdr.dwUser);		delete p;		m_audio_data.pop_front();	}}void gui::dg::audio_renderer::clear_data() {	while(has_audio_data()) {		WAVEHDR& waveHdr = m_audio_data.front();		audio_buffer *p =  reinterpret_cast<audio_buffer*>(waveHdr.dwUser);		delete p;		m_audio_data.pop_front();	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -