src/audio/dmedia/SDL_irixaudio.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 14 Dec 2001 12:30:25 +0000
changeset 249 e3d0d44f6f2e
parent 148 8758b8d42cd9
child 252 e8157fcb3114
permissions -rw-r--r--
*** empty log message ***
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997, 1998  Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Library General Public
     7     License as published by the Free Software Foundation; either
     8     version 2 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Library General Public License for more details.
    14 
    15     You should have received a copy of the GNU Library General Public
    16     License along with this library; if not, write to the Free
    17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    18 
    19     Sam Lantinga
    20     5635-34 Springhouse Dr.
    21     Pleasanton, CA 94588 (USA)
    22     slouken@devolution.com
    23 */
    24 
    25 #ifdef SAVE_RCSID
    26 static char rcsid =
    27  "@(#) $Id$";
    28 #endif
    29 
    30 /* Allow access to a raw mixing buffer (For IRIX 6.5 and higher) */
    31 
    32 #include <stdlib.h>
    33 
    34 #include "SDL_endian.h"
    35 #include "SDL_timer.h"
    36 #include "SDL_audio.h"
    37 #include "SDL_audiomem.h"
    38 #include "SDL_audio_c.h"
    39 #include "SDL_irixaudio.h"
    40 
    41 
    42 /* Audio driver functions */
    43 static int AL_OpenAudio(_THIS, SDL_AudioSpec *spec);
    44 static void AL_WaitAudio(_THIS);
    45 static void AL_PlayAudio(_THIS);
    46 static Uint8 *AL_GetAudioBuf(_THIS);
    47 static void AL_CloseAudio(_THIS);
    48 
    49 /* Audio driver bootstrap functions */
    50 
    51 static int Audio_Available(void)
    52 {
    53 	return 1;
    54 }
    55 
    56 static void Audio_DeleteDevice(SDL_AudioDevice *device)
    57 {
    58 	free(device->hidden);
    59 	free(device);
    60 }
    61 
    62 static SDL_AudioDevice *Audio_CreateDevice(int devindex)
    63 {
    64 	SDL_AudioDevice *this;
    65 
    66 	/* Initialize all variables that we clean on shutdown */
    67 	this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice));
    68 	if ( this ) {
    69 		memset(this, 0, (sizeof *this));
    70 		this->hidden = (struct SDL_PrivateAudioData *)
    71 				malloc((sizeof *this->hidden));
    72 	}
    73 	if ( (this == NULL) || (this->hidden == NULL) ) {
    74 		SDL_OutOfMemory();
    75 		if ( this ) {
    76 			free(this);
    77 		}
    78 		return(0);
    79 	}
    80 	memset(this->hidden, 0, (sizeof *this->hidden));
    81 
    82 	/* Set the function pointers */
    83 	this->OpenAudio = AL_OpenAudio;
    84 	this->WaitAudio = AL_WaitAudio;
    85 	this->PlayAudio = AL_PlayAudio;
    86 	this->GetAudioBuf = AL_GetAudioBuf;
    87 	this->CloseAudio = AL_CloseAudio;
    88 
    89 	this->free = Audio_DeleteDevice;
    90 
    91 	return this;
    92 }
    93 
    94 AudioBootStrap DMEDIA_bootstrap = {
    95 	"AL", "IRIX DMedia audio",
    96 	Audio_Available, Audio_CreateDevice
    97 };
    98 
    99 
   100 void static AL_WaitAudio(_THIS)
   101 {
   102 	Sint32 timeleft;
   103 
   104 	timeleft = this->spec.samples - alGetFillable(audio_port);
   105 	if ( timeleft > 0 ) {
   106 		timeleft /= (this->spec.freq/1000);
   107 		SDL_Delay((Uint32)timeleft);
   108 	}
   109 }
   110 
   111 static void AL_PlayAudio(_THIS)
   112 {
   113 	/* Write the audio data out */
   114 	if ( alWriteFrames(audio_port, mixbuf, this->spec.samples) < 0 ) {
   115 		/* Assume fatal error, for now */
   116 		this->enabled = 0;
   117 	}
   118 }
   119 
   120 static Uint8 *AL_GetAudioBuf(_THIS)
   121 {
   122 	return(mixbuf);
   123 }
   124 
   125 static void AL_CloseAudio(_THIS)
   126 {
   127 	if ( mixbuf != NULL ) {
   128 		SDL_FreeAudioMem(mixbuf);
   129 		mixbuf = NULL;
   130 	}
   131 	if ( audio_port != NULL ) {
   132 		ALcloseport(audio_port);
   133 		audio_port = NULL;
   134 	}
   135 }
   136 
   137 static int AL_OpenAudio(_THIS, SDL_AudioSpec *spec)
   138 {
   139 	ALconfig audio_config;
   140 	ALpv audio_param;
   141 	int width;
   142 
   143 	/* Determine the audio parameters from the AudioSpec */
   144 	switch ( spec->format & 0xFF ) {
   145 
   146 		case 8: { /* Signed 8 bit audio data */
   147 			spec->format = AUDIO_S8;
   148 			width = AL_SAMPLE_8;
   149 		}
   150 		break;
   151 
   152 		case 16: { /* Signed 16 bit audio data */
   153 			spec->format = AUDIO_S16MSB;
   154 			width = AL_SAMPLE_16;
   155 		}
   156 		break;
   157 
   158 		default: {
   159 			SDL_SetError("Unsupported audio format");
   160 			return(-1);
   161 		}
   162 	}
   163 
   164 	/* Update the fragment size as size in bytes */
   165 	SDL_CalculateAudioSpec(spec);
   166 
   167 	/* Set output frequency */
   168 	audio_param.param = AL_RATE;
   169 	audio_param.value.i = spec->freq;
   170 	if( alSetParams(AL_DEFAULT_OUTPUT, &audio_param, 1) < 0 ) {
   171 		SDL_SetError("alSetParams failed");
   172 		return(-1);
   173 	}
   174 
   175 	/* Open the audio port with the requested frequency */
   176 	audio_port = NULL;
   177 	audio_config = alNewConfig();
   178 	if ( audio_config &&
   179 	     (alSetSampFmt(audio_config, AL_SAMPFMT_TWOSCOMP) >= 0) &&
   180 	     (alSetWidth(audio_config, width) >= 0) &&
   181 	     (alSetQueueSize(audio_config, spec->samples*2) >= 0) &&
   182 	     (alSetChannels(audio_config, spec->channels) >= 0) ) {
   183 		audio_port = ALopenport("SDL audio", "w", audio_config);
   184 	}
   185 	alFreeConfig(audio_config);
   186 	if( audio_port == NULL ) {
   187 		SDL_SetError("Unable to open audio port");
   188 		return(-1);
   189 	}
   190 
   191 	/* Allocate mixing buffer */
   192 	mixbuf = (Uint8 *)SDL_AllocAudioMem(spec->size);
   193 	if ( mixbuf == NULL ) {
   194 		SDL_OutOfMemory();
   195 		return(-1);
   196 	}
   197 	memset(mixbuf, spec->silence, spec->size);
   198 
   199 	/* We're ready to rock and roll. :-) */
   200 	return(0);
   201 }