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

📄 sdl_sunaudio.c

📁 完整的RTP RTSP代码库
💻 C
字号:
/*    SDL - Simple DirectMedia Layer    Copyright (C) 1997-2004 Sam Lantinga    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Library General Public    License as published by the Free Software Foundation; either    version 2 of the License, or (at your option) any later version.    This library 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    Library General Public License for more details.    You should have received a copy of the GNU Library General Public    License along with this library; if not, write to the Free    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA    Sam Lantinga    slouken@libsdl.org*/#ifdef SAVE_RCSIDstatic char rcsid = "@(#) $Id: SDL_sunaudio.c,v 1.1 2004/02/25 01:18:51 wmaycisco Exp $";#endif/* Allow access to a raw mixing buffer */#include <stdlib.h>#include <stdio.h>#include <fcntl.h>#include <errno.h>#include <string.h>#ifdef __NetBSD__#include <sys/ioctl.h>#include <sys/audioio.h>#endif#ifdef __SVR4#include <sys/audioio.h>#else#include <sys/time.h>#include <sys/types.h>#endif#include <unistd.h>#include "Our_SDL_audio.h"#include "SDL_audiomem.h"#include "SDL_audiodev_c.h"#include "SDL_sunaudio.h"#include "SDL_audio_c.h"/* Open the audio device for playback, and don't block if busy */#define OPEN_FLAGS	(O_WRONLY|O_NONBLOCK)/* Audio driver functions */static int DSP_OpenAudio(_THIS, SDL_AudioSpec *spec);static void DSP_WaitAudio(_THIS);static void DSP_PlayAudio(_THIS);static Uint8 *DSP_GetAudioBuf(_THIS);static void DSP_CloseAudio(_THIS);/* Audio driver bootstrap functions */static int Audio_Available(void){	int fd;	int available;	available = 0;	fd = SDL_OpenAudioPath(NULL, 0, OPEN_FLAGS, 1);	if ( fd >= 0 ) {		available = 1;		close(fd);	}	return(available);}static void Audio_DeleteDevice(SDL_AudioDevice *device){	free(device->hidden);	free(device);}static SDL_AudioDevice *Audio_CreateDevice(int devindex){	SDL_AudioDevice *this;	/* Initialize all variables that we clean on shutdown */	this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice));	if ( this ) {		memset(this, 0, (sizeof *this));		this->hidden = (struct SDL_PrivateAudioData *)				malloc((sizeof *this->hidden));	}	if ( (this == NULL) || (this->hidden == NULL) ) {		SDL_OutOfMemory();		if ( this ) {			free(this);		}		return(0);	}	memset(this->hidden, 0, (sizeof *this->hidden));	audio_fd = -1;	/* Set the function pointers */	this->OpenAudio = DSP_OpenAudio;	this->WaitAudio = DSP_WaitAudio;	this->PlayAudio = DSP_PlayAudio;	this->GetAudioBuf = DSP_GetAudioBuf;	this->CloseAudio = DSP_CloseAudio;	this->free = Audio_DeleteDevice;	return this;}AudioBootStrap SUNAUDIO_bootstrap_ours = {	"audio", "UNIX /dev/audio interface",	Audio_Available, Audio_CreateDevice};#ifdef DEBUG_AUDIOvoid CheckUnderflow(_THIS){#ifdef AUDIO_GETINFO	audio_info_t info;	int left;	ioctl(audio_fd, AUDIO_GETINFO, &info);	left = (written - info.play.samples);	if ( written && (left == 0) ) {		fprintf(stderr, "audio underflow!\n");	}#endif}#endifvoid DSP_WaitAudio(_THIS){#ifdef AUDIO_GETINFO#define SLEEP_FUDGE	10		/* 10 ms scheduling fudge factor */	audio_info_t info;	Sint32 left;	ioctl(audio_fd, AUDIO_GETINFO, &info);	left = (written - info.play.samples);	if ( left > fragsize ) {		Sint32 sleepy;		sleepy = ((left - fragsize)/frequency);		sleepy -= SLEEP_FUDGE;		if ( sleepy > 0 ) {			SDL_Delay(sleepy);		}	}#else	fd_set fdset;	FD_ZERO(&fdset);	FD_SET(audio_fd, &fdset);	select(audio_fd+1, NULL, &fdset, NULL, NULL);#endif}void DSP_PlayAudio(_THIS){	static Uint8 snd2au(int sample);	/* Write the audio data */	if ( ulaw_only ) {		/* Assuming that this->spec.freq >= 8000 Hz */		int accum, incr, pos;		Uint8 *aubuf;		accum = 0;		incr  = this->spec.freq/8;		aubuf = ulaw_buf;		switch (audio_fmt & 0xFF) {			case 8: {				Uint8 *sndbuf;				sndbuf = mixbuf;				for ( pos=0; pos < fragsize; ++pos ) {					*aubuf = snd2au((0x80-*sndbuf)*64);					accum += incr;					while ( accum > 0 ) {						accum -= 1000;						sndbuf += 1;					}					aubuf += 1;				}			}			break;			case 16: {				Sint16 *sndbuf;				sndbuf = (Sint16 *)mixbuf;				for ( pos=0; pos < fragsize; ++pos ) {					*aubuf = snd2au(*sndbuf/4);					accum += incr;					while ( accum > 0 ) {						accum -= 1000;						sndbuf += 1;					}					aubuf += 1;				}			}			break;		}#ifdef DEBUG_AUDIO		CheckUnderflow(this);#endif		if ( write(audio_fd, ulaw_buf, fragsize) < 0 ) {			/* Assume fatal error, for now */			this->enabled = 0;		}		written += fragsize;	} else {#ifdef DEBUG_AUDIO		CheckUnderflow(this);#endif		if ( write(audio_fd, mixbuf, this->spec.size) < 0 ) {			/* Assume fatal error, for now */			this->enabled = 0;		}		written += fragsize;	}}Uint8 *DSP_GetAudioBuf(_THIS){	return(mixbuf);}void DSP_CloseAudio(_THIS){	if ( mixbuf != NULL ) {		SDL_FreeAudioMem(mixbuf);		mixbuf = NULL;	}	if ( ulaw_buf != NULL ) {		free(ulaw_buf);		ulaw_buf = NULL;	}	close(audio_fd);}int DSP_OpenAudio(_THIS, SDL_AudioSpec *spec){	char audiodev[1024];#ifdef AUDIO_SETINFO	int enc;#endif	int desired_freq = spec->freq;	/* Initialize our freeable variables, in case we fail*/	audio_fd = -1;	mixbuf = NULL;	ulaw_buf = NULL;	/* Determine the audio parameters from the AudioSpec */	switch ( spec->format & 0xFF ) {		case 8: { /* Unsigned 8 bit audio data */			spec->format = AUDIO_U8;#ifdef AUDIO_SETINFO			enc = AUDIO_ENCODING_LINEAR8;#endif		}		break;		case 16: { /* Signed 16 bit audio data */		        spec->format = AUDIO_S16SYS;#ifdef AUDIO_SETINFO			enc = AUDIO_ENCODING_LINEAR;#endif		}		break;		default: {			SDL_SetError("Unsupported audio format");			return(-1);		}	}	audio_fmt = spec->format;	/* Open the audio device */	audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 1);	if ( audio_fd < 0 ) {		SDL_SetError("Couldn't open %s: %s", audiodev,			     strerror(errno));		return(-1);	}	ulaw_only = 0;		/* modern Suns do support linear audio */#ifdef AUDIO_SETINFO	for(;;) {	    audio_info_t info;	    AUDIO_INITINFO(&info); /* init all fields to "no change" */	    /* Try to set the requested settings */	    info.play.sample_rate = spec->freq;	    info.play.channels = spec->channels;	    info.play.precision = (enc == AUDIO_ENCODING_ULAW)		                  ? 8 : spec->format & 0xff;	    info.play.encoding = enc;	    if( ioctl(audio_fd, AUDIO_SETINFO, &info) == 0 ) {		/* Check to be sure we got what we wanted */		if(ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) {		    SDL_SetError("Error getting audio parameters: %s",				 strerror(errno));		    return -1;		}		if(info.play.encoding == enc		   && info.play.precision == (spec->format & 0xff)		   && info.play.channels == spec->channels) {		    /* Yow! All seems to be well! */		    spec->freq = info.play.sample_rate;		    break;		}	    }	    switch(enc) {	    case AUDIO_ENCODING_LINEAR8:		/* unsigned 8bit apparently not supported here */		enc = AUDIO_ENCODING_LINEAR;		spec->format = AUDIO_S16SYS;		break;	/* try again */	    case AUDIO_ENCODING_LINEAR:		/* linear 16bit didn't work either, resort to 

⌨️ 快捷键说明

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