|
|
| version 1.8, 2004/07/26 15:54:18 | version 1.18, 2011/12/24 17:50:44 |
|---|---|
| Line 10 | Line 10 |
| * 2. Redistributions in binary form must reproduce the above copyright | * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the | * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. | * documentation and/or other materials provided with the distribution. |
| * 3. The name of the author may not be used to endorse or promote products | |
| * derived from this software without specific prior written permission. | |
| * | * |
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
| * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| Line 33 BYTE | Line 31 BYTE |
| snddrv_drv2num(const char* cfgstr) | snddrv_drv2num(const char* cfgstr) |
| { | { |
| if (strcasecmp(cfgstr, "NetBSD") == 0) | if (strcasecmp(cfgstr, "SDL") == 0) |
| return SNDDRV_NETBSD; | |
| else if (strcasecmp(cfgstr, "OSS") == 0) | |
| return SNDDRV_OSS; | |
| else if (strcasecmp(cfgstr, "ESD") == 0) | |
| return SNDDRV_ESD; | |
| else if (strcasecmp(cfgstr, "SDL") == 0) | |
| return SNDDRV_SDL; | return SNDDRV_SDL; |
| return SNDDRV_NODRV; | return SNDDRV_NODRV; |
| } | } |
| Line 49 snddrv_num2drv(BYTE num) | Line 41 snddrv_num2drv(BYTE num) |
| { | { |
| switch (num) { | switch (num) { |
| case SNDDRV_NETBSD: | |
| return "NetBSD"; | |
| case SNDDRV_OSS: | |
| return "OSS"; | |
| case SNDDRV_ESD: | |
| return "ESD"; | |
| case SNDDRV_SDL: | case SNDDRV_SDL: |
| return "SDL"; | return "SDL"; |
| } | } |
| Line 69 snddrv_num2drv(BYTE num) | Line 55 snddrv_num2drv(BYTE num) |
| #include "dosio.h" | #include "dosio.h" |
| #include "parts.h" | #include "parts.h" |
| #include "sysmng.h" | |
| #include "sound.h" | #include "sound.h" |
| #if defined(VERMOUTH_LIB) | #if defined(VERMOUTH_LIB) |
| #include "vermouth.h" | #include "vermouth.h" |
| #endif | |
| #include "sysmng.h" | |
| #if defined(VERMOUTH_LIB) | |
| MIDIMOD vermouth_module = NULL; | MIDIMOD vermouth_module = NULL; |
| #endif | #endif |
| /* | /* |
| * driver | * driver |
| */ | */ |
| int audio_fd = -1; | static struct { |
| snddrv_t snddrv; | BOOL (*drvinit)(UINT rate, UINT samples); |
| BOOL (*drvterm)(void); | |
| void (*drvlock)(void); | |
| void (*drvunlock)(void); | |
| void (*sndplay)(void); | |
| void (*sndstop)(void); | |
| void *(*pcmload)(UINT num, const char *path); | |
| void (*pcmdestroy)(void *cookie, UINT num); | |
| void (*pcmplay)(void *cookie, UINT num, BOOL loop); | |
| void (*pcmstop)(void *cookie, UINT num); | |
| void (*pcmvolume)(void *cookie, UINT num, int volume); | |
| } snddrv; | |
| static int audio_fd = -1; | |
| static BOOL opened = FALSE; | static BOOL opened = FALSE; |
| static UINT mute = 0; | |
| static UINT opna_frame; | static UINT opna_frame; |
| static BOOL nosound_setup(void); | static BOOL nosound_setup(void); |
| static BOOL sdlaudio_setup(void); | |
| static void PARTSCALL (*fnmix)(SINT16* dst, const SINT32* src, UINT size); | static void PARTSCALL (*fnmix)(SINT16* dst, const SINT32* src, UINT size); |
| Line 103 void PARTSCALL saturation_s16mmx(SINT16 | Line 100 void PARTSCALL saturation_s16mmx(SINT16 |
| /* | /* |
| * PCM | * PCM |
| */ | */ |
| static void *pcm_channel[SOUND_MAXPCM]; | typedef struct { |
| void *cookie; | |
| char *path; | |
| int volume; | |
| } pcm_channel_t; | |
| static pcm_channel_t *pcm_channel[SOUND_MAXPCM]; | |
| static void soundmng_pcminit(void); | static void soundmng_pcminit(void); |
| static void soundmng_pcmdestroy(void); | static void soundmng_pcmdestroy(void); |
| #ifndef PCM_VOULE_DEFAULT | |
| #define PCM_VOULE_DEFAULT 25 | |
| #endif | |
| int pcm_volume_default = PCM_VOULE_DEFAULT; | |
| /* | /* |
| * buffer | * buffer |
| */ | */ |
| int sound_nextbuf; | #ifndef NSOUNDBUFFER |
| char *sound_event; | #define NSOUNDBUFFER 2 |
| char *sound_buffer[NSOUNDBUFFER]; | #endif |
| static char *sound_buffer[NSOUNDBUFFER]; | |
| static int sound_nextbuf; | |
| static char *sound_event; | |
| static BOOL buffer_init(void); | static BOOL buffer_init(void); |
| static void buffer_destroy(void); | static void buffer_destroy(void); |
| static void buffer_clear(void); | static void buffer_clear(void); |
| UINT | static UINT |
| calc_blocksize(UINT size) | calc_blocksize(UINT size) |
| { | { |
| UINT s = size; | UINT s = size; |
| Line 131 calc_blocksize(UINT size) | Line 141 calc_blocksize(UINT size) |
| return s; | return s; |
| } | } |
| UINT | |
| calc_fragment(UINT size) | |
| { | |
| UINT f; | |
| for (f = 0; size > (UINT)(1 << f); f++) | |
| continue; | |
| return f; | |
| } | |
| static void | static void |
| snddrv_setup(void) | snddrv_setup(void) |
| { | { |
| if (np2oscfg.snddrv < SNDDRV_DRVMAX) { | if (np2oscfg.snddrv < SNDDRV_DRVMAX) { |
| switch (np2oscfg.snddrv) { | switch (np2oscfg.snddrv) { |
| #if defined(USE_NETBSDAUDIO) | |
| case SNDDRV_NETBSD: | |
| netbsdaudio_setup(); | |
| return; | |
| #endif | |
| #if defined(USE_OSSAUDIO) | |
| case SNDDRV_OSS: | |
| ossaudio_setup(); | |
| return; | |
| #endif | |
| #if defined(USE_ESDAUDIO) | |
| case SNDDRV_ESD: | |
| esdaudio_setup(); | |
| return; | |
| #endif | |
| #if defined(USE_SDLAUDIO) || defined(USE_SDLMIXER) | #if defined(USE_SDLAUDIO) || defined(USE_SDLMIXER) |
| case SNDDRV_SDL: | case SNDDRV_SDL: |
| #if defined(USE_SDLMIXER) | |
| sdlmixer_setup(); | |
| #else | |
| sdlaudio_setup(); | sdlaudio_setup(); |
| #endif | |
| return; | return; |
| #endif | #endif |
| } | } |
| } else { | } else { |
| #if defined(USE_SDLMIXER) | #if defined(USE_SDLAUDIO) || defined(USE_SDLMIXER) |
| if (sdlmixer_setup() == SUCCESS) { | |
| np2oscfg.snddrv = SNDDRV_SDL; | |
| sysmng_update(SYS_UPDATEOSCFG); | |
| return; | |
| } else | |
| #endif | |
| #if defined(USE_SDLAUDIO) | |
| if (sdlaudio_setup() == SUCCESS) { | if (sdlaudio_setup() == SUCCESS) { |
| np2oscfg.snddrv = SNDDRV_SDL; | np2oscfg.snddrv = SNDDRV_SDL; |
| sysmng_update(SYS_UPDATEOSCFG); | sysmng_update(SYS_UPDATEOSCFG); |
| return; | return; |
| } else | } else |
| #endif | #endif |
| #if defined(USE_ESDAUDIO) | |
| if (esdaudio_setup() == SUCCESS) { | |
| np2oscfg.snddrv = SNDDRV_ESD; | |
| sysmng_update(SYS_UPDATEOSCFG); | |
| return; | |
| } else | |
| #endif | |
| #if defined(USE_OSSAUDIO) | |
| if (ossaudio_setup() == SUCCESS) { | |
| np2oscfg.snddrv = SNDDRV_OSS; | |
| sysmng_update(SYS_UPDATEOSCFG); | |
| return; | |
| } else | |
| #endif | |
| #if defined(USE_NETBSDAUDIO) | |
| if (netbsdaudio_setup() == SUCCESS) { | |
| np2oscfg.snddrv = SNDDRV_NETBSD; | |
| sysmng_update(SYS_UPDATEOSCFG); | |
| return; | |
| } else | |
| #endif | |
| { | { |
| /* Nothing to do */ | /* Nothing to do */ |
| /* fall thourgh "no match" */ | /* fall thourgh "no match" */ |
| Line 220 snddrv_setup(void) | Line 173 snddrv_setup(void) |
| sysmng_update(SYS_UPDATEOSCFG); | sysmng_update(SYS_UPDATEOSCFG); |
| } | } |
| static void | |
| sounddrv_lock(void) | |
| { | |
| (*snddrv.drvlock)(); | |
| } | |
| static void | |
| sounddrv_unlock(void) | |
| { | |
| (*snddrv.drvunlock)(); | |
| } | |
| UINT | UINT |
| soundmng_create(UINT rate, UINT bufmsec) | soundmng_create(UINT rate, UINT bufmsec) |
| { | { |
| pcm_channel_t *chan; | |
| UINT samples; | UINT samples; |
| int i; | |
| if (opened || ((rate != 11025) && (rate != 22050) && (rate != 44100))) { | if (opened || ((rate != 11025) && (rate != 22050) && (rate != 44100))) { |
| return 0; | return 0; |
| Line 234 soundmng_create(UINT rate, UINT bufmsec) | Line 203 soundmng_create(UINT rate, UINT bufmsec) |
| else if (bufmsec > 1000) | else if (bufmsec > 1000) |
| bufmsec = 1000; | bufmsec = 1000; |
| for (i = 0; i < SOUND_MAXPCM; i++) { | |
| chan = pcm_channel[i]; | |
| if (chan != NULL && chan->cookie != NULL) { | |
| soundmng_pcmstop(i); | |
| (*snddrv.pcmdestroy)(chan->cookie, i); | |
| chan->cookie = NULL; | |
| } | |
| } | |
| snddrv_setup(); | snddrv_setup(); |
| samples = (rate * bufmsec) / 1000 / 2; | samples = (rate * bufmsec) / 1000 / 2; |
| Line 242 soundmng_create(UINT rate, UINT bufmsec) | Line 220 soundmng_create(UINT rate, UINT bufmsec) |
| if ((*snddrv.drvinit)(rate, samples) != SUCCESS) { | if ((*snddrv.drvinit)(rate, samples) != SUCCESS) { |
| audio_fd = -1; | audio_fd = -1; |
| nosound_setup(); | |
| np2oscfg.snddrv = SNDDRV_NODRV; | np2oscfg.snddrv = SNDDRV_NODRV; |
| sysmng_update(SYS_UPDATEOSCFG); | sysmng_update(SYS_UPDATEOSCFG); |
| return 0; | return 0; |
| Line 256 soundmng_create(UINT rate, UINT bufmsec) | Line 235 soundmng_create(UINT rate, UINT bufmsec) |
| buffer_init(); | buffer_init(); |
| soundmng_reset(); | soundmng_reset(); |
| for (i = 0; i < SOUND_MAXPCM; i++) { | |
| chan = pcm_channel[i]; | |
| if (chan != NULL && chan->path != NULL) { | |
| chan->cookie = (*snddrv.pcmload)(i, chan->path); | |
| if (chan->cookie != NULL) | |
| (*snddrv.pcmvolume)(chan->cookie, i, chan->volume); | |
| } | |
| } | |
| opened = TRUE; | opened = TRUE; |
| return samples; | return samples; |
| Line 265 void | Line 253 void |
| soundmng_reset(void) | soundmng_reset(void) |
| { | { |
| sounddrv_lock(); | |
| sound_nextbuf = 0; | sound_nextbuf = 0; |
| sound_event = NULL; | sound_event = NULL; |
| sounddrv_unlock(); | |
| buffer_clear(); | buffer_clear(); |
| } | } |
| Line 285 soundmng_destroy(void) | Line 275 soundmng_destroy(void) |
| } | } |
| (*snddrv.sndstop)(); | (*snddrv.sndstop)(); |
| (*snddrv.drvterm)(); | (*snddrv.drvterm)(); |
| buffer_destroy(); | |
| nosound_setup(); | |
| audio_fd = -1; | audio_fd = -1; |
| opened = FALSE; | opened = FALSE; |
| } | } |
| Line 296 void | Line 284 void |
| soundmng_play(void) | soundmng_play(void) |
| { | { |
| if (!mute) { | (*snddrv.sndplay)(); |
| (*snddrv.sndplay)(); | |
| } | |
| } | } |
| void | void |
| soundmng_stop(void) | soundmng_stop(void) |
| { | { |
| if (!mute) { | (*snddrv.sndstop)(); |
| (*snddrv.sndstop)(); | |
| } | |
| } | } |
| BOOL | BOOL |
| Line 326 soundmng_deinitialize(void) | Line 310 soundmng_deinitialize(void) |
| soundmng_pcmdestroy(); | soundmng_pcmdestroy(); |
| soundmng_destroy(); | soundmng_destroy(); |
| buffer_destroy(); | |
| } | } |
| void | void |
| Line 335 soundmng_sync(void) | Line 320 soundmng_sync(void) |
| SINT16 *q; | SINT16 *q; |
| if (opened) { | if (opened) { |
| sounddrv_lock(); | |
| if (sound_event) { | if (sound_event) { |
| pcm = sound_pcmlock(); | pcm = sound_pcmlock(); |
| q = (SINT16 *)sound_event; | q = (SINT16 *)sound_event; |
| Line 342 soundmng_sync(void) | Line 328 soundmng_sync(void) |
| (*fnmix)(q, pcm, opna_frame); | (*fnmix)(q, pcm, opna_frame); |
| sound_pcmunlock(pcm); | sound_pcmunlock(pcm); |
| } | } |
| sounddrv_unlock(); | |
| } | } |
| } | } |
| Line 381 soundmng_setreverse(BOOL reverse) | Line 368 soundmng_setreverse(BOOL reverse) |
| /* | /* |
| * PCM function | * PCM function |
| */ | */ |
| void | static void |
| soundmng_pcminit(void) | soundmng_pcminit(void) |
| { | { |
| int i; | int i; |
| Line 391 soundmng_pcminit(void) | Line 378 soundmng_pcminit(void) |
| } | } |
| } | } |
| void | static void |
| soundmng_pcmdestroy(void) | soundmng_pcmdestroy(void) |
| { | { |
| pcm_channel_t *chan; | |
| int i; | int i; |
| for (i = 0; i < SOUND_MAXPCM; i++) { | for (i = 0; i < SOUND_MAXPCM; i++) { |
| if (pcm_channel[i]) { | chan = pcm_channel[i]; |
| (*snddrv.pcmdestroy)(pcm_channel[i], i); | if (chan != NULL) { |
| pcm_channel[i] = NULL; | pcm_channel[i] = NULL; |
| if (chan->cookie != NULL) { | |
| (*snddrv.pcmdestroy)(chan->cookie, i); | |
| chan->cookie = NULL; | |
| } | |
| if (chan->path != NULL) { | |
| _MFREE(chan->path); | |
| chan->path = NULL; | |
| } | |
| } | } |
| } | } |
| } | } |
| Line 407 soundmng_pcmdestroy(void) | Line 403 soundmng_pcmdestroy(void) |
| BOOL | BOOL |
| soundmng_pcmload(UINT num, const char *filename) | soundmng_pcmload(UINT num, const char *filename) |
| { | { |
| pcm_channel_t *chan; | |
| struct stat sb; | |
| int rv; | |
| if (num < SOUND_MAXPCM) { | if (num < SOUND_MAXPCM) { |
| if (pcm_channel[num]) | rv = stat(filename, &sb); |
| (*snddrv.pcmdestroy)(pcm_channel[num], num); | if (rv < 0) |
| pcm_channel[num] = (*snddrv.pcmload)(num, filename); | return FAILURE; |
| if (pcm_channel[num]) | |
| return SUCCESS; | chan = pcm_channel[num]; |
| if (chan != NULL) { | |
| if (strcmp(filename, chan->path)) { | |
| _MFREE(chan->path); | |
| chan->path = strdup(filename); | |
| } | |
| } else { | |
| chan = _MALLOC(sizeof(*chan), "pcm channel"); | |
| if (chan == NULL) | |
| return FAILURE; | |
| chan->cookie = NULL; | |
| chan->path = strdup(filename); | |
| chan->volume = pcm_volume_default; | |
| pcm_channel[num] = chan; | |
| } | |
| return SUCCESS; | |
| } | } |
| return FAILURE; | return FAILURE; |
| } | } |
| Line 421 soundmng_pcmload(UINT num, const char *f | Line 435 soundmng_pcmload(UINT num, const char *f |
| void | void |
| soundmng_pcmvolume(UINT num, int volume) | soundmng_pcmvolume(UINT num, int volume) |
| { | { |
| pcm_channel_t *chan; | |
| if ((num < SOUND_MAXPCM) && (pcm_channel[num])) { | if (num < SOUND_MAXPCM) { |
| (*snddrv.pcmvolume)(pcm_channel[num], num, volume); | chan = pcm_channel[num]; |
| if (chan != NULL) { | |
| chan->volume = volume; | |
| if (chan->cookie != NULL) | |
| (*snddrv.pcmvolume)(chan->cookie, num, volume); | |
| } | |
| } | } |
| } | } |
| BOOL | BOOL |
| soundmng_pcmplay(UINT num, BOOL loop) | soundmng_pcmplay(UINT num, BOOL loop) |
| { | { |
| pcm_channel_t *chan; | |
| if ((num < SOUND_MAXPCM) && (pcm_channel[num])) { | if (num < SOUND_MAXPCM) { |
| (*snddrv.pcmplay)(pcm_channel[num], num, loop); | chan = pcm_channel[num]; |
| if (chan != NULL && chan->cookie != NULL) { | |
| (*snddrv.pcmplay)(chan->cookie, num, loop); | |
| } | |
| return SUCCESS; | return SUCCESS; |
| } | } |
| return FAILURE; | return FAILURE; |
| Line 441 soundmng_pcmplay(UINT num, BOOL loop) | Line 465 soundmng_pcmplay(UINT num, BOOL loop) |
| void | void |
| soundmng_pcmstop(UINT num) | soundmng_pcmstop(UINT num) |
| { | { |
| pcm_channel_t *chan; | |
| if ((num < SOUND_MAXPCM) && (pcm_channel[num])) { | if (num < SOUND_MAXPCM) { |
| (*snddrv.pcmstop)(pcm_channel[num], num); | chan = pcm_channel[num]; |
| if (chan != NULL && chan->cookie != NULL) { | |
| (*snddrv.pcmstop)(chan->cookie, num); | |
| } | |
| } | } |
| } | } |
| Line 455 buffer_init(void) | Line 483 buffer_init(void) |
| { | { |
| int i; | int i; |
| sounddrv_lock(); | |
| for (i = 0; i < NSOUNDBUFFER; i++) { | for (i = 0; i < NSOUNDBUFFER; i++) { |
| if (sound_buffer[i]) { | if (sound_buffer[i] != NULL) { |
| _MFREE(sound_buffer[i]); | _MFREE(sound_buffer[i]); |
| } | } |
| sound_buffer[i] = (char *)_MALLOC(opna_frame, "sound buffer"); | sound_buffer[i] = (char *)_MALLOC(opna_frame, "sound buffer"); |
| if (sound_buffer[i] == NULL) { | if (sound_buffer[i] == NULL) { |
| fprintf(stderr, "buffer_init: can't alloc memory\n"); | g_printerr("buffer_init: can't alloc memory\n"); |
| sounddrv_unlock(); | |
| return FAILURE; | return FAILURE; |
| } | } |
| } | } |
| sounddrv_unlock(); | |
| return SUCCESS; | return SUCCESS; |
| } | } |
| Line 473 buffer_clear(void) | Line 504 buffer_clear(void) |
| { | { |
| int i; | int i; |
| sounddrv_lock(); | |
| for (i = 0; i < NSOUNDBUFFER; i++) { | for (i = 0; i < NSOUNDBUFFER; i++) { |
| if (sound_buffer[i]) { | if (sound_buffer[i]) { |
| memset(sound_buffer[i], 0, opna_frame); | memset(sound_buffer[i], 0, opna_frame); |
| } | } |
| } | } |
| sounddrv_unlock(); | |
| } | } |
| static void | static void |
| Line 485 buffer_destroy(void) | Line 518 buffer_destroy(void) |
| { | { |
| int i; | int i; |
| sounddrv_lock(); | |
| for (i = 0; i < NSOUNDBUFFER; i++) { | for (i = 0; i < NSOUNDBUFFER; i++) { |
| if (sound_buffer[i]) { | if (sound_buffer[i] != NULL) { |
| _MFREE(sound_buffer[i]); | _MFREE(sound_buffer[i]); |
| sound_buffer[i] = NULL; | sound_buffer[i] = NULL; |
| } | } |
| } | } |
| sounddrv_unlock(); | |
| } | } |
| /* | /* |
| Line 500 static BOOL | Line 535 static BOOL |
| nosound_drvinit(UINT rate, UINT bufmsec) | nosound_drvinit(UINT rate, UINT bufmsec) |
| { | { |
| UNUSED(rate); | |
| UNUSED(bufmsec); | |
| return SUCCESS; | return SUCCESS; |
| } | } |
| Line 514 nosound_drvterm(void) | Line 546 nosound_drvterm(void) |
| } | } |
| static void | static void |
| nosound_drvlock(void) | |
| { | |
| /* Nothing to do */ | |
| } | |
| static void | |
| nosound_drvunlock(void) | |
| { | |
| /* Nothing to do */ | |
| } | |
| static void | |
| nosound_sndplay(void) | nosound_sndplay(void) |
| { | { |
| Line 527 nosound_sndstop(void) | Line 573 nosound_sndstop(void) |
| /* Nothing to do */ | /* Nothing to do */ |
| } | } |
| void * | static void * |
| nosound_pcmload(UINT num, const char *path) | nosound_pcmload(UINT num, const char *path) |
| { | { |
| UNUSED(num); | |
| UNUSED(path); | |
| return NULL; | return NULL; |
| } | } |
| void | static void |
| nosound_pcmdestroy(void *chanp, UINT num) | nosound_pcmdestroy(void *cookie, UINT num) |
| { | { |
| UNUSED(chanp); | |
| UNUSED(num); | |
| /* Nothing to do */ | /* Nothing to do */ |
| } | } |
| void | static void |
| nosound_pcmplay(void *chanp, UINT num, BOOL loop) | nosound_pcmplay(void *cookie, UINT num, BOOL loop) |
| { | { |
| UNUSED(chanp); | |
| UNUSED(num); | |
| UNUSED(loop); | |
| /* Nothing to do */ | /* Nothing to do */ |
| } | } |
| void | static void |
| nosound_pcmstop(void *chanp, UINT num) | nosound_pcmstop(void *cookie, UINT num) |
| { | { |
| UNUSED(chanp); | |
| UNUSED(num); | |
| /* Nothing to do */ | /* Nothing to do */ |
| } | } |
| void | static void |
| nosound_pcmvolume(void *chanp, UINT num, int volume) | nosound_pcmvolume(void *cookie, UINT num, int volume) |
| { | { |
| UNUSED(chanp); | |
| UNUSED(num); | |
| UNUSED(volume); | |
| /* Nothing to do */ | /* Nothing to do */ |
| } | } |
| Line 585 nosound_setup(void) | Line 614 nosound_setup(void) |
| snddrv.drvinit = nosound_drvinit; | snddrv.drvinit = nosound_drvinit; |
| snddrv.drvterm = nosound_drvterm; | snddrv.drvterm = nosound_drvterm; |
| snddrv.drvlock = nosound_drvlock; | |
| snddrv.drvunlock = nosound_drvunlock; | |
| snddrv.sndplay = nosound_sndplay; | snddrv.sndplay = nosound_sndplay; |
| snddrv.sndstop = nosound_sndstop; | snddrv.sndstop = nosound_sndstop; |
| snddrv.pcmload = nosound_pcmload; | snddrv.pcmload = nosound_pcmload; |
| Line 596 nosound_setup(void) | Line 627 nosound_setup(void) |
| return SUCCESS; | return SUCCESS; |
| } | } |
| #if defined(USE_NETBSDAUDIO) || defined(USE_OSSAUDIO) || defined(USE_ESDAUDIO) | |
| /* | |
| * common driver | |
| */ | |
| static pthread_t ptid; | |
| static BOOL is_proc; | |
| static void * | |
| buffer_play(void *arg) | |
| { | |
| char *buf; | |
| size_t len = opna_frame; | |
| size_t s; | |
| ssize_t r; | |
| int nextbuf; | |
| UNUSED(arg); | |
| is_proc = TRUE; | |
| while (is_proc) { | |
| nextbuf = sound_nextbuf; | |
| if (sound_event) | |
| memset(sound_event, 0, len); | |
| sound_nextbuf = (sound_nextbuf + 1) % NSOUNDBUFFER; | |
| sound_event = sound_buffer[sound_nextbuf]; | |
| buf = sound_buffer[nextbuf]; | |
| s = 0; | |
| for (;;) { | |
| r = write(audio_fd, buf + s, len - s); | |
| if (r >= 0) { | |
| s += r; | |
| if (len <= s) | |
| break; | |
| } | |
| } | |
| } | |
| is_proc = FALSE; | |
| return NULL; | |
| } | |
| void | |
| snddrv_play(void) | |
| { | |
| if (pthread_create(&ptid, NULL, buffer_play, NULL) != 0) { | |
| fprintf(stderr, "audio_play: can't create thread.\n"); | |
| } | |
| } | |
| void | |
| snddrv_stop(void) | |
| { | |
| is_proc = FALSE; | |
| } | |
| #endif /* USE_NETBSDAUDIO || USE_OSSAUDIO || USE_ESDAUDIO */ | |
| #if defined(GCC_CPU_ARCH_AMD64) | #if defined(GCC_CPU_ARCH_AMD64) |
| void PARTSCALL | void PARTSCALL |
| _saturation_s16(SINT16 *dst, const SINT32 *src, UINT size) | _saturation_s16(SINT16 *dst, const SINT32 *src, UINT size) |
| Line 858 saturation_s16mmx(SINT16 *dst, const SIN | Line 829 saturation_s16mmx(SINT16 *dst, const SIN |
| } | } |
| #endif /* GCC_CPU_ARCH_AMD64 */ | #endif /* GCC_CPU_ARCH_AMD64 */ |
| #if defined(USE_SDLAUDIO) || defined(USE_SDLMIXER) | |
| #include <SDL.h> | |
| static void sdlaudio_lock(void); | |
| static void sdlaudio_unlock(void); | |
| static void sdlaudio_play(void); | |
| static void sdlaudio_stop(void); | |
| static void sdlaudio_callback(void *, unsigned char *, int); | |
| #if !defined(USE_SDLMIXER) | |
| static BOOL | |
| sdlaudio_init(UINT rate, UINT samples) | |
| { | |
| static SDL_AudioSpec fmt; | |
| int rv; | |
| fmt.freq = rate; | |
| fmt.format = AUDIO_S16SYS; | |
| fmt.channels = 2; | |
| fmt.samples = samples; | |
| fmt.callback = sdlaudio_callback; | |
| fmt.userdata = (void *)(samples * 2 * sizeof(SINT16)); | |
| rv = SDL_InitSubSystem(SDL_INIT_AUDIO); | |
| if (rv < 0) { | |
| g_printerr("sdlaudio_init: SDL_InitSubSystem(): %s\n", | |
| SDL_GetError()); | |
| return FAILURE; | |
| } | |
| audio_fd = SDL_OpenAudio(&fmt, NULL); | |
| if (audio_fd < 0) { | |
| g_printerr("sdlaudio_init: SDL_OpenAudio(): %s\n", | |
| SDL_GetError()); | |
| SDL_QuitSubSystem(SDL_INIT_AUDIO); | |
| return FAILURE; | |
| } | |
| return SUCCESS; | |
| } | |
| static BOOL | |
| sdlaudio_term(void) | |
| { | |
| SDL_PauseAudio(1); | |
| SDL_CloseAudio(); | |
| return SUCCESS; | |
| } | |
| static BOOL | |
| sdlaudio_setup(void) | |
| { | |
| snddrv.drvinit = sdlaudio_init; | |
| snddrv.drvterm = sdlaudio_term; | |
| snddrv.drvlock = sdlaudio_lock; | |
| snddrv.drvunlock = sdlaudio_unlock; | |
| snddrv.sndplay = sdlaudio_play; | |
| snddrv.sndstop = sdlaudio_stop; | |
| snddrv.pcmload = nosound_pcmload; | |
| snddrv.pcmdestroy = nosound_pcmdestroy; | |
| snddrv.pcmplay = nosound_pcmplay; | |
| snddrv.pcmstop = nosound_pcmstop; | |
| snddrv.pcmvolume = nosound_pcmvolume; | |
| return SUCCESS; | |
| } | |
| #else /* USE_SDLMIXER */ | |
| #include <SDL_mixer.h> | |
| static BOOL | |
| sdlmixer_init(UINT rate, UINT samples) | |
| { | |
| int rv; | |
| rv = SDL_InitSubSystem(SDL_INIT_AUDIO); | |
| if (rv < 0) { | |
| g_printerr("sdlmixer_init: SDL_InitSubSystem(): %s\n", | |
| SDL_GetError()); | |
| goto failure; | |
| } | |
| rv = Mix_OpenAudio(rate, AUDIO_S16SYS, 2, samples); | |
| if (rv < 0) { | |
| g_printerr("sdlmixer_init: Mix_OpenAudio(): %s\n", | |
| Mix_GetError()); | |
| goto failure1; | |
| } | |
| rv = Mix_AllocateChannels(SOUND_MAXPCM); | |
| if (rv < 0) { | |
| g_printerr("sdlmixer_init: Mix_AllocateChannels(): %s\n", | |
| Mix_GetError()); | |
| goto failure1; | |
| } | |
| Mix_HookMusic(sdlaudio_callback, (void*)(samples * 2 * sizeof(SINT16))); | |
| return SUCCESS; | |
| failure1: | |
| Mix_CloseAudio(); | |
| failure: | |
| return FAILURE; | |
| } | |
| static BOOL | |
| sdlmixer_term(void) | |
| { | |
| SDL_PauseAudio(1); | |
| Mix_CloseAudio(); | |
| return SUCCESS; | |
| } | |
| static void * | |
| sdlmixer_pcmload(UINT num, const char *path) | |
| { | |
| return Mix_LoadWAV(path); | |
| } | |
| static void | |
| sdlmixer_pcmdestroy(void *cookie, UINT num) | |
| { | |
| Mix_Chunk *chunk = cookie; | |
| Mix_FreeChunk(chunk); | |
| } | |
| static void | |
| sdlmixer_pcmplay(void *cookie, UINT num, BOOL loop) | |
| { | |
| Mix_Chunk *chunk = cookie; | |
| Mix_PlayChannel(num, chunk, loop ? -1 : 1); | |
| } | |
| static void | |
| sdlmixer_pcmstop(void *cookie, UINT num) | |
| { | |
| Mix_HaltChannel(num); | |
| } | |
| static void | |
| sdlmixer_pcmvolume(void *cookie, UINT num, int volume) | |
| { | |
| Mix_Volume(num, (MIX_MAX_VOLUME * volume) / 100); | |
| } | |
| static BOOL | |
| sdlaudio_setup(void) | |
| { | |
| snddrv.drvinit = sdlmixer_init; | |
| snddrv.drvterm = sdlmixer_term; | |
| snddrv.drvlock = sdlaudio_lock; | |
| snddrv.drvunlock = sdlaudio_unlock; | |
| snddrv.sndplay = sdlaudio_play; | |
| snddrv.sndstop = sdlaudio_stop; | |
| snddrv.pcmload = sdlmixer_pcmload; | |
| snddrv.pcmdestroy = sdlmixer_pcmdestroy; | |
| snddrv.pcmplay = sdlmixer_pcmplay; | |
| snddrv.pcmstop = sdlmixer_pcmstop; | |
| snddrv.pcmvolume = sdlmixer_pcmvolume; | |
| return SUCCESS; | |
| } | |
| #endif /* !USE_SDLMIXER */ | |
| static void | |
| sdlaudio_lock(void) | |
| { | |
| SDL_LockAudio(); | |
| } | |
| static void | |
| sdlaudio_unlock(void) | |
| { | |
| SDL_UnlockAudio(); | |
| } | |
| static void | |
| sdlaudio_play(void) | |
| { | |
| SDL_PauseAudio(0); | |
| } | |
| static void | |
| sdlaudio_stop(void) | |
| { | |
| SDL_PauseAudio(1); | |
| } | |
| static void | |
| sdlaudio_callback(void *userdata, unsigned char *stream, int len) | |
| { | |
| UINT samples = (UINT)userdata; | |
| int nextbuf = sound_nextbuf; | |
| if (sound_event != NULL) | |
| memset(sound_event, 0, samples); | |
| sound_nextbuf = (sound_nextbuf + 1) % NSOUNDBUFFER; | |
| sound_event = sound_buffer[sound_nextbuf]; | |
| SDL_MixAudio(stream, (const void *)sound_buffer[nextbuf], len, | |
| SDL_MIX_MAXVOLUME); | |
| } | |
| #endif /* USE_SDLAUDIO || USE_SDLMIXER */ | |
| #endif /* !NOSOUND */ | #endif /* !NOSOUND */ |