Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wii: preload some audio voices #390

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions ball/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "package.h"
#include "log.h"
#include "game_client.h"
#include "game_common.h"
#include "strbuf/substr.h"
#include "strbuf/joinstr.h"
#include "lang.h"
Expand Down Expand Up @@ -942,6 +943,24 @@ static int main_init(int argc, char *argv[])
/* Initialize audio. */

audio_init();
audio_cache(AUD_MENU);
audio_cache(AUD_BALL);
audio_cache(AUD_BUMPS);
audio_cache(AUD_BUMPM);
audio_cache(AUD_BUMPL);
audio_cache(AUD_COIN);
audio_cache(AUD_TICK);
audio_cache(AUD_TOCK);
audio_cache(AUD_SWITCH);
audio_cache(AUD_JUMP);
audio_cache(AUD_GOAL);
audio_cache(AUD_SCORE);
audio_cache(AUD_FALL);
audio_cache(AUD_TIME);
audio_cache(AUD_OVER);
audio_cache(AUD_GROW);
audio_cache(AUD_SHRINK);
audio_cache(AUD_JUMP);
tilt_init();

/* Initialize video. */
Expand Down
152 changes: 151 additions & 1 deletion share/audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,19 @@
#define AUDIO_RATE 44100
#define AUDIO_CHAN 2

struct cached_voice
{
char *name;
short *samples;
int num_samples; /* sample = 16 bits of data, one channel only */
int chan;
struct cached_voice *next;
};

struct voice
{
struct cached_voice *cached_voice;
int cached_voice_start;
OggVorbis_File vf;
float amp;
float damp;
Expand All @@ -55,6 +66,7 @@ static struct voice *music = NULL;
static struct voice *queue = NULL;
static struct voice *voices = NULL;
static short *buffer = NULL;
static struct cached_voice *cached_voices = NULL;

static ov_callbacks callbacks = {
fs_ov_read, fs_ov_seek, fs_ov_close, fs_ov_tell
Expand All @@ -71,6 +83,113 @@ static ov_callbacks callbacks = {
else (d) = (short) T; \
}

static int cached_voice_step(struct voice *V, float volume, Uint8 *stream, int length)
{
short *obuf = (short *) stream;

const struct cached_voice *CV = V->cached_voice;
int i, n = 1, c = 0, r = 0;

/* Compute the total request size for the current stream. */
int sample_size = length / sizeof(short);

if (V->chan == 1) r = sample_size / 2;
if (V->chan == 2) r = sample_size ;

/* While data is coming in and data is still needed... */

if (r == 0) return 1;

n = r;
if (n > CV->num_samples - V->cached_voice_start) {
n = CV->num_samples - V->cached_voice_start;
}
/* Mix mono audio. */

short *ibuf = CV->samples + V->cached_voice_start;
if (V->chan == 1)
for (i = 0; i < n; i += 1)
{
short M = (short) (V->amp * volume * ibuf[i]);

MIX(obuf[c], M); c++;
MIX(obuf[c], M); c++;

V->amp += V->damp;

if (V->amp < 0.0f) V->amp = 0.0;
if (V->amp > 1.0f) V->amp = 1.0;
}

/* Mix stereo audio. */

if (V->chan == 2)
for (i = 0; i < n; i += 2)
{
short L = (short) (V->amp * volume * ibuf[i + 0]);
short R = (short) (V->amp * volume * ibuf[i + 1]);

MIX(obuf[c], L); c++;
MIX(obuf[c], R); c++;

V->amp += V->damp;

if (V->amp < 0.0f) V->amp = 0.0;
if (V->amp > 1.0f) V->amp = 1.0;
}

V->cached_voice_start += n;
return n < r;
}

static struct cached_voice *cached_voice_init(const char *filename)
{
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
int order = 1;
#else
int order = 0;
#endif
struct cached_voice *CV;
fs_file fp;

/* Allocate and initialize a new voice structure. */

if ((CV = (struct cached_voice *) calloc(1, sizeof (struct cached_voice))))
{
/* Note the name. */

CV->name = strdup(filename);

/* Attempt to open the named Ogg stream. */

if ((fp = fs_open_read(filename)))
{
OggVorbis_File vf;
if (ov_open_callbacks(fp, &vf, NULL, 0, callbacks) == 0)
{
vorbis_info *info = ov_info(&vf, -1);
CV->chan = info->channels;

ov_raw_seek(&vf, 0); // Workaround for https://stackoverflow.com/questions/8653670
CV->num_samples = ov_pcm_total(&vf, 0) * CV->chan;
int bufsize = CV->num_samples * sizeof(short);
CV->samples = malloc(bufsize);

long read = 0;
char *buffer = (char *)CV->samples;
while (read < bufsize) {
int b = 0;
read += ov_read(&vf, buffer + read, bufsize - read,
order, 2, 1, &b);
}

ov_clear(&vf);
} else fs_close(fp);
}
}
return CV;
}

static int voice_step(struct voice *V, float volume, Uint8 *stream, int length)
{
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
Expand All @@ -79,6 +198,8 @@ static int voice_step(struct voice *V, float volume, Uint8 *stream, int length)
int order = 0;
#endif

if (V->cached_voice) return cached_voice_step(V, volume, stream, length);

short *obuf = (short *) stream;
char *ibuf = (char *) buffer;

Expand Down Expand Up @@ -160,6 +281,22 @@ static struct voice *voice_init(const char *filename, float a)

V->name = strdup(filename);

struct cached_voice *CV = NULL;
for (CV = cached_voices; CV; CV = CV->next)
if (strcmp(CV->name, filename) == 0) {
V->cached_voice = CV;
V->cached_voice_start = 0;
V->amp = a;
V->damp = 0;
V->chan = CV->chan;
V->play = 1;
V->loop = 0;

if (V->amp > 1.0f) V->amp = 1.0;
if (V->amp < 0.0f) V->amp = 0.0;

return V;
}
/* Attempt to open the named Ogg stream. */

if ((fp = fs_open_read(filename)))
Expand Down Expand Up @@ -335,7 +472,11 @@ void audio_play(const char *filename, float a)
for (V = voices; V; V = V->next)
if (strcmp(V->name, filename) == 0)
{
ov_raw_seek(&V->vf, 0);
if (V->cached_voice) {
V->cached_voice_start = 0;
} else {
ov_raw_seek(&V->vf, 0);
}

V->amp = a;

Expand Down Expand Up @@ -363,6 +504,15 @@ void audio_play(const char *filename, float a)
}
}

void audio_cache(const char *filename)
{
struct cached_voice *CV = cached_voice_init(filename);
if (CV) {
CV->next = cached_voices;
cached_voices = CV;
}
}

/*---------------------------------------------------------------------------*/

static void audio_music_play(const char *filename)
Expand Down
1 change: 1 addition & 0 deletions share/audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
void audio_init(void);
void audio_free(void);
void audio_play(const char *, float);
void audio_cache(const char *);

void audio_music_fade_to(float, const char *);
void audio_music_fade_in(float);
Expand Down