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

📄 oss_dsp.c

📁 smallbasic for linux
💻 C
字号:
/**	/dev/dsp driver*//**	This code is taken from tonegen program.*	ToneGen: Plays a sine wave via the dsp or standard out. ToneGen written by Timothy Pozar pozar@lns.com*/#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <sys/ioctl.h>#include <math.h>#include <unistd.h>#include <pthread.h>#include <linux/soundcard.h>#define DSPDEV "/dev/dsp"#define TRUE		1#define FALSE		0#define TSIZE	4096static	unsigned char *audio_buffer;static	int		rate = 44100;static	int		gotmask;static	int		oss_h;static	int		oss_init = 0;static	char	device[TSIZE];static	pthread_t	backg_tid;volatile int audio_lock = 0;struct oss_qe_s	{	int		freq;	int		time;	int		vol;	};typedef struct oss_qe_s oss_node;#define	QSIZE		4096static oss_node	audio_queue[QSIZE];static int 		q_head, q_tail;void*	ossdsp_backg(void*);/**/int		ossdsp_init(){	strcpy(device, DSPDEV);	if ( (oss_h = open(device, O_RDWR)) == -1 ) {        perror("oss: opening device");		return 0;		}	else	{		if ( ioctl(oss_h, SNDCTL_DSP_GETFMTS, &gotmask) == -1 )		{			perror("oss: get dsp mask");			return 0;			}				if ( ioctl(oss_h, SNDCTL_DSP_SPEED, &rate) == -1){			perror("oss: set sample rate");			return 0;			}		}	audio_buffer = (unsigned char *) malloc((rate << 1)); 	q_head = q_tail = 0;	oss_init = 1;	if	( pthread_create(&backg_tid, NULL, ossdsp_backg, NULL) )	{		perror("oss: background thread failed");		oss_init = 0;		return 0;		}	return 1;}/**/void	ossdsp_close(){	if	( oss_init )	{		oss_init = 0;		usleep(1000);		close(oss_h);		oss_h = -1;		free(audio_buffer);		}}/**/void	ossdsp_play(int freq, int time_ms, int vol){	int		count, loops;	double	cyclesamples;	double	f, sinnum, fu;	short int dspnum;	if	( !freq )		freq = rate >> 1;	cyclesamples = ((double) rate) / ((double) freq);	loops = (time_ms * freq/2) / 1000;	memset(audio_buffer, 0x7f, rate << 1);	fu = (2.0 * M_PI) / cyclesamples;	f = fu;	count = 0;	while ( 1 )	{		sinnum = sin(f);		dspnum = 0x7fff * sinnum;		memmove(audio_buffer + count, &dspnum, sizeof(dspnum));		count += sizeof(dspnum);		write(oss_h, audio_buffer, count);		count = 0;		f += fu;		if	( f > (2.0 * M_PI) )	{			loops --;			if	( loops <= 0 )				return;			f = fu;			}		}}/**/void*	ossdsp_backg(void *nil){	oss_node	*node;	while ( 1 )	{		if ( oss_init )	{			if	( !audio_lock )	{				if ( q_head != q_tail )	{					while ( q_head != q_tail )	{						node = &audio_queue[q_head];						ossdsp_play(node->freq, node->time, node->vol);						q_head ++;						if	( q_head == QSIZE )							q_head = 0;						}					}				else						usleep(1000);	// sleep 1ms, wait for message				}			else					usleep(100);	// sleep 0.1 ms, locked			}		else			usleep(1000000);		}	return NULL;}/**/void	oss_sound(int frq, int  ms, int vol, int bgplay){	oss_node	*node;	int			q_next;	if	( oss_init )	{		node = &audio_queue[q_tail];		node->freq = frq;		node->time = ms;		node->vol = vol;		audio_lock = 1;		q_tail ++;		if	( q_tail == QSIZE )			q_tail = 0;		audio_lock = 0;		if	( !bgplay )			usleep(ms * 1000);		}}/**/void	oss_beep(){	oss_sound(440, 250, 75, 0);}

⌨️ 快捷键说明

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