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 $@
|
||||
|
||||
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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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));
|
||||
}
|
|
@ -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
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