From 9f2419a0bc95b2d8b9e8790747e4cf50765787d8 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Tue, 5 Jul 2022 20:12:48 +0000 Subject: [PATCH] SDL for audio conversion --- Makefile | 4 +-- source/engine/circbuf.c | 4 ++- source/engine/circbuf.h | 4 +-- source/engine/dsp.c | 20 ++++++++++-- source/engine/dsp.h | 13 ++++++++ source/engine/sound.c | 70 +++++++++++++++++++++++++++++++++++------ source/engine/sound.h | 8 ++--- source/engine/texture.c | 19 +---------- 8 files changed, 102 insertions(+), 40 deletions(-) diff --git a/Makefile b/Makefile index 9c1cbcc..4b87c02 100755 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ UNAME_P != uname -m CCACHE = #ccache #CC specifies which compiler we're using -CC = $(CCACHE) tcc +CC = $(CCACHE) tcc -DSDL_DISABLE_IMMINTRIN_H MUSL = /usr/local/musl/include @@ -97,7 +97,7 @@ ifeq ($(UNAME), Windows_NT) EXT = .exe else LINKER_FLAGS = -g /usr/lib64/pipewire-0.3/jack/libjack.so.0 #/usr/local/lib/tcc/bcheck.o /usr/local/lib/tcc/bt-exe.o /usr/local/lib/tcc/bt-log.o - ELIBS = m c engine editor glfw3 portaudio rt asound pthread + ELIBS = m c engine editor glfw3 portaudio rt asound pthread SDL2 CLIBS = EXT = endif diff --git a/source/engine/circbuf.c b/source/engine/circbuf.c index 2dcbd59..ddd178d 100644 --- a/source/engine/circbuf.c +++ b/source/engine/circbuf.c @@ -1,10 +1,12 @@ #include "circbuf.h" +#include "util.h" #include "assert.h" -struct circbuf circbuf_init(size_t size, int len) +struct circbuf circbuf_init(size_t size, unsigned int len) { struct circbuf new; + new.len = powof2(len); new.len = len; new.data = calloc(sizeof(short), new.len); new.read = new.write = 0; diff --git a/source/engine/circbuf.h b/source/engine/circbuf.h index d3741d4..52f9600 100644 --- a/source/engine/circbuf.h +++ b/source/engine/circbuf.h @@ -8,10 +8,10 @@ struct circbuf { int16_t *data; uint32_t read; uint32_t write; - int len; + unsigned int len; }; -struct circbuf circbuf_init(size_t size, int len); +struct circbuf circbuf_init(size_t size, unsigned int len); void cbuf_push(struct circbuf *buf, short data); short cbuf_shift(struct circbuf *buf); diff --git a/source/engine/dsp.c b/source/engine/dsp.c index 98c98b3..545fcbf 100644 --- a/source/engine/dsp.c +++ b/source/engine/dsp.c @@ -73,10 +73,12 @@ struct wav gen_triangle(float amp, float freq, int sr, int ch) if (amp > 1) amp = 1; if (amp < 0) amp = 0; + short *data = (short*)new.data; + for (int i = 0; i < new.frames; i++) { short val = 2 * abs( (i/new.frames) - floor( (i/new.frames) + 0.5)); for (int j = 0; j < new.ch; j++) { - new.data[i+j] = val; + data[i+j] = val; } } } @@ -88,12 +90,24 @@ struct wav gen_saw(float amp, float freq, int sr, int ch) if (amp > 1) amp = 1; if (amp < 0) amp = 0; - samp = amp*SHRT_MAX; + short samp = amp*SHRT_MAX; + + short *data = (short*)new.data; for (int i = 0; i < new.frames; i++) { short val = samp * 2 * i/sr - samp; for (int j = 0; j < new.ch; j++) { - new.data[i+j] = val; + data[i+j] = val; } } +} + +void make_dsp_filter() +{ + +} + +void dsp_filter(short *in, short *out, int samples, struct dsp_delay *d) +{ + } \ No newline at end of file diff --git a/source/engine/dsp.h b/source/engine/dsp.h index 41c1be6..ca5c106 100644 --- a/source/engine/dsp.h +++ b/source/engine/dsp.h @@ -1,12 +1,25 @@ #ifndef DSP_H #define DSP_H +#include "circbuf.h" + void am_mod(short *a, short *b, short *c, int n); +struct dsp_filter { + void (*filter)(short *in, short *out, int samples, void *data); + void *data; +}; + +struct dsp_delay { + unsigned int ms_delay; + struct circbuf buf; +}; + struct wav; struct wav gen_sine(float amp, float freq, int sr, int ch); struct wav gen_square(float amp, float freq, int sr, int ch); struct wav gen_triangle(float amp, float freq, int sr, int ch); +struct wav gen_saw(float amp, float freq, int sr, int ch); #endif \ No newline at end of file diff --git a/source/engine/sound.c b/source/engine/sound.c index 226ac90..af9f96e 100755 --- a/source/engine/sound.c +++ b/source/engine/sound.c @@ -7,8 +7,14 @@ #include "limits.h" #include "time.h" + +#include "SDL2/SDL.h" + #include "dsp.h" +#define TSF_IMPLEMENTATION +#include "tsf.h" + #define DR_WAV_IMPLEMENTATION #include "dr_wav.h" @@ -37,6 +43,58 @@ struct sound wavsound; int vidplaying = 0; +struct wav change_samplerate(struct wav w, int rate) +{ + SDL_AudioCVT cvt; + printf("Convert from %i to %i.\n", w.samplerate, rate); + + SDL_BuildAudioCVT(&cvt, AUDIO_S16, w.ch, w.samplerate, AUDIO_S16, w.ch, rate); + + cvt.len = w.frames * w.ch * sizeof(short); + cvt.buf = malloc(cvt.len * cvt.len_mult); + memcpy(cvt.buf, w.data, cvt.len*cvt.len_mult); + SDL_ConvertAudio(&cvt); + + w.samplerate = rate; + free(w.data); + w.data = cvt.buf; + printf("cvt len: %i\n", cvt.len_cvt); + w.frames = cvt.len_cvt / (w.ch * sizeof(short)); + + +/* + float change = (float)rate/w.samplerate; + int oldsamples = w.frames * w.ch; + w.samplerate = rate; + w.frames *= change; + + short *old = (short*)w.data; + short *new = calloc(w.frames * w.ch, sizeof(short)); + + int samples = w.frames*w.ch; + + short s1; + short s2; + + for (int i = 0; i < w.frames; i++) { + for (int j = 0; j < w.ch; j++) { + int v1 = ((float)(i*w.ch+j)/samples) * oldsamples; + int v2 = ((float)(i*w.ch+j+w.ch)/samples) * oldsamples; + printf("Val is %i and %i.\n", v1, v2); + s1 = old[v1]; + s2 = old[v2]; + new[i*w.ch+j] = (s1 + s2) >> 1; // Average of the two with bitshift ops + } + } + + printf("Old samples: %i\nNew samples: %i\nFrames:%i\n", oldsamples, samples, w.frames); + + w.data = new; + + free(old); + */ +} + static int patestCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData) { /* Cast data passed through stream to our structure. */ @@ -59,7 +117,6 @@ static int patestCallback(const void *inputBuffer, void *outputBuffer, unsigned //wavsound.data->gain = -6; float mult = powf(10.f, (float)wavsound.data->gain/20.f); - printf("Mult is %f\n", mult); short *s = (short*)wavsound.data->data; for (int i = 0; i < framesPerBuffer; i++) { out[i*2] = s[wavsound.frame++] * mult; @@ -135,16 +192,9 @@ void sound_init() printf("Loaded wav: ch %i, sr %i, fr %i.\n", mwav.ch, mwav.samplerate, mwav.frames); - mwav = gen_square(1, 150, 48000, 2); + change_samplerate(mwav, 48000); -/* - short *tdata = mwav.data; - mwav.frames /= 2; - short *newdata = calloc(mwav.frames * 2, sizeof(short)); - for (int i = 0; i < mwav.frames; i++) { - newdata[i] = tdata[i*2]; - } -*/ + //mwav = gen_square(1, 150, 48000, 2); wavsound.data = &mwav; wavsound.loop = 1; diff --git a/source/engine/sound.h b/source/engine/sound.h index c4f17c9..48bf7a4 100755 --- a/source/engine/sound.h +++ b/source/engine/sound.h @@ -18,7 +18,7 @@ enum MUS { struct sound { int sound; int loop; - int ch; + unsigned int ch; int fin; int frame; int play; @@ -28,9 +28,9 @@ struct sound { }; struct wav { - int ch; - int samplerate; - int frames; + unsigned int ch; + unsigned int samplerate; + unsigned int frames; double gain; void *data; }; diff --git a/source/engine/texture.c b/source/engine/texture.c index 990df87..8c1b46b 100755 --- a/source/engine/texture.c +++ b/source/engine/texture.c @@ -6,6 +6,7 @@ #include #include "log.h" #include +#include "util.h" static struct { char *key; @@ -167,25 +168,7 @@ void tex_anim_calc_uv(struct TexAnimation *anim) anim->uv = uv; } -unsigned int powof2(unsigned int num) -{ - if (num != 0) { - num--; - num |= (num >> 1); - num |= (num >> 2); - num |= (num >> 4); - num |= (num >> 8); - num |= (num >> 16); - num++; - } - return num; -} - -int ispow2(int num) -{ - return (num && !(num & (num - 1))); -} void tex_bind(struct Texture *tex) {