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

📄 gameswf_sound_handler_sdl.cpp

📁 一个开源的Flash 播放器,可以在Windows/Linux 上运行
💻 CPP
字号:
// gameswf_sound_handler_sdl.cpp	-- Thatcher Ulrich http://tulrich.com 2003// This source code has been donated to the Public Domain.  Do// whatever you want with it.// A gameswf::sound_handler that uses SDL_mixer for output#include "gameswf/gameswf.h"#include "base/container.h"#include "SDL_mixer.h"#include "gameswf/gameswf_log.h"#include "gameswf/gameswf_types.h"	// for IF_VERBOSE_* macros// Use SDL_mixer to handle gameswf sounds.struct SDL_sound_handler : gameswf::sound_handler{	bool	m_opened;	bool	m_stereo;	int	m_sample_rate;	Uint16 m_format;	array<Mix_Chunk*>	m_samples;	#define	SAMPLE_RATE 44100	#define MIX_CHANNELS 8	#define CHANNELS 2		//stereo - 2, mono - 1	#define BUFSIZE 4096		// for 44100 bufsize 1024 is small	SDL_sound_handler()		:		m_opened(false),		m_stereo(false),		m_sample_rate(0),		m_format(0)	{		// !!! some drivers on Linux always open audio with channels=2		if (Mix_OpenAudio(SAMPLE_RATE, AUDIO_S16SYS, CHANNELS, BUFSIZE) != 0)		{			gameswf::log_error("can't open SDL_mixer: %s\n", Mix_GetError());		}		else		{			m_opened = true;     			Mix_AllocateChannels(MIX_CHANNELS);			Mix_Volume(-1, MIX_MAX_VOLUME);			// get and print the audio format in use			int channels;			int num_times_opened = Mix_QuerySpec(&m_sample_rate, &m_format, &channels);			UNUSED(num_times_opened);			m_stereo = channels == 2 ? true : false;						const char *format_str = "Unknown";			switch (m_format)			{			case AUDIO_U8: format_str = "U8"; break;			case AUDIO_S8: format_str = "S8"; break;			case AUDIO_U16LSB: format_str = "U16LSB"; break;			case AUDIO_S16LSB: format_str = "S16LSB"; break;			case AUDIO_U16MSB: format_str = "U16MSB"; break;			case AUDIO_S16MSB: format_str = "S16MSB"; break;			}	    			// @@ Usually I don't care about this.  Need a IF_VERBOSE_SOUND or something.			// IF_VERBOSE_DEBUG(			// 	gameswf::log_msg("SDL_mixer: opened %d times, frequency=%dHz, format=%s, stereo=%s\n",			// 		     num_times_opened,			// 		     m_sample_rate,			// 		     format_str,			// 		     m_stereo ? "yes" : "no"));			// char name[32];			// IF_VERBOSE_DEBUG(			// 	gameswf::log_msg("Using audio driver: %s\n", SDL_AudioDriverName(name, 32)));		}	}	~SDL_sound_handler()	{		if (m_opened)		{			Mix_CloseAudio();			for (int i = 0, n = m_samples.size(); i < n; i++)			{				if (m_samples[i])				{					Mix_FreeChunk(m_samples[i]);				}			}		}		else		{			assert(m_samples.size() == 0);		}	}	virtual int	create_sound(		void* data,		int data_bytes,		int sample_count,		format_type format,		int sample_rate,		bool stereo)	// Called by gameswf to create a sample.  We'll return a sample ID that gameswf	// can use for playing it.	{		if (m_opened == false)		{			return 0;		}		Sint16*	adjusted_data = 0;		int	adjusted_size = 0;		Mix_Chunk*	sample = 0;		switch (format)		{		case FORMAT_RAW:			convert_raw_data(&adjusted_data, &adjusted_size, data, sample_count, 1, sample_rate, stereo);			break;		case FORMAT_NATIVE16:			convert_raw_data(&adjusted_data, &adjusted_size, data, sample_count, 2, sample_rate, stereo);			break;		case FORMAT_MP3:#ifdef GAMESWF_MP3_SUPPORT			extern void convert_mp3_data(Sint16 **adjusted_data, int *adjusted_size, void *data, const int sample_count, const int sample_size, const int sample_rate, const bool stereo);			if (1) {				Sint16*	x_adjusted_data = 0;				int	x_adjusted_size = 0;				Mix_Chunk*	x_sample = 0;				convert_mp3_data(&x_adjusted_data, &x_adjusted_size, data, sample_count, 0, sample_rate, stereo);				/* convert_mp3_data doesn't ACTUALLY convert				   samplerate, so... */				convert_raw_data(&adjusted_data, &adjusted_size, x_adjusted_data, sample_count, 0, sample_rate, stereo);				if (x_adjusted_data) {					delete x_adjusted_data;				}			} else {				convert_mp3_data(&adjusted_data, &adjusted_size, data, sample_count, 0, sample_rate, stereo);			}#else			IF_VERBOSE_DEBUG(gameswf::log_error("mp3 format sound requested; this demo does not handle mp3\n"));#endif			break;		default:			// Unhandled format.			IF_VERBOSE_DEBUG(gameswf::log_error("unknown format sound requested; this demo does not handle it\n"));			break;		}		if (adjusted_data)		{			sample = Mix_QuickLoad_RAW((unsigned char*) adjusted_data, adjusted_size);			Mix_VolumeChunk(sample, MIX_MAX_VOLUME);	// full volume by default		}		m_samples.push_back(sample);		return m_samples.size() - 1;	}	virtual void	play_sound(int sound_handle, int loop_count /* other params */)	// Play the index'd sample.	{		if (sound_handle >= 0 && sound_handle < m_samples.size())		{			if (m_samples[sound_handle])			{				// Play this sample on the first available channel.				Mix_PlayChannel(-1, m_samples[sound_handle], loop_count);			}		}	}		virtual void	stop_sound(int sound_handle)	{		if (sound_handle < 0 || sound_handle >= m_samples.size())		{			// Invalid handle.			return;		}		for (int i = 0; i < MIX_CHANNELS; i++)		{			Mix_Chunk*	playing_chunk = Mix_GetChunk(i);			if (Mix_Playing(i)			    && playing_chunk == m_samples[sound_handle])			{				// Stop this channel.				Mix_HaltChannel(i);			}		}	}	virtual void	delete_sound(int sound_handle)	// gameswf calls this when it's done with a sample.	{		if (sound_handle >= 0 && sound_handle < m_samples.size())		{			Mix_Chunk*	chunk = m_samples[sound_handle];			if (chunk)			{				delete [] (chunk->abuf);				Mix_FreeChunk(chunk);				m_samples[sound_handle] = 0;			}		}	}	virtual void convert_raw_data(		Sint16** adjusted_data,		int* adjusted_size,		void* data,		int sample_count,		int sample_size,		int sample_rate,		bool stereo)	// VERY crude sample-rate & sample-size conversion.  Converts	// input data to the SDL_mixer output format (SAMPLE_RATE,	// stereo, 16-bit native endianness)	{// 		// xxxxx debug pass-thru// 		{// 			int	output_sample_count = sample_count * (stereo ? 2 : 1);// 			Sint16*	out_data = new Sint16[output_sample_count];// 			*adjusted_data = out_data;// 			*adjusted_size = output_sample_count * 2;	// 2 bytes per sample// 			memcpy(out_data, data, *adjusted_size);// 			return;// 		}// 		// xxxxx		// simple hack to handle dup'ing mono to stereo		if ( !stereo && m_stereo)		{			sample_rate >>= 1;		}		 // simple hack to lose half the samples to get mono from stereo		if ( stereo && !m_stereo)		{			sample_rate <<= 1; 		}		// Brain-dead sample-rate conversion: duplicate or		// skip input samples an integral number of times.		int	inc = 1;	// increment		int	dup = 1;	// duplicate		if (sample_rate > m_sample_rate)		{			inc = sample_rate / m_sample_rate;		}		else if (sample_rate < m_sample_rate)		{			dup = m_sample_rate / sample_rate;		}		int	output_sample_count = (sample_count * dup) / inc;		Sint16*	out_data = new Sint16[output_sample_count];		*adjusted_data = out_data;		*adjusted_size = output_sample_count * 2;	// 2 bytes per sample		if (sample_size == 1)		{			// Expand from 8 bit to 16 bit.			Uint8*	in = (Uint8*) data;			for (int i = 0; i < output_sample_count; i++)			{				Uint8	val = *in;				for (int j = 0; j < dup; j++)				{					*out_data++ = (int(val) - 128);				}				in += inc;			}		}		else		{			// 16-bit to 16-bit conversion.			Sint16*	in = (Sint16*) data;			for (int i = 0; i < output_sample_count; i += dup)			{				Sint16	val = *in;				for (int j = 0; j < dup; j++)				{					*out_data++ = val;				}				in += inc;			}		}	}};gameswf::sound_handler*	gameswf::create_sound_handler_sdl()// Factory.{	return new SDL_sound_handler;}// Local Variables:// mode: C++// c-basic-offset: 8 // tab-width: 8// indent-tabs-mode: t// End:

⌨️ 快捷键说明

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