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

📄 simplemixer.c

📁 一段linux下用sdl实现的混音程序
💻 C
字号:
/* * SimpleMixer 1.1 * * Simple sound mixing example for SDL. * * (C) David Olofson, 2003 */#include <stdlib.h>#include <signal.h>#include "SDL.h"#include "SDL_audio.h"#define	SM_SOUNDS	4#define	SM_VOICES	4typedef struct{	Uint8	*data;	Uint32	length;} SM_sound;typedef struct{	Sint16	*data;	int	length;	int	position;	int	l_vol;	int	r_vol;} SM_voice;SM_sound sounds[SM_SOUNDS];SM_voice voices[SM_VOICES];SDL_AudioSpec audiospec;int die = 0;void sm_play(unsigned voice, unsigned sound, float lvol, float rvol){	if(voice >= SM_VOICES || sound >= SM_SOUNDS)		return;	/* Stop voice */	voices[voice].data = NULL;	/* Reprogram */	voices[voice].length = sounds[sound].length / 2;	voices[voice].position = 0;	voices[voice].l_vol = (int)(lvol * 256.0);	voices[voice].r_vol = (int)(rvol * 256.0);	/* Start! */	voices[voice].data = (Sint16*)(sounds[sound].data);}static void sm_mixer(void *ud, Uint8 *stream, int len){	int vi, s;	Sint16 *buf = (Sint16 *)stream;	/* Clear the buffer */	memset(buf, 0, len);	/* 2 channels, 2 bytes/sample = 4 bytes/frame */        len /= 4;	/* For each voice... */	for(vi = 0; vi < SM_VOICES; ++vi)	{		SM_voice *v = &voices[vi];		if(!v->data)			continue;		/* For each sample... */		for(s = 0; s < len; ++s)		{			if(v->position >= v->length)			{				v->data = NULL;				break;			}			buf[s * 2] += v->data[v->position] * v->l_vol >> 8;			buf[s * 2 + 1] += v->data[v->position] * v->r_vol >> 8;			++v->position;		}	}}int sm_open(void){	SDL_AudioSpec as;	memset(sounds, 0, sizeof(sounds));	memset(voices, 0, sizeof(voices));	if(SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)		return -2;	as.freq = 44100;	as.format = AUDIO_S16SYS;	as.channels = 2;	as.samples = 1024;	as.callback = sm_mixer;	if(SDL_OpenAudio(&as, &audiospec) < 0)		return -3;	if(audiospec.format != AUDIO_S16SYS)		return -4;	SDL_PauseAudio(0);	return 0;}void sm_close(void){	int i;	SDL_PauseAudio(1);	for(i = 0; i < SM_VOICES; ++i)		voices[i].data = NULL;	SDL_CloseAudio();	for(i = 0; i < SM_SOUNDS; ++i)		SDL_FreeWAV(sounds[i].data);	memset(sounds, 0, sizeof(sounds));	memset(voices, 0, sizeof(voices));}void flip_endian(Uint8 *data, int length){	int i;	for(i = 0; i < length; i += 2)	{		int x = data[i];		data[i] = data[i + 1];		data[i + 1] = x;	}}int sm_load(int sound, const char *file){	int failed = 0;	SDL_AudioSpec spec;	if(sounds[sound].data)		SDL_FreeWAV(sounds[sound].data);	sounds[sound].data = NULL;	if(SDL_LoadWAV(file, &spec, &sounds[sound].data,			&sounds[sound].length) == NULL)		return -1;	if(spec.freq != 44100)		fprintf(stderr, "WARNING: File '%s' is not 44.1 kHz."				" Might sound weird...\n", file);	if(spec.channels != 1)	{		fprintf(stderr, "Only mono sounds are supported!\n");		failed = 1;	}	switch(spec.format)	{	  case AUDIO_S16LSB:	  case AUDIO_S16MSB:		if(spec.format != AUDIO_S16SYS)			flip_endian(sounds[sound].data, sounds[sound].length);		break;	  default:		fprintf(stderr, "Unsupported sample format!\n");		failed = 1;		break;	}	if(failed)	{		SDL_FreeWAV(sounds[sound].data);		sounds[sound].data = NULL;		return -2;	}	return 0;}void breakhandler(int a){	die = 1;}int main(int argc, char *argv[]){	const char *bd = "#...#...#...#..##...#...#...#.##";	const char *cl = "....#..*....#....*..#....*..#.**";	const char *cb = "#...*..#..*...#.#...*..#..*..*#*";	const char *hh = "..#...#...#...#...#...#...#...#.";	int res;	Uint32 step = 0;	Sint32 timer;	if(SDL_Init(0) < 0)		return -1;	atexit(SDL_Quit);	signal(SIGTERM, breakhandler);	signal(SIGINT, breakhandler);	if(sm_open() < 0)	{		fprintf(stderr, "Couldn't start mixer!\n");		SDL_Quit();		return -1;	}	res = 0;	res |= sm_load(0, "808-bassdrum.wav");	res |= sm_load(1, "808-clap.wav");	res |= sm_load(2, "808-cowbell.wav");	res |= sm_load(3, "808-hihat.wav");	if(res)	{		sm_close();		SDL_Quit();		fprintf(stderr, "Couldn't load sounds!\n");		return -1;	}	/*	 * Of course, playing this stuff would be	 * much better done in the audio callback,	 * since the timing out here jitters a lot.	 *	 * However, this is just a fun hack to get	 * the thing to make some sound, without	 * slapping in a game or something. :-)	 */	SDL_Delay(200);	timer = (Sint32)SDL_GetTicks();	while(!die)	{		if('#' == bd[step])			sm_play(0, 0, 1.0, 1.0);		if('#' == cl[step])			sm_play(1, 1, 0.6, 0.5);		else if('*' == cl[step])			sm_play(1, 1, 0.2, 0.3);		if('#' == cb[step])			sm_play(2, 2, 0.3, 0.2);		else if('*' == cb[step])			sm_play(2, 2, 0.1, 0.2);		if('#' == hh[step])			sm_play(3, 3, 0.3, 0.4);		step = (step + 1) % 32;		timer += 120;		while(((Sint32)SDL_GetTicks() - timer) < 0)			SDL_Delay(10);	}	sm_close();	SDL_Quit();	return 0;}

⌨️ 快捷键说明

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