Bitcrusher
This commit is contained in:
parent
37d6b64bb9
commit
4896bc5e52
6
Makefile
6
Makefile
|
@ -120,12 +120,12 @@ linkinclude = $(BIN)include
|
||||||
|
|
||||||
LINK = $(LIBPATH) $(LINKER_FLAGS) $(LELIBS) -o $@
|
LINK = $(LIBPATH) $(LINKER_FLAGS) $(LELIBS) -o $@
|
||||||
|
|
||||||
engine: $(yuginec:.%.c=$(objprefix)%.o) $(ENGINE)
|
engine: tags $(yuginec:.%.c=$(objprefix)%.o) $(ENGINE)
|
||||||
@echo Linking engine
|
@echo Linking engine
|
||||||
@$(CC) $@ $(LINK)
|
@$(CC) $@ $(LINK)
|
||||||
@echo Finished build
|
@echo Finished build
|
||||||
|
|
||||||
editor: $(yuginec:.%.c=$(objprefix)%.o) $(EDITOR) $(ENGINE)
|
editor: tags $(yuginec:.%.c=$(objprefix)%.o) $(EDITOR) $(ENGINE)
|
||||||
@echo Linking editor
|
@echo Linking editor
|
||||||
@$(CC) $^ $(LINK)
|
@$(CC) $^ $(LINK)
|
||||||
@echo Finished build
|
@echo Finished build
|
||||||
|
@ -145,7 +145,7 @@ xbrainstorm: $(bsobjects) $(ENGINE) $(EDITOR)
|
||||||
$(CC) $^ $(LINK)
|
$(CC) $^ $(LINK)
|
||||||
@mv xbrainstorm brainstorm/brainstorm$(EXT)
|
@mv xbrainstorm brainstorm/brainstorm$(EXT)
|
||||||
|
|
||||||
pinball: $(ENGINE) $(pinobjects)
|
pinball: tags $(ENGINE) $(pinobjects)
|
||||||
@echo Making pinball
|
@echo Making pinball
|
||||||
@$(CC) $(pinobjects) $(LINK) -o $@
|
@$(CC) $(pinobjects) $(LINK) -o $@
|
||||||
@mv pinball paladin/pinball
|
@mv pinball paladin/pinball
|
||||||
|
|
|
@ -494,14 +494,14 @@ void editor_project_gui()
|
||||||
NK_WINDOW_NO_SCROLLBAR))
|
NK_WINDOW_NO_SCROLLBAR))
|
||||||
{
|
{
|
||||||
nk_layout_row_dynamic(ctx, 25, 2);
|
nk_layout_row_dynamic(ctx, 25, 2);
|
||||||
static struct sound *ss;
|
static struct wav ss;
|
||||||
|
|
||||||
if (nk_button_label(ctx, "Load sound")) {
|
if (nk_button_label(ctx, "Load sound")) {
|
||||||
ss = make_sound("alert.wav");
|
ss = make_sound("alert.wav");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nk_button_label(ctx, "Play sound")) {
|
if (nk_button_label(ctx, "Play sound")) {
|
||||||
play_sound(ss);
|
play_sound(&ss);
|
||||||
}
|
}
|
||||||
|
|
||||||
nk_layout_row_dynamic(ctx, 30, 2);
|
nk_layout_row_dynamic(ctx, 30, 2);
|
||||||
|
|
|
@ -130,6 +130,8 @@ struct wav gen_triangle(float amp, float freq, int sr, int ch)
|
||||||
data[i+j] = val;
|
data[i+j] = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wav gen_saw(float amp, float freq, int sr, int ch)
|
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;
|
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)
|
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 L = out[i*CHANNELS];
|
||||||
short R = out[i*CHANNELS +1];
|
short R = out[i*CHANNELS +1];
|
||||||
|
|
||||||
|
|
||||||
if (*deg > 0) {
|
if (*deg > 0) {
|
||||||
|
|
||||||
|
|
||||||
out[i*CHANNELS] = short_gain(L, db1);
|
out[i*CHANNELS] = short_gain(L, db1);
|
||||||
out[i*CHANNELS+1] = (R + short_gain(L, db2)) / 2;
|
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+1] = short_gain(R, db1);
|
||||||
out[i*CHANNELS] = short_gain(L, db1) + short_gain(R, db2);
|
out[i*CHANNELS] = short_gain(L, db1) + short_gain(R, db2);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dsp_mono(void *p, short *out, int n)
|
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++)
|
for (int j = 0; j < CHANNELS; j++)
|
||||||
out[i*CHANNELS+j] = val;
|
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 */
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -22,6 +22,8 @@ struct dsp_filter {
|
||||||
int dirty;
|
int dirty;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct dsp_filter dsp_filter(void *data, void (*filter)(void *data, short *out, int samples));
|
||||||
|
|
||||||
struct dsp_fir {
|
struct dsp_fir {
|
||||||
float freq;
|
float freq;
|
||||||
int n;
|
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_mono(void *p, short *out, int n);
|
||||||
|
|
||||||
|
void dsp_bitcrush(void *p, short *out, int n);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -10,6 +10,7 @@ struct bus {
|
||||||
int on;
|
int on;
|
||||||
struct dsp_filter in;
|
struct dsp_filter in;
|
||||||
short buf[BUF_FRAMES*CHANNELS];
|
short buf[BUF_FRAMES*CHANNELS];
|
||||||
|
float gain;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct listener {
|
struct listener {
|
||||||
|
@ -22,6 +23,7 @@ extern short mastermix[BUF_FRAMES*CHANNELS];
|
||||||
|
|
||||||
struct bus *first_free_bus(struct dsp_filter in);
|
struct bus *first_free_bus(struct dsp_filter in);
|
||||||
void bus_fill_buffers(short *master, int n);
|
void bus_fill_buffers(short *master, int n);
|
||||||
|
void bus_free(struct bus *bus);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -31,8 +31,22 @@
|
||||||
|
|
||||||
const char *audioDriver;
|
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)
|
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_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));
|
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;
|
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 tarmax = db2short(lv);
|
||||||
short max = 0;
|
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;
|
struct osc sin600;
|
||||||
|
@ -143,40 +163,70 @@ struct wav make_sound(const char *wav)
|
||||||
mwav = change_samplerate(mwav, 48000);
|
mwav = change_samplerate(mwav, 48000);
|
||||||
}
|
}
|
||||||
|
|
||||||
mwav.gain = 0;
|
mwav.gain = 1.f;
|
||||||
|
|
||||||
normalize_gain(&mwav, -3);
|
|
||||||
|
|
||||||
return mwav;
|
return mwav;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sound play_sound(struct wav *wav)
|
struct sound *play_sound(struct wav *wav)
|
||||||
{
|
{
|
||||||
struct sound new;
|
struct sound *new = calloc(1, sizeof(*new));
|
||||||
new.loop = 0;
|
|
||||||
new.frame = 0;
|
|
||||||
new.gain = 0;
|
|
||||||
new.data = wav;
|
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;
|
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)
|
struct music 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("CIrcus mp3 channels: %ui, samplerate: %ui\n", mp3.channels, mp3.sampleRate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void audio_init()
|
void audio_init()
|
||||||
{
|
{
|
||||||
//audioDriver = SDL_GetAudioDeviceName(0,0);
|
//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)
|
void sound_fillbuf(struct sound *s, short *buf, int n)
|
||||||
{
|
{
|
||||||
|
float gainmult = pct2mult(s->data->gain);
|
||||||
|
|
||||||
short *in = s->data->data;
|
short *in = s->data->data;
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
for (int j = 0; j < 2; j++) {
|
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++;
|
s->frame++;
|
||||||
if (s->frame == s->data->frames) {
|
if (s->frame == s->data->frames) {
|
||||||
s->frame = 0;
|
|
||||||
if (s->loop > 0) {
|
if (s->loop > 0) {
|
||||||
s->loop--;
|
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 soundstream_make()
|
||||||
{
|
{
|
||||||
struct soundstream new;
|
struct soundstream new;
|
||||||
|
@ -259,4 +320,11 @@ float pct2db(float pct)
|
||||||
if (pct <= 0) return -72.f;
|
if (pct <= 0) return -72.f;
|
||||||
|
|
||||||
return 10*log2(pct);
|
return 10*log2(pct);
|
||||||
|
}
|
||||||
|
|
||||||
|
float pct2mult(float pct)
|
||||||
|
{
|
||||||
|
if (pct <= 0) return 0.f;
|
||||||
|
|
||||||
|
return pow(10, 0.5*log2(pct));
|
||||||
}
|
}
|
|
@ -26,20 +26,28 @@ struct soundstream soundstream_make();
|
||||||
struct sound {
|
struct sound {
|
||||||
int loop;
|
int loop;
|
||||||
int frame;
|
int frame;
|
||||||
|
int playing;
|
||||||
float gain;
|
float gain;
|
||||||
|
|
||||||
struct wav *data;
|
struct wav *data;
|
||||||
|
struct bus *bus;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wav {
|
struct wav {
|
||||||
unsigned int ch;
|
unsigned int ch;
|
||||||
unsigned int samplerate;
|
unsigned int samplerate;
|
||||||
unsigned int frames;
|
unsigned int frames;
|
||||||
float gain;
|
float gain; /* In dB */
|
||||||
|
|
||||||
void *data;
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct soundstream {
|
||||||
|
SDL_AudioStream *srconv;
|
||||||
|
void *data;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
struct music {
|
struct music {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -53,9 +61,22 @@ void audio_close();
|
||||||
void sound_fillbuf(struct sound *s, short *buf, int n);
|
void sound_fillbuf(struct sound *s, short *buf, int n);
|
||||||
|
|
||||||
struct wav make_sound(const char *wav);
|
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();
|
const char *get_audio_driver();
|
||||||
|
@ -67,9 +88,11 @@ int open_device(const char *adriver);
|
||||||
|
|
||||||
float short2db(short val);
|
float short2db(short val);
|
||||||
short db2short(float db);
|
short db2short(float db);
|
||||||
float pct2db(float pct);
|
|
||||||
short short_gain(short val, float db);
|
short short_gain(short val, float db);
|
||||||
|
|
||||||
|
float pct2db(float pct);
|
||||||
|
float pct2mult(float pct);
|
||||||
|
|
||||||
void audio_init();
|
void audio_init();
|
||||||
|
|
||||||
|
|
||||||
|
|
3158
source/engine/tinyspline.c
Normal file
3158
source/engine/tinyspline.c
Normal file
File diff suppressed because it is too large
Load diff
2886
source/engine/tinyspline.h
Normal file
2886
source/engine/tinyspline.h
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue