Bitcrusher

This commit is contained in:
John Alanbrook 2022-07-12 20:43:02 +00:00
parent 37d6b64bb9
commit 4896bc5e52
9 changed files with 6184 additions and 37 deletions

View file

@ -120,12 +120,12 @@ linkinclude = $(BIN)include
LINK = $(LIBPATH) $(LINKER_FLAGS) $(LELIBS) -o $@
engine: $(yuginec:.%.c=$(objprefix)%.o) $(ENGINE)
engine: tags $(yuginec:.%.c=$(objprefix)%.o) $(ENGINE)
@echo Linking engine
@$(CC) $@ $(LINK)
@echo Finished build
editor: $(yuginec:.%.c=$(objprefix)%.o) $(EDITOR) $(ENGINE)
editor: tags $(yuginec:.%.c=$(objprefix)%.o) $(EDITOR) $(ENGINE)
@echo Linking editor
@$(CC) $^ $(LINK)
@echo Finished build
@ -145,7 +145,7 @@ xbrainstorm: $(bsobjects) $(ENGINE) $(EDITOR)
$(CC) $^ $(LINK)
@mv xbrainstorm brainstorm/brainstorm$(EXT)
pinball: $(ENGINE) $(pinobjects)
pinball: tags $(ENGINE) $(pinobjects)
@echo Making pinball
@$(CC) $(pinobjects) $(LINK) -o $@
@mv pinball paladin/pinball

View file

@ -494,14 +494,14 @@ void editor_project_gui()
NK_WINDOW_NO_SCROLLBAR))
{
nk_layout_row_dynamic(ctx, 25, 2);
static struct sound *ss;
static struct wav ss;
if (nk_button_label(ctx, "Load sound")) {
ss = make_sound("alert.wav");
}
if (nk_button_label(ctx, "Play sound")) {
play_sound(ss);
play_sound(&ss);
}
nk_layout_row_dynamic(ctx, 30, 2);

View file

@ -130,6 +130,8 @@ struct wav gen_triangle(float amp, float freq, int sr, int ch)
data[i+j] = val;
}
}
return new;
}
struct wav gen_saw(float amp, float freq, int sr, int ch)
@ -149,11 +151,16 @@ struct wav gen_saw(float amp, float freq, int sr, int ch)
data[i+j] = val;
}
}
return new;
}
void make_dsp_filter()
struct dsp_filter dsp_filter(void *data, void (*filter)(void *data, short *out, int samples))
{
struct dsp_filter new;
new.data = data;
data.filter = filter;
return new;
}
void dsp_filter(short *in, short *out, int samples, struct dsp_delay *d)
@ -600,10 +607,7 @@ void dsp_pan(float *deg, short *out, int n)
short L = out[i*CHANNELS];
short R = out[i*CHANNELS +1];
if (*deg > 0) {
out[i*CHANNELS] = short_gain(L, db1);
out[i*CHANNELS+1] = (R + short_gain(L, db2)) / 2;
@ -612,13 +616,7 @@ void dsp_pan(float *deg, short *out, int n)
out[i*CHANNELS+1] = short_gain(R, db1);
out[i*CHANNELS] = short_gain(L, db1) + short_gain(R, db2);
}
}
void dsp_mono(void *p, short *out, int n)
@ -629,4 +627,12 @@ void dsp_mono(void *p, short *out, int n)
for (int j = 0; j < CHANNELS; j++)
out[i*CHANNELS+j] = val;
}
}
void dsp_bitcrush(void *p, short *out, int n)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < CHANNELS; j++)
out[i*CHANNELS+j] = (out[i*CHANNELS+j] | 0xFF); /* Mask out the lower 8 bits */
}
}

View file

@ -22,6 +22,8 @@ struct dsp_filter {
int dirty;
};
struct dsp_filter dsp_filter(void *data, void (*filter)(void *data, short *out, int samples));
struct dsp_fir {
float freq;
int n;
@ -147,4 +149,6 @@ void dsp_pan(float *deg, short *out, int n);
void dsp_mono(void *p, short *out, int n);
void dsp_bitcrush(void *p, short *out, int n);
#endif

View file

@ -10,6 +10,7 @@ struct bus {
int on;
struct dsp_filter in;
short buf[BUF_FRAMES*CHANNELS];
float gain;
};
struct listener {
@ -22,6 +23,7 @@ extern short mastermix[BUF_FRAMES*CHANNELS];
struct bus *first_free_bus(struct dsp_filter in);
void bus_fill_buffers(short *master, int n);
void bus_free(struct bus *bus);
#endif

View file

@ -31,8 +31,22 @@
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);
}
struct wav change_samplerate(struct wav w, int rate)
{
int samples = sizeof(short) * w.ch * w.frames;
short *new = malloc(samples);
new_samplerate(w.data, new,
SDL_AudioStream *stream = SDL_NewAudioStream(AUDIO_S16, w.ch, w.samplerate, AUDIO_S16, w.ch, rate);
SDL_AudioStreamPut(stream, w.data, w.frames*w.ch*sizeof(short));
@ -70,7 +84,7 @@ void check_pa_err(PaError e)
static PaStream *stream_def;
void normalize_gain(struct wav *w, double lv)
void wav_norm_gain(struct wav *w, double lv)
{
short tarmax = db2short(lv);
short max = 0;
@ -81,7 +95,13 @@ void normalize_gain(struct wav *w, double lv)
}
}
w->gain = log10((float)tarmax/max) * 20;
float mult = (float)max / tarmax;
for (int i = 0; i < w->frames; i++) {
for (int j = 0; j < w->ch; j++) {
s[i*w->ch + j] *= mult;
}
}
}
struct osc sin600;
@ -143,40 +163,70 @@ struct wav make_sound(const char *wav)
mwav = change_samplerate(mwav, 48000);
}
mwav.gain = 0;
normalize_gain(&mwav, -3);
mwav.gain = 1.f;
return mwav;
}
struct sound play_sound(struct wav *wav)
struct sound *play_sound(struct wav *wav)
{
struct sound new;
new.loop = 0;
new.frame = 0;
new.gain = 0;
struct sound *new = calloc(1, sizeof(*new));
new.data = wav;
// TODO: Make filter to send to mixer
new->bus = first_free_bus(dsp_filter(new, sound_fillbuf));
new->playing = 1;
return new;
}
int sound_playing(const struct sound *s)
{
return s.playing;
}
int sound_paused(const struct sound *s)
{
return (!s.playing && s.frame < s.data->frames);
}
void sound_pause(struct sound *s)
{
s->playing = 0;
bus_free(s->bus);
}
void sound_resume(struct sound *s)
{
s->playing = 1;
s->bus = first_free_bus(dsp_filter(s, sound_fillbuf));
}
void sound_stop(struct sound *s)
{
s->playing = 0;
s->frame = 0;
bus_free(s->bus);
}
int sound_finished(struct sound *s)
{
return !s->playing && s->frame == s->data->frames;
}
int sound_stopped(struct sound *s)
{
return !s->playing && s->frame = 0;
}
struct music make_music(const char *mp3)
{
drmp3 new;
if (!drmp3_init_file(&new, mp3, NULL)) {
YughError("Could not open mp3 file %s.", mp3);
}
//printf("CIrcus mp3 channels: %ui, samplerate: %ui\n", mp3.channels, mp3.sampleRate);
}
void audio_init()
{
//audioDriver = SDL_GetAudioDeviceName(0,0);
@ -208,21 +258,32 @@ int open_device(const char *adriver)
void sound_fillbuf(struct sound *s, short *buf, int n)
{
float gainmult = pct2mult(s->data->gain);
short *in = s->data->data;
for (int i = 0; i < n; i++) {
for (int j = 0; j < 2; j++) {
buf[i*2+j] = in[s->frame+j];
buf[i*2+j] = in[s->frame+j] * gainmult;
}
s->frame++;
if (s->frame == s->data->frames) {
s->frame = 0;
if (s->loop > 0) {
s->loop--;
s->frame = 0;
} else {
bus_free(s->bus);
}
}
}
}
void mp3_fillbuf(struct sound *s, short *buf, int n)
{
}
struct soundstream soundstream_make()
{
struct soundstream new;
@ -259,4 +320,11 @@ float pct2db(float pct)
if (pct <= 0) return -72.f;
return 10*log2(pct);
}
float pct2mult(float pct)
{
if (pct <= 0) return 0.f;
return pow(10, 0.5*log2(pct));
}

View file

@ -26,20 +26,28 @@ struct soundstream soundstream_make();
struct sound {
int loop;
int frame;
int playing;
float gain;
struct wav *data;
struct bus *bus;
};
struct wav {
unsigned int ch;
unsigned int samplerate;
unsigned int frames;
float gain;
float gain; /* In dB */
void *data;
};
struct soundstream {
SDL_AudioStream *srconv;
void *data;
};
struct music {
};
@ -53,9 +61,22 @@ void audio_close();
void sound_fillbuf(struct sound *s, short *buf, int n);
struct wav make_sound(const char *wav);
struct sound *make_music(const char *ogg);
void wav_norm_gain(struct wav *w, double lv);
struct sound play_sound(struct wav *wav);
int sound_playing(struct sound *s);
int sound_paused(struct sound *s);
int sound_stopped(struct sound *s);
int sound_finished(struct sound *s);
void sound_pause(struct sound *s);
void sound_resume(struct sound *s);
void sound_stop(struct sound *s);
struct music make_music(const char *ogg);
void play_sound(struct wav wav);
const char *get_audio_driver();
@ -67,9 +88,11 @@ int open_device(const char *adriver);
float short2db(short val);
short db2short(float db);
float pct2db(float pct);
short short_gain(short val, float db);
float pct2db(float pct);
float pct2mult(float pct);
void audio_init();

3158
source/engine/tinyspline.c Normal file

File diff suppressed because it is too large Load diff

2886
source/engine/tinyspline.h Normal file

File diff suppressed because it is too large Load diff