rts/src/sfx/sdl-1.2/src/sound.c

107 lines
2.0 KiB
C

#include <sfx.h>
#include <sfx/port.h>
#include <header.h>
#include <SDL.h>
#include <SDL_mixer.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
static bool mixer_init;
void sfx_free(struct sound *const s)
{
if (s && s->chunk)
Mix_FreeChunk(s->chunk);
}
int sfx_play(const struct sound *const s)
{
if (mixer_init && Mix_PlayChannel(-1, s->chunk, s->loop ? -1 : 0) < 0)
return -1;
return 0;
}
static int load_data(struct sound *const s, FILE *const f)
{
int ret = -1;
SDL_RWops *const ops = SDL_RWFromFP(f, 0);
if (!ops)
{
fprintf(stderr, "SDL_RWFromFP: %s\n", SDL_GetError());
goto end;
}
else if (!(s->chunk = Mix_LoadWAV_RW(ops, 0)))
{
fprintf(stderr, "Mix_LoadWAV_RW: %s\n", SDL_GetError());
goto end;
}
ret = 0;
end:
SDL_FreeRW(ops);
return ret;
}
static int load_header(struct sound *const s, FILE *const f)
{
if (header_load_bool(f, "loop", &s->loop))
return -1;
return 0;
}
int sfx_sound_from_fp(struct sound *const s, FILE *const f, const size_t sz)
{
if (mixer_init)
{
if (load_header(s, f) || load_data(s, f))
return -1;
}
else
/* Skip the file. */
fseek(f, sz, SEEK_CUR);
return 0;
}
void sfx_deinit(void)
{
if (mixer_init)
Mix_CloseAudio();
if (SDL_WasInit(SDL_INIT_AUDIO) & SDL_INIT_AUDIO)
SDL_QuitSubSystem(SDL_INIT_AUDIO);
}
int sfx_init(void)
{
enum {CHUNK_SZ = 4096};
/* Some older systems might not support sound at all. */
if (SDL_InitSubSystem(SDL_INIT_AUDIO))
{
fprintf(stderr, "SDL_InitSubSystem: %s\n", SDL_GetError());
goto failure;
}
if (Mix_OpenAudio(MIX_DEFAULT_FREQUENCY,
MIX_DEFAULT_FORMAT, MIX_DEFAULT_CHANNELS, CHUNK_SZ))
{
fprintf(stderr, "Mix_OpenAudio: %s\n", SDL_GetError());
goto failure;
}
else
mixer_init = true;
return 0;
failure:
sfx_deinit();
fprintf(stderr, "Running without audio support\n");
return 0;
}