SDL for audio conversion

This commit is contained in:
John Alanbrook 2022-07-05 20:12:48 +00:00
parent 2d4e2e06c2
commit 9f2419a0bc
8 changed files with 102 additions and 40 deletions

View file

@ -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

View file

@ -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;

View file

@ -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);

View file

@ -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)
{
}

View file

@ -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

View file

@ -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;

View file

@ -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;
};

View file

@ -6,6 +6,7 @@
#include <stb_ds.h>
#include "log.h"
#include <math.h>
#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)
{