2016-01-25 12:04:21 +00:00
|
|
|
#include "compiler.h"
|
|
|
|
#include "soundmng.h"
|
|
|
|
#include <algorithm>
|
|
|
|
#include "parts.h"
|
|
|
|
#include "sound.h"
|
|
|
|
#if defined(SUPPORT_EXTERNALCHIP)
|
|
|
|
#include "ext/externalchipmanager.h"
|
|
|
|
#endif
|
2015-11-18 00:19:53 +00:00
|
|
|
|
|
|
|
#define NSNDBUF 2
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
BOOL opened;
|
|
|
|
int nsndbuf;
|
|
|
|
int samples;
|
|
|
|
SINT16 *buf[NSNDBUF];
|
|
|
|
} SOUNDMNG;
|
|
|
|
|
|
|
|
static SOUNDMNG soundmng;
|
|
|
|
|
|
|
|
|
2016-01-25 12:04:21 +00:00
|
|
|
static void sound_play_cb(void *userdata, UINT8 *stream, int len) {
|
2015-11-18 00:19:53 +00:00
|
|
|
|
|
|
|
int length;
|
|
|
|
SINT16 *dst;
|
|
|
|
const SINT32 *src;
|
|
|
|
|
2016-01-25 12:04:21 +00:00
|
|
|
length = (std::min)(len, (int)(soundmng.samples * 2 * sizeof(SINT16)));
|
2015-11-18 00:19:53 +00:00
|
|
|
dst = soundmng.buf[soundmng.nsndbuf];
|
|
|
|
src = sound_pcmlock();
|
|
|
|
if (src) {
|
|
|
|
satuation_s16(dst, src, length);
|
|
|
|
sound_pcmunlock(src);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
ZeroMemory(dst, length);
|
|
|
|
}
|
|
|
|
SDL_memset(stream, 0, len);
|
2016-01-25 12:04:21 +00:00
|
|
|
SDL_MixAudio(stream, (UINT8 *)dst, length, SDL_MIX_MAXVOLUME);
|
2015-11-18 00:19:53 +00:00
|
|
|
soundmng.nsndbuf = (soundmng.nsndbuf + 1) % NSNDBUF;
|
|
|
|
(void)userdata;
|
|
|
|
}
|
|
|
|
|
|
|
|
UINT soundmng_create(UINT rate, UINT ms) {
|
|
|
|
|
|
|
|
SDL_AudioSpec fmt;
|
|
|
|
UINT s;
|
|
|
|
UINT samples;
|
|
|
|
SINT16 *tmp;
|
|
|
|
|
|
|
|
if (soundmng.opened) {
|
|
|
|
goto smcre_err1;
|
|
|
|
}
|
|
|
|
if (SDL_InitSubSystem(SDL_INIT_AUDIO | SDL_INIT_TIMER) < 0) {
|
|
|
|
fprintf(stderr, "Error: SDL_Init: %s\n", SDL_GetError());
|
|
|
|
goto smcre_err1;
|
|
|
|
}
|
|
|
|
|
|
|
|
s = rate * ms / (NSNDBUF * 1000);
|
|
|
|
samples = 1;
|
|
|
|
while(s > samples) {
|
|
|
|
samples <<= 1;
|
|
|
|
}
|
|
|
|
soundmng.nsndbuf = 0;
|
|
|
|
soundmng.samples = samples;
|
|
|
|
for (s=0; s<NSNDBUF; s++) {
|
|
|
|
tmp = (SINT16 *)_MALLOC(samples * 2 * sizeof(SINT16), "buf");
|
|
|
|
if (tmp == NULL) {
|
|
|
|
goto smcre_err2;
|
|
|
|
}
|
|
|
|
soundmng.buf[s] = tmp;
|
|
|
|
ZeroMemory(tmp, samples * 2 * sizeof(SINT16));
|
|
|
|
}
|
|
|
|
|
|
|
|
ZeroMemory(&fmt, sizeof(fmt));
|
|
|
|
fmt.freq = rate;
|
|
|
|
fmt.format = AUDIO_S16SYS;
|
|
|
|
fmt.channels = 2;
|
|
|
|
fmt.samples = samples;
|
|
|
|
fmt.callback = sound_play_cb;
|
|
|
|
if (SDL_OpenAudio(&fmt, NULL) < 0) {
|
|
|
|
fprintf(stderr, "Error: SDL_OpenAudio: %s\n", SDL_GetError());
|
|
|
|
return(FAILURE);
|
|
|
|
}
|
|
|
|
soundmng.opened = TRUE;
|
|
|
|
return(samples);
|
|
|
|
|
|
|
|
smcre_err2:
|
|
|
|
for (s=0; s<NSNDBUF; s++) {
|
|
|
|
tmp = soundmng.buf[s];
|
|
|
|
soundmng.buf[s] = NULL;
|
|
|
|
if (tmp) {
|
|
|
|
_MFREE(tmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
smcre_err1:
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void soundmng_destroy(void) {
|
|
|
|
|
|
|
|
int i;
|
|
|
|
SINT16 *tmp;
|
|
|
|
|
|
|
|
if (soundmng.opened) {
|
|
|
|
soundmng.opened = FALSE;
|
|
|
|
SDL_PauseAudio(1);
|
|
|
|
SDL_CloseAudio();
|
|
|
|
for (i=0; i<NSNDBUF; i++) {
|
|
|
|
tmp = soundmng.buf[i];
|
|
|
|
soundmng.buf[i] = NULL;
|
|
|
|
_MFREE(tmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-25 12:04:21 +00:00
|
|
|
void soundmng_play(void)
|
|
|
|
{
|
|
|
|
if (soundmng.opened)
|
|
|
|
{
|
2015-11-18 00:19:53 +00:00
|
|
|
SDL_PauseAudio(0);
|
2016-01-25 12:04:21 +00:00
|
|
|
#if defined(SUPPORT_EXTERNALCHIP)
|
|
|
|
CExternalChipManager::GetInstance()->Mute(false);
|
|
|
|
#endif
|
2015-11-18 00:19:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-25 12:04:21 +00:00
|
|
|
void soundmng_stop(void)
|
|
|
|
{
|
|
|
|
if (soundmng.opened)
|
|
|
|
{
|
2015-11-18 00:19:53 +00:00
|
|
|
SDL_PauseAudio(1);
|
2016-01-25 12:04:21 +00:00
|
|
|
#if defined(SUPPORT_EXTERNALCHIP)
|
|
|
|
CExternalChipManager::GetInstance()->Mute(true);
|
|
|
|
#endif
|
2015-11-18 00:19:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ----
|
|
|
|
|
2016-01-25 12:04:21 +00:00
|
|
|
void soundmng_initialize()
|
|
|
|
{
|
|
|
|
#if defined(SUPPORT_EXTERNALCHIP)
|
|
|
|
CExternalChipManager::GetInstance()->Initialize();
|
|
|
|
#endif
|
2015-11-18 00:19:53 +00:00
|
|
|
}
|
|
|
|
|
2016-01-25 12:04:21 +00:00
|
|
|
void soundmng_deinitialize()
|
|
|
|
{
|
|
|
|
#if defined(SUPPORT_EXTERNALCHIP)
|
|
|
|
CExternalChipManager::GetInstance()->Deinitialize();
|
|
|
|
#endif
|
2015-11-18 00:19:53 +00:00
|
|
|
}
|