|
|
| version 1.10, 2007/01/23 15:48:20 | version 1.18, 2011/12/24 17:50:44 |
|---|---|
| Line 1 | Line 1 |
| /* $Id$ */ | |
| /* | /* |
| * Copyright (c) 2001-2003 NONAKA Kimihiro | * Copyright (c) 2001-2003 NONAKA Kimihiro |
| * All rights reserved. | * All rights reserved. |
| Line 69 MIDIMOD vermouth_module = NULL; | Line 67 MIDIMOD vermouth_module = NULL; |
| /* | /* |
| * 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 89 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 117 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) |
| { | { |
| Line 135 snddrv_setup(void) | Line 149 snddrv_setup(void) |
| switch (np2oscfg.snddrv) { | switch (np2oscfg.snddrv) { |
| #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); |
| Line 170 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 184 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 192 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 206 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 215 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 235 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 246 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 276 soundmng_deinitialize(void) | Line 310 soundmng_deinitialize(void) |
| soundmng_pcmdestroy(); | soundmng_pcmdestroy(); |
| soundmng_destroy(); | soundmng_destroy(); |
| buffer_destroy(); | |
| } | } |
| void | void |
| Line 285 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 292 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 331 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 341 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 357 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 371 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 391 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 405 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 423 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 435 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 450 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 464 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 477 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 535 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 752 saturation_s16mmx(SINT16 *dst, const SIN | Line 833 saturation_s16mmx(SINT16 *dst, const SIN |
| #include <SDL.h> | #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); | static void sdlaudio_callback(void *, unsigned char *, int); |
| #if defined(USE_SDLAUDIO) | #if !defined(USE_SDLMIXER) |
| static BOOL | static BOOL |
| sdlaudio_init(UINT rate, UINT samples) | sdlaudio_init(UINT rate, UINT samples) |
| Line 769 sdlaudio_init(UINT rate, UINT samples) | Line 854 sdlaudio_init(UINT rate, UINT samples) |
| fmt.callback = sdlaudio_callback; | fmt.callback = sdlaudio_callback; |
| fmt.userdata = (void *)(samples * 2 * sizeof(SINT16)); | fmt.userdata = (void *)(samples * 2 * sizeof(SINT16)); |
| rv = SDL_Init(SDL_INIT_AUDIO); | rv = SDL_InitSubSystem(SDL_INIT_AUDIO); |
| if (rv < 0) { | if (rv < 0) { |
| fprintf(stderr, "sdlaudio_init: SDL_Init\n"); | g_printerr("sdlaudio_init: SDL_InitSubSystem(): %s\n", |
| SDL_GetError()); | |
| return FAILURE; | return FAILURE; |
| } | } |
| audio_fd = SDL_OpenAudio(&fmt, NULL); | audio_fd = SDL_OpenAudio(&fmt, NULL); |
| if (audio_fd < 0) { | if (audio_fd < 0) { |
| fprintf(stderr, "sdlaudio_init: SDL_OpenAudio\n"); | g_printerr("sdlaudio_init: SDL_OpenAudio(): %s\n", |
| SDL_Quit(); | SDL_GetError()); |
| SDL_QuitSubSystem(SDL_INIT_AUDIO); | |
| return FAILURE; | return FAILURE; |
| } | } |
| Line 789 static BOOL | Line 876 static BOOL |
| sdlaudio_term(void) | sdlaudio_term(void) |
| { | { |
| SDL_PauseAudio(1); | |
| SDL_CloseAudio(); | SDL_CloseAudio(); |
| SDL_Quit(); | |
| return SUCCESS; | return SUCCESS; |
| } | } |
| static void | static BOOL |
| sdlaudio_play(void) | |
| { | |
| SDL_PauseAudio(0); | |
| } | |
| static void | |
| sdlaudio_stop(void) | |
| { | |
| SDL_PauseAudio(1); | |
| } | |
| BOOL | |
| sdlaudio_setup(void) | sdlaudio_setup(void) |
| { | { |
| snddrv.drvinit = sdlaudio_init; | snddrv.drvinit = sdlaudio_init; |
| snddrv.drvterm = sdlaudio_term; | snddrv.drvterm = sdlaudio_term; |
| snddrv.drvlock = sdlaudio_lock; | |
| snddrv.drvunlock = sdlaudio_unlock; | |
| snddrv.sndplay = sdlaudio_play; | snddrv.sndplay = sdlaudio_play; |
| snddrv.sndstop = sdlaudio_stop; | snddrv.sndstop = sdlaudio_stop; |
| snddrv.pcmload = nosound_pcmload; | snddrv.pcmload = nosound_pcmload; |
| Line 826 sdlaudio_setup(void) | Line 901 sdlaudio_setup(void) |
| return SUCCESS; | return SUCCESS; |
| } | } |
| #endif /* USE_SDLAUDIO */ | #else /* USE_SDLMIXER */ |
| #if defined(USE_SDLMIXER) | |
| #include <SDL_mixer.h> | #include <SDL_mixer.h> |
| Line 837 sdlmixer_init(UINT rate, UINT samples) | Line 910 sdlmixer_init(UINT rate, UINT samples) |
| { | { |
| int rv; | int rv; |
| rv = SDL_Init(SDL_INIT_AUDIO); | rv = SDL_InitSubSystem(SDL_INIT_AUDIO); |
| if (rv < 0) { | if (rv < 0) { |
| fprintf(stderr, "SDL_Init(): %s\n", SDL_GetError()); | g_printerr("sdlmixer_init: SDL_InitSubSystem(): %s\n", |
| SDL_GetError()); | |
| goto failure; | goto failure; |
| } | } |
| rv = Mix_OpenAudio(rate, AUDIO_S16SYS, 2, samples); | rv = Mix_OpenAudio(rate, AUDIO_S16SYS, 2, samples); |
| if (rv < 0) { | if (rv < 0) { |
| fprintf(stderr, "Mix_OpenAudio(): %s\n", Mix_GetError()); | g_printerr("sdlmixer_init: Mix_OpenAudio(): %s\n", |
| Mix_GetError()); | |
| goto failure1; | goto failure1; |
| } | } |
| SDL_PauseAudio(1); | |
| rv = Mix_AllocateChannels(SOUND_MAXPCM); | rv = Mix_AllocateChannels(SOUND_MAXPCM); |
| if (rv < 0) { | if (rv < 0) { |
| fprintf(stderr, "Mix_AllocateChannels(): %s\n", Mix_GetError()); | g_printerr("sdlmixer_init: Mix_AllocateChannels(): %s\n", |
| goto failure2; | Mix_GetError()); |
| goto failure1; | |
| } | } |
| Mix_HookMusic(sdlaudio_callback, (void*)(samples * 2 * sizeof(SINT16))); | Mix_HookMusic(sdlaudio_callback, (void*)(samples * 2 * sizeof(SINT16))); |
| return SUCCESS; | return SUCCESS; |
| failure2: | |
| Mix_CloseAudio(); | |
| failure1: | failure1: |
| SDL_Quit(); | Mix_CloseAudio(); |
| failure: | failure: |
| return FAILURE; | return FAILURE; |
| } | } |
| Line 872 static BOOL | Line 945 static BOOL |
| sdlmixer_term(void) | sdlmixer_term(void) |
| { | { |
| SDL_PauseAudio(1); | |
| Mix_CloseAudio(); | Mix_CloseAudio(); |
| SDL_Quit(); | |
| return SUCCESS; | return SUCCESS; |
| } | } |
| static void | |
| sdlmixer_play(void) | |
| { | |
| SDL_PauseAudio(0); | |
| } | |
| static void | |
| sdlmixer_stop(void) | |
| { | |
| SDL_PauseAudio(1); | |
| } | |
| static void * | static void * |
| sdlmixer_pcmload(UINT num, const char *path) | sdlmixer_pcmload(UINT num, const char *path) |
| { | { |
| Mix_Chunk *chunk; | |
| UNUSED(num); | return Mix_LoadWAV(path); |
| chunk = Mix_LoadWAV(path); | |
| return (void *)chunk; | |
| } | } |
| static void | static void |
| sdlmixer_pcmdestroy(void *chanp, UINT num) | sdlmixer_pcmdestroy(void *cookie, UINT num) |
| { | { |
| Mix_Chunk *chunk = (Mix_Chunk *)chanp; | Mix_Chunk *chunk = cookie; |
| Mix_HaltChannel(num); | |
| Mix_FreeChunk(chunk); | Mix_FreeChunk(chunk); |
| } | } |
| static void | static void |
| sdlmixer_pcmplay(void *chanp, UINT num, BOOL loop) | sdlmixer_pcmplay(void *cookie, UINT num, BOOL loop) |
| { | { |
| Mix_Chunk *chunk = (Mix_Chunk *)chanp; | Mix_Chunk *chunk = cookie; |
| Mix_PlayChannel(num, chunk, loop ? -1 : 1); | Mix_PlayChannel(num, chunk, loop ? -1 : 1); |
| } | } |
| static void | static void |
| sdlmixer_pcmstop(void *chanp, UINT num) | sdlmixer_pcmstop(void *cookie, UINT num) |
| { | { |
| UNUSED(chanp); | |
| Mix_HaltChannel(num); | Mix_HaltChannel(num); |
| } | } |
| static void | static void |
| sdlmixer_pcmvolume(void *chanp, UINT num, int volume) | sdlmixer_pcmvolume(void *cookie, UINT num, int volume) |
| { | { |
| UNUSED(chanp); | |
| Mix_Volume(num, (MIX_MAX_VOLUME * volume) / 100); | Mix_Volume(num, (MIX_MAX_VOLUME * volume) / 100); |
| } | } |
| BOOL | static BOOL |
| sdlmixer_setup(void) | sdlaudio_setup(void) |
| { | { |
| snddrv.drvinit = sdlmixer_init; | snddrv.drvinit = sdlmixer_init; |
| snddrv.drvterm = sdlmixer_term; | snddrv.drvterm = sdlmixer_term; |
| snddrv.sndplay = sdlmixer_play; | snddrv.drvlock = sdlaudio_lock; |
| snddrv.sndstop = sdlmixer_stop; | snddrv.drvunlock = sdlaudio_unlock; |
| snddrv.sndplay = sdlaudio_play; | |
| snddrv.sndstop = sdlaudio_stop; | |
| snddrv.pcmload = sdlmixer_pcmload; | snddrv.pcmload = sdlmixer_pcmload; |
| snddrv.pcmdestroy = sdlmixer_pcmdestroy; | snddrv.pcmdestroy = sdlmixer_pcmdestroy; |
| snddrv.pcmplay = sdlmixer_pcmplay; | snddrv.pcmplay = sdlmixer_pcmplay; |
| Line 955 sdlmixer_setup(void) | Line 1007 sdlmixer_setup(void) |
| return SUCCESS; | return SUCCESS; |
| } | } |
| #endif /* USE_SDLMIXER */ | #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 | static void |
| sdlaudio_callback(void *userdata, unsigned char *stream, int len) | sdlaudio_callback(void *userdata, unsigned char *stream, int len) |
| Line 963 sdlaudio_callback(void *userdata, unsign | Line 1043 sdlaudio_callback(void *userdata, unsign |
| UINT samples = (UINT)userdata; | UINT samples = (UINT)userdata; |
| int nextbuf = sound_nextbuf; | int nextbuf = sound_nextbuf; |
| UNUSED(len); | |
| if (sound_event != NULL) | if (sound_event != NULL) |
| memset(sound_event, 0, samples); | memset(sound_event, 0, samples); |
| sound_nextbuf = (sound_nextbuf + 1) % NSOUNDBUFFER; | sound_nextbuf = (sound_nextbuf + 1) % NSOUNDBUFFER; |
| sound_event = sound_buffer[sound_nextbuf]; | sound_event = sound_buffer[sound_nextbuf]; |
| SDL_MixAudio(stream, sound_buffer[nextbuf], samples, | SDL_MixAudio(stream, (const void *)sound_buffer[nextbuf], len, |
| SDL_MIX_MAXVOLUME); | SDL_MIX_MAXVOLUME); |
| } | } |