Bitcrusher

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

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