Fixed anim2d bug; fixed sound bug; free oneshots now

This commit is contained in:
John Alanbrook 2023-01-16 19:20:07 +00:00
parent 01256542b6
commit 4ee6e1683b
8 changed files with 48 additions and 90 deletions

View file

@ -12,6 +12,7 @@
#include "mix.h" #include "mix.h"
#include "limits.h" #include "limits.h"
#include "iir.h" #include "iir.h"
#include "dsp.h"
struct shader *vid_shader; struct shader *vid_shader;
@ -101,7 +102,7 @@ void ds_openvideo(struct datastream *ds, const char *video, const char *adriver)
plm_set_audio_stream(ds->plm, 0); plm_set_audio_stream(ds->plm, 0);
// Adjust the audio lead time according to the audio_spec buffer size // Adjust the audio lead time according to the audio_spec buffer size
plm_set_audio_lead_time(ds->plm, 4096/48000); plm_set_audio_lead_time(ds->plm, BUF_FRAMES/SAMPLERATE);
ds->playing = true; ds->playing = true;
} }

View file

@ -17,6 +17,9 @@
#include "nuke.h" #include "nuke.h"
#include "sound.h" #include "sound.h"
#include "font.h" #include "font.h"
#include "sound.h"
#include "music.h"
#include "level.h"
struct color duk2color(duk_context *duk, int p) struct color duk2color(duk_context *duk, int p)
{ {
@ -185,8 +188,7 @@ duk_ret_t duk_register_collide(duk_context *duk) {
int go = duk_get_int(duk, 3); int go = duk_get_int(duk, 3);
struct callee c = {fn, obj}; struct callee c = {fn, obj};
phys2d_add_handler_type(cmd, go, c);
phys2d_add_handler_type(0, go, c);
return 0; return 0;
} }
@ -378,8 +380,6 @@ duk_ret_t duk_make_sprite(duk_context *duk) {
duk_ret_t duk_make_anim2d(duk_context *duk) { duk_ret_t duk_make_anim2d(duk_context *duk) {
int go = duk_to_int(duk, 0); int go = duk_to_int(duk, 0);
const char *path = duk_to_string(duk, 1); const char *path = duk_to_string(duk, 1);
int frames = duk_to_int(duk, 2);
int fps = duk_to_int(duk, 3);
int sprite = make_sprite(go); int sprite = make_sprite(go);
struct sprite *sp = id2sprite(sprite); struct sprite *sp = id2sprite(sprite);

View file

@ -37,18 +37,6 @@ static struct {
struct wav *value; struct wav *value;
} *wavhash = NULL; } *wavhash = NULL;
const char *audioDriver;
void new_samplerate(short *in, short *out, int n, int ch, int sr_in, int sr_out)
{
/*
SDL_AudioStream *stream = SDL_NewAudioStream(AUDIO_S16, ch, sr_in, AUDIO_S16, ch, sr_out);
SDL_AudioStreamPut(stream, in, n * ch * sizeof(short));
SDL_AudioStreamGet(stream, out, n * ch * sizeof(short));
SDL_FreeAudioStream(stream);
*/
}
static struct wav change_channels(struct wav w, int ch) static struct wav change_channels(struct wav w, int ch)
{ {
short *data = w.data; short *data = w.data;
@ -102,8 +90,6 @@ static struct wav change_samplerate(struct wav w, int rate)
static int patestCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData) static int patestCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
{ {
short *out = (short*)outputBuffer;
bus_fill_buffers(outputBuffer, framesPerBuffer); bus_fill_buffers(outputBuffer, framesPerBuffer);
return 0; return 0;
@ -153,21 +139,11 @@ void print_devices()
void sound_init() void sound_init()
{ {
mixer_init();
PaError err = Pa_Initialize(); PaError err = Pa_Initialize();
check_pa_err(err); check_pa_err(err);
err = Pa_OpenDefaultStream(&stream_def, 0, CHANNELS, paInt16, SAMPLERATE, BUF_FRAMES, patestCallback, NULL);
/*
PaStreamParameters outparams;
outparams.channelCount = 2;
outparams.device = 19;
outparams.sampleFormat = paInt16;
outparams.suggestedLatency = Pa_GetDeviceInfo(outparams.device)->defaultLowOutputLatency;
outparams.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(&stream_def, NULL, &outparams, 48000, 4096, paNoFlag, patestCallback, &data);
*/
err = Pa_OpenDefaultStream(&stream_def, 0, 2, paInt16, SAMPLERATE, BUF_FRAMES, patestCallback, NULL);
check_pa_err(err); check_pa_err(err);
err = Pa_StartStream(stream_def); err = Pa_StartStream(stream_def);
@ -175,16 +151,6 @@ void sound_init()
} }
void audio_open(const char *device)
{
//Mix_OpenAudioDevice(44100, MIX_DEFAULT_FORMAT, 2, 2048, device, 0);
}
void audio_close()
{
//Mix_CloseAudio();
}
struct wav *make_sound(const char *wav) struct wav *make_sound(const char *wav)
{ {
int index = shgeti(wavhash, wav); int index = shgeti(wavhash, wav);
@ -195,13 +161,13 @@ struct wav *make_sound(const char *wav)
if (mwav.samplerate != SAMPLERATE) { if (mwav.samplerate != SAMPLERATE) {
YughInfo("Changing samplerate of %s from %d to %d.", wav, mwav.samplerate, 48000); YughInfo("Changing samplerate of %s from %d to %d.", wav, mwav.samplerate, SAMPLERATE);
mwav = change_samplerate(mwav, 48000); mwav = change_samplerate(mwav, SAMPLERATE);
} }
if (mwav.ch != CHANNELS) { if (mwav.ch != CHANNELS) {
YughInfo("Changing channels of %s from %d to %d.", wav, mwav.ch, CHANNELS); YughInfo("Changing channels of %s from %d to %d.", wav, mwav.ch, CHANNELS);
//mwav = change_channels(mwav, CHANNELS); mwav = change_channels(mwav, CHANNELS);
} }
mwav.gain = 1.f; mwav.gain = 1.f;
@ -233,13 +199,19 @@ struct soundstream *soundstream_make()
return new; return new;
} }
void kill_oneshot(struct sound *s)
{
free(s);
}
void play_oneshot(struct wav *wav) { void play_oneshot(struct wav *wav) {
struct sound *new = calloc(1, sizeof(*new)); struct sound *new = malloc(sizeof(*new));
new->data = wav; new->data = wav;
new->bus = first_free_bus(dsp_filter(new, sound_fillbuf)); new->bus = first_free_bus(dsp_filter(new, sound_fillbuf));
new->playing=1; new->playing=1;
new->loop=0; new->loop=0;
new->frame = 0; new->frame = 0;
new->endcb = kill_oneshot;
} }
struct sound *play_sound(struct wav *wav) struct sound *play_sound(struct wav *wav)
@ -292,41 +264,23 @@ int sound_stopped(const struct sound *s)
return !s->playing && s->frame == 0; return !s->playing && s->frame == 0;
} }
struct music make_music(const char *mp3) struct mp3 make_music(const char *mp3)
{ {
drmp3 new; drmp3 new;
if (!drmp3_init_file(&new, mp3, NULL)) { if (!drmp3_init_file(&new, mp3, NULL)) {
YughError("Could not open mp3 file %s.", mp3); YughError("Could not open mp3 file %s.", mp3);
} }
struct mp3 newmp3 = {};
return newmp3;
} }
void audio_init()
{
//audioDriver = SDL_GetAudioDeviceName(0,0);
}
void close_audio_device(int device) void close_audio_device(int device)
{ {
//SDL_CloseAudioDevice(device);
} }
int open_device(const char *adriver) int open_device(const char *adriver)
{ {
/*
SDL_AudioSpec audio_spec;
SDL_memset(&audio_spec, 0, sizeof(audio_spec));
audio_spec.freq = SAMPLERATE;
audio_spec.format = AUDIO_F32;
audio_spec.channels = 2;
audio_spec.samples = BUF_FRAMES;
int dev = (int) SDL_OpenAudioDevice(adriver, 0, &audio_spec, NULL, 0);
SDL_PauseAudioDevice(dev, 0);
return dev;
*/
return 0; return 0;
} }
@ -341,16 +295,13 @@ void sound_fillbuf(struct sound *s, short *buf, int n)
s->frame++; s->frame++;
if (s->frame == s->data->frames) { if (s->frame == s->data->frames) {
if (s->loop > 0) {
s->loop--;
s->frame = 0;
} else {
bus_free(s->bus); bus_free(s->bus);
s->bus = NULL;
s->endcb(s);
return; return;
} }
} }
} }
}
void mp3_fillbuf(struct sound *s, short *buf, int n) void mp3_fillbuf(struct sound *s, short *buf, int n)
{ {
@ -364,13 +315,13 @@ void soundstream_fillbuf(struct soundstream *s, short *buf, int n)
int max = s->buf->write - s->buf->read; int max = s->buf->write - s->buf->read;
int lim = (max < n*CHANNELS) ? max : n*CHANNELS; int lim = (max < n*CHANNELS) ? max : n*CHANNELS;
for (int i = 0; i < lim; i++) { for (int i = 0; i < lim; i++) {
buf[i] = cbuf_shift(&s->buf); buf[i] = cbuf_shift(s->buf);
} }
} }
float short2db(short val) float short2db(short val)
{ {
return 20*log10(abs((double)val) / SHRT_MAX); return 20*log10(abs(val) / SHRT_MAX);
} }
short db2short(float db) short db2short(float db)

View file

@ -21,10 +21,6 @@ struct soundstream {
struct circbuf *buf; struct circbuf *buf;
}; };
struct soundconvstream {
void *data;
};
struct soundstream *soundstream_make(); struct soundstream *soundstream_make();
/* A playing sound */ /* A playing sound */
@ -36,25 +32,24 @@ struct sound {
struct wav *data; struct wav *data;
struct bus *bus; struct bus *bus;
void (*endcb)(struct sound*);
}; };
/* Represents a sound file */ /* Represents a sound file */
struct wav { struct wav {
unsigned int ch; unsigned int ch;
unsigned int samplerate; unsigned int samplerate;
unsigned int frames; unsigned long long frames;
float gain; /* In dB */ float gain; /* In dB */
void *data; void *data;
}; };
struct mp3 {
struct music {
}; };
extern const char *audioDriver;
void sound_init(); void sound_init();
void audio_open(const char *device); void audio_open(const char *device);
void audio_close(); void audio_close();
@ -65,6 +60,7 @@ struct wav *make_sound(const char *wav);
void free_sound(const char *wav); void free_sound(const char *wav);
void wav_norm_gain(struct wav *w, double lv); void wav_norm_gain(struct wav *w, double lv);
struct sound *play_sound(struct wav *wav); struct sound *play_sound(struct wav *wav);
void play_oneshot(struct wav *wav);
int sound_playing(const struct sound *s); int sound_playing(const struct sound *s);
int sound_paused(const struct sound *s); int sound_paused(const struct sound *s);
@ -74,7 +70,7 @@ void sound_pause(struct sound *s);
void sound_resume(struct sound *s); void sound_resume(struct sound *s);
void sound_stop(struct sound *s); void sound_stop(struct sound *s);
struct music make_music(const char *mp3); struct mp3 make_mp3(const char *mp3);
const char *get_audio_driver(); const char *get_audio_driver();

View file

@ -2,9 +2,9 @@
#define DSP_H #define DSP_H
#define SAMPLERATE 48000 #define SAMPLERATE 48000
#define BUF_FRAMES 4096 #define BUF_FRAMES 128 /* At 48k, 128 needed for 240fps consistency */
#define CHANNELS 2 #define CHANNELS 2
#define MUSIZE 2
#include "circbuf.h" #include "circbuf.h"

View file

@ -12,6 +12,8 @@ static int first = 0; /* First bus available */
static int first_on = -1; /* First bus to fill buffer with */ static int first_on = -1; /* First bus to fill buffer with */
short mastermix[BUF_FRAMES*CHANNELS]; short mastermix[BUF_FRAMES*CHANNELS];
static int initted = 0;
void mixer_init() { void mixer_init() {
for (int i = 0; i < 256; i++) { for (int i = 0; i < 256; i++) {
bus[i].next = i+1; bus[i].next = i+1;
@ -20,9 +22,16 @@ void mixer_init() {
} }
bus[255].next = -1; bus[255].next = -1;
initted = 1;
} }
struct bus *first_free_bus(struct dsp_filter in) { struct bus *first_free_bus(struct dsp_filter in) {
if (!initted) {
YughError("Tried to use a mixing bus without calling mixer_init().");
return NULL;
}
if (first == -1) return NULL; if (first == -1) return NULL;
int ret = first; int ret = first;
first = bus[ret].next; first = bus[ret].next;

View file

@ -52,7 +52,7 @@ void dsp_midi_fillbuf(struct dsp_midi_song *song, void *out, int n)
tsf_render_short(song->sf, o, TSF_BLOCK, 0); tsf_render_short(song->sf, o, TSF_BLOCK, 0);
o += TSF_BLOCK*2; o += TSF_BLOCK*CHANNELS;
song->time += TSF_BLOCK * (1000.f/SAMPLERATE); song->time += TSF_BLOCK * (1000.f/SAMPLERATE);
} }

View file

@ -124,7 +124,7 @@ void tex_draw(struct Texture *tex, float pos[2], float angle, float size[2], flo
memcpy(r_model, UNITMAT4, sizeof(UNITMAT4)); memcpy(r_model, UNITMAT4, sizeof(UNITMAT4));
memcpy(s_model, UNITMAT4, sizeof(UNITMAT4)); memcpy(s_model, UNITMAT4, sizeof(UNITMAT4));
mfloat_t t_scale[2] = { tex->width, tex->height }; mfloat_t t_scale[2] = { tex->width * st_s_w(r), tex->height * st_s_h(r) };
mfloat_t t_offset[2] = { offset[0] * t_scale[0], offset[1] * t_scale[1] }; mfloat_t t_offset[2] = { offset[0] * t_scale[0], offset[1] * t_scale[1] };
mat4_translate_vec2(model, t_offset); mat4_translate_vec2(model, t_offset);
@ -167,6 +167,7 @@ void sprite_draw(struct sprite *sprite)
cpVect cpos = cpBodyGetPosition(go->body); cpVect cpos = cpBodyGetPosition(go->body);
float pos[2] = {cpos.x, cpos.y}; float pos[2] = {cpos.x, cpos.y};
float size[2] = { sprite->size[0] * go->scale * go->flipx, sprite->size[1] * go->scale * go->flipy }; float size[2] = { sprite->size[0] * go->scale * go->flipx, sprite->size[1] * go->scale * go->flipy };
if (sprite->tex->opts.animation) { if (sprite->tex->opts.animation) {
tex_draw(sprite->tex, pos, cpBodyGetAngle(go->body), size, sprite->pos, anim_get_rect(&sprite->anim)); tex_draw(sprite->tex, pos, cpBodyGetAngle(go->body), size, sprite->pos, anim_get_rect(&sprite->anim));
} else { } else {