diff options
author | Sam Lantinga <slouken@libsdl.org> | 2006-07-10 21:04:37 +0000 |
---|---|---|
committer | Sam Lantinga <slouken@libsdl.org> | 2006-07-10 21:04:37 +0000 |
commit | 0f030a1802c6205f4782adf086fcc6ad416aa52a (patch) | |
tree | d6fe19c1f8605151b3b800a9158e26f979b96563 /src/audio/sun/SDL_sunaudio.c | |
parent | 91a32b77a24e61974f415d0c9d7aee208c29b2b5 (diff) |
SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%401938
Diffstat (limited to 'src/audio/sun/SDL_sunaudio.c')
-rw-r--r-- | src/audio/sun/SDL_sunaudio.c | 602 |
1 files changed, 309 insertions, 293 deletions
diff --git a/src/audio/sun/SDL_sunaudio.c b/src/audio/sun/SDL_sunaudio.c index 5ddaba10..30527149 100644 --- a/src/audio/sun/SDL_sunaudio.c +++ b/src/audio/sun/SDL_sunaudio.c @@ -48,7 +48,7 @@ #define OPEN_FLAGS (O_WRONLY|O_NONBLOCK) /* Audio driver functions */ -static int DSP_OpenAudio(_THIS, SDL_AudioSpec *spec); +static int DSP_OpenAudio(_THIS, SDL_AudioSpec * spec); static void DSP_WaitAudio(_THIS); static void DSP_PlayAudio(_THIS); static Uint8 *DSP_GetAudioBuf(_THIS); @@ -58,325 +58,338 @@ static Uint8 snd2au(int sample); /* Audio driver bootstrap functions */ -static int Audio_Available(void) +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); + 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) +static void +Audio_DeleteDevice(SDL_AudioDevice * device) { - SDL_free(device->hidden); - SDL_free(device); + SDL_free(device->hidden); + SDL_free(device); } -static SDL_AudioDevice *Audio_CreateDevice(int devindex) +static SDL_AudioDevice * +Audio_CreateDevice(int devindex) { - SDL_AudioDevice *this; - - /* Initialize all variables that we clean on shutdown */ - this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); - if ( this ) { - SDL_memset(this, 0, (sizeof *this)); - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - } - if ( (this == NULL) || (this->hidden == NULL) ) { - SDL_OutOfMemory(); - if ( this ) { - SDL_free(this); - } - return(0); - } - SDL_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; + SDL_AudioDevice *this; + + /* Initialize all variables that we clean on shutdown */ + this = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice)); + if (this) { + SDL_memset(this, 0, (sizeof *this)); + this->hidden = (struct SDL_PrivateAudioData *) + SDL_malloc((sizeof *this->hidden)); + } + if ((this == NULL) || (this->hidden == NULL)) { + SDL_OutOfMemory(); + if (this) { + SDL_free(this); + } + return (0); + } + SDL_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 = { - "audio", "UNIX /dev/audio interface", - Audio_Available, Audio_CreateDevice + "audio", "UNIX /dev/audio interface", + Audio_Available, Audio_CreateDevice }; #ifdef DEBUG_AUDIO -void CheckUnderflow(_THIS) +void +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"); - } + 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 } #endif -void DSP_WaitAudio(_THIS) +void +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); - } - } +#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_set fdset; - FD_ZERO(&fdset); - FD_SET(audio_fd, &fdset); - select(audio_fd+1, NULL, &fdset, NULL, NULL); + FD_ZERO(&fdset); + FD_SET(audio_fd, &fdset); + select(audio_fd + 1, NULL, &fdset, NULL, NULL); #endif } -void DSP_PlayAudio(_THIS) +void +DSP_PlayAudio(_THIS) { - /* 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; - } + /* 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); + CheckUnderflow(this); #endif - if ( write(audio_fd, ulaw_buf, fragsize) < 0 ) { - /* Assume fatal error, for now */ - this->enabled = 0; - } - written += fragsize; - } else { + if (write(audio_fd, ulaw_buf, fragsize) < 0) { + /* Assume fatal error, for now */ + this->enabled = 0; + } + written += fragsize; + } else { #ifdef DEBUG_AUDIO - CheckUnderflow(this); + CheckUnderflow(this); #endif - if ( write(audio_fd, mixbuf, this->spec.size) < 0 ) { - /* Assume fatal error, for now */ - this->enabled = 0; - } - written += fragsize; - } + if (write(audio_fd, mixbuf, this->spec.size) < 0) { + /* Assume fatal error, for now */ + this->enabled = 0; + } + written += fragsize; + } } -Uint8 *DSP_GetAudioBuf(_THIS) +Uint8 * +DSP_GetAudioBuf(_THIS) { - return(mixbuf); + return (mixbuf); } -void DSP_CloseAudio(_THIS) +void +DSP_CloseAudio(_THIS) { - if ( mixbuf != NULL ) { - SDL_FreeAudioMem(mixbuf); - mixbuf = NULL; - } - if ( ulaw_buf != NULL ) { - SDL_free(ulaw_buf); - ulaw_buf = NULL; - } - close(audio_fd); + if (mixbuf != NULL) { + SDL_FreeAudioMem(mixbuf); + mixbuf = NULL; + } + if (ulaw_buf != NULL) { + SDL_free(ulaw_buf); + ulaw_buf = NULL; + } + close(audio_fd); } -int DSP_OpenAudio(_THIS, SDL_AudioSpec *spec) +int +DSP_OpenAudio(_THIS, SDL_AudioSpec * spec) { - char audiodev[1024]; + char audiodev[1024]; #ifdef AUDIO_SETINFO - int enc; + int enc; #endif - int desired_freq = spec->freq; + int desired_freq = spec->freq; - /* Initialize our freeable variables, in case we fail*/ - audio_fd = -1; - mixbuf = NULL; - ulaw_buf = NULL; + /* 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 ) { + /* Determine the audio parameters from the AudioSpec */ + switch (spec->format & 0xFF) { - case 8: { /* Unsigned 8 bit audio data */ - spec->format = AUDIO_U8; + case 8: + { /* Unsigned 8 bit audio data */ + spec->format = AUDIO_U8; #ifdef AUDIO_SETINFO - enc = AUDIO_ENCODING_LINEAR8; + enc = AUDIO_ENCODING_LINEAR8; #endif - } - break; + } + break; - case 16: { /* Signed 16 bit audio data */ - spec->format = AUDIO_S16SYS; + case 16: + { /* Signed 16 bit audio data */ + spec->format = AUDIO_S16SYS; #ifdef AUDIO_SETINFO - enc = AUDIO_ENCODING_LINEAR; + 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 */ + } + 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 µ-law */ - enc = AUDIO_ENCODING_ULAW; - spec->channels = 1; - spec->freq = 8000; - spec->format = AUDIO_U8; - ulaw_only = 1; - break; - - default: - /* oh well... */ - SDL_SetError("Error setting audio parameters: %s", - strerror(errno)); - return -1; - } - } + 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 µ-law */ + enc = AUDIO_ENCODING_ULAW; + spec->channels = 1; + spec->freq = 8000; + spec->format = AUDIO_U8; + ulaw_only = 1; + break; + + default: + /* oh well... */ + SDL_SetError("Error setting audio parameters: %s", + strerror(errno)); + return -1; + } + } #endif /* AUDIO_SETINFO */ - written = 0; - - /* We can actually convert on-the-fly to U-Law */ - if ( ulaw_only ) { - spec->freq = desired_freq; - fragsize = (spec->samples*1000)/(spec->freq/8); - frequency = 8; - ulaw_buf = (Uint8 *)SDL_malloc(fragsize); - if ( ulaw_buf == NULL ) { - SDL_OutOfMemory(); - return(-1); - } - spec->channels = 1; - } else { - fragsize = spec->samples; - frequency = spec->freq/1000; - } + written = 0; + + /* We can actually convert on-the-fly to U-Law */ + if (ulaw_only) { + spec->freq = desired_freq; + fragsize = (spec->samples * 1000) / (spec->freq / 8); + frequency = 8; + ulaw_buf = (Uint8 *) SDL_malloc(fragsize); + if (ulaw_buf == NULL) { + SDL_OutOfMemory(); + return (-1); + } + spec->channels = 1; + } else { + fragsize = spec->samples; + frequency = spec->freq / 1000; + } #ifdef DEBUG_AUDIO - fprintf(stderr, "Audio device %s U-Law only\n", - ulaw_only ? "is" : "is not"); - fprintf(stderr, "format=0x%x chan=%d freq=%d\n", - spec->format, spec->channels, spec->freq); + fprintf(stderr, "Audio device %s U-Law only\n", + ulaw_only ? "is" : "is not"); + fprintf(stderr, "format=0x%x chan=%d freq=%d\n", + spec->format, spec->channels, spec->freq); #endif - /* Update the fragment size as size in bytes */ - SDL_CalculateAudioSpec(spec); + /* Update the fragment size as size in bytes */ + SDL_CalculateAudioSpec(spec); - /* Allocate mixing buffer */ - mixbuf = (Uint8 *)SDL_AllocAudioMem(spec->size); - if ( mixbuf == NULL ) { - SDL_OutOfMemory(); - return(-1); - } - SDL_memset(mixbuf, spec->silence, spec->size); + /* Allocate mixing buffer */ + mixbuf = (Uint8 *) SDL_AllocAudioMem(spec->size); + if (mixbuf == NULL) { + SDL_OutOfMemory(); + return (-1); + } + SDL_memset(mixbuf, spec->silence, spec->size); - /* We're ready to rock and roll. :-) */ - return(0); + /* We're ready to rock and roll. :-) */ + return (0); } /************************************************************************/ @@ -397,36 +410,39 @@ int DSP_OpenAudio(_THIS, SDL_AudioSpec *spec) /* provided "as is" without express or implied warranty. */ /************************************************************************/ -static Uint8 snd2au(int sample) +static Uint8 +snd2au(int sample) { - int mask; - - if (sample < 0) { - sample = -sample; - mask = 0x7f; - } else { - mask = 0xff; - } - - if (sample < 32) { - sample = 0xF0 | (15 - sample / 2); - } else if (sample < 96) { - sample = 0xE0 | (15 - (sample - 32) / 4); - } else if (sample < 224) { - sample = 0xD0 | (15 - (sample - 96) / 8); - } else if (sample < 480) { - sample = 0xC0 | (15 - (sample - 224) / 16); - } else if (sample < 992) { - sample = 0xB0 | (15 - (sample - 480) / 32); - } else if (sample < 2016) { - sample = 0xA0 | (15 - (sample - 992) / 64); - } else if (sample < 4064) { - sample = 0x90 | (15 - (sample - 2016) / 128); - } else if (sample < 8160) { - sample = 0x80 | (15 - (sample - 4064) / 256); - } else { - sample = 0x80; - } - return (mask & sample); + int mask; + + if (sample < 0) { + sample = -sample; + mask = 0x7f; + } else { + mask = 0xff; + } + + if (sample < 32) { + sample = 0xF0 | (15 - sample / 2); + } else if (sample < 96) { + sample = 0xE0 | (15 - (sample - 32) / 4); + } else if (sample < 224) { + sample = 0xD0 | (15 - (sample - 96) / 8); + } else if (sample < 480) { + sample = 0xC0 | (15 - (sample - 224) / 16); + } else if (sample < 992) { + sample = 0xB0 | (15 - (sample - 480) / 32); + } else if (sample < 2016) { + sample = 0xA0 | (15 - (sample - 992) / 64); + } else if (sample < 4064) { + sample = 0x90 | (15 - (sample - 2016) / 128); + } else if (sample < 8160) { + sample = 0x80 | (15 - (sample - 4064) / 256); + } else { + sample = 0x80; + } + return (mask & sample); } + +/* vi: set ts=4 sw=4 expandtab: */ |