SDL for audio conversion
This commit is contained in:
parent
2d4e2e06c2
commit
9f2419a0bc
4
Makefile
4
Makefile
|
@ -12,7 +12,7 @@ UNAME_P != uname -m
|
||||||
CCACHE = #ccache
|
CCACHE = #ccache
|
||||||
|
|
||||||
#CC specifies which compiler we're using
|
#CC specifies which compiler we're using
|
||||||
CC = $(CCACHE) tcc
|
CC = $(CCACHE) tcc -DSDL_DISABLE_IMMINTRIN_H
|
||||||
|
|
||||||
MUSL = /usr/local/musl/include
|
MUSL = /usr/local/musl/include
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ ifeq ($(UNAME), Windows_NT)
|
||||||
EXT = .exe
|
EXT = .exe
|
||||||
else
|
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
|
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 =
|
CLIBS =
|
||||||
EXT =
|
EXT =
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
#include "circbuf.h"
|
#include "circbuf.h"
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
#include "assert.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;
|
struct circbuf new;
|
||||||
|
new.len = powof2(len);
|
||||||
new.len = len;
|
new.len = len;
|
||||||
new.data = calloc(sizeof(short), new.len);
|
new.data = calloc(sizeof(short), new.len);
|
||||||
new.read = new.write = 0;
|
new.read = new.write = 0;
|
||||||
|
|
|
@ -8,10 +8,10 @@ struct circbuf {
|
||||||
int16_t *data;
|
int16_t *data;
|
||||||
uint32_t read;
|
uint32_t read;
|
||||||
uint32_t write;
|
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);
|
void cbuf_push(struct circbuf *buf, short data);
|
||||||
short cbuf_shift(struct circbuf *buf);
|
short cbuf_shift(struct circbuf *buf);
|
||||||
|
|
||||||
|
|
|
@ -73,10 +73,12 @@ struct wav gen_triangle(float amp, float freq, int sr, int ch)
|
||||||
if (amp > 1) amp = 1;
|
if (amp > 1) amp = 1;
|
||||||
if (amp < 0) amp = 0;
|
if (amp < 0) amp = 0;
|
||||||
|
|
||||||
|
short *data = (short*)new.data;
|
||||||
|
|
||||||
for (int i = 0; i < new.frames; i++) {
|
for (int i = 0; i < new.frames; i++) {
|
||||||
short val = 2 * abs( (i/new.frames) - floor( (i/new.frames) + 0.5));
|
short val = 2 * abs( (i/new.frames) - floor( (i/new.frames) + 0.5));
|
||||||
for (int j = 0; j < new.ch; j++) {
|
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 > 1) amp = 1;
|
||||||
if (amp < 0) amp = 0;
|
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++) {
|
for (int i = 0; i < new.frames; i++) {
|
||||||
short val = samp * 2 * i/sr - samp;
|
short val = samp * 2 * i/sr - samp;
|
||||||
for (int j = 0; j < new.ch; j++) {
|
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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -1,12 +1,25 @@
|
||||||
#ifndef DSP_H
|
#ifndef DSP_H
|
||||||
#define DSP_H
|
#define DSP_H
|
||||||
|
|
||||||
|
#include "circbuf.h"
|
||||||
|
|
||||||
void am_mod(short *a, short *b, short *c, int n);
|
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;
|
||||||
|
|
||||||
struct wav gen_sine(float amp, float freq, int sr, int ch);
|
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_square(float amp, float freq, int sr, int ch);
|
||||||
struct wav gen_triangle(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
|
#endif
|
|
@ -7,8 +7,14 @@
|
||||||
#include "limits.h"
|
#include "limits.h"
|
||||||
#include "time.h"
|
#include "time.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "SDL2/SDL.h"
|
||||||
|
|
||||||
#include "dsp.h"
|
#include "dsp.h"
|
||||||
|
|
||||||
|
#define TSF_IMPLEMENTATION
|
||||||
|
#include "tsf.h"
|
||||||
|
|
||||||
|
|
||||||
#define DR_WAV_IMPLEMENTATION
|
#define DR_WAV_IMPLEMENTATION
|
||||||
#include "dr_wav.h"
|
#include "dr_wav.h"
|
||||||
|
@ -37,6 +43,58 @@ struct sound wavsound;
|
||||||
|
|
||||||
int vidplaying = 0;
|
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)
|
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. */
|
/* 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;
|
//wavsound.data->gain = -6;
|
||||||
|
|
||||||
float mult = powf(10.f, (float)wavsound.data->gain/20.f);
|
float mult = powf(10.f, (float)wavsound.data->gain/20.f);
|
||||||
printf("Mult is %f\n", mult);
|
|
||||||
short *s = (short*)wavsound.data->data;
|
short *s = (short*)wavsound.data->data;
|
||||||
for (int i = 0; i < framesPerBuffer; i++) {
|
for (int i = 0; i < framesPerBuffer; i++) {
|
||||||
out[i*2] = s[wavsound.frame++] * mult;
|
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);
|
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);
|
||||||
|
|
||||||
/*
|
//mwav = gen_square(1, 150, 48000, 2);
|
||||||
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];
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
wavsound.data = &mwav;
|
wavsound.data = &mwav;
|
||||||
wavsound.loop = 1;
|
wavsound.loop = 1;
|
||||||
|
|
|
@ -18,7 +18,7 @@ enum MUS {
|
||||||
struct sound {
|
struct sound {
|
||||||
int sound;
|
int sound;
|
||||||
int loop;
|
int loop;
|
||||||
int ch;
|
unsigned int ch;
|
||||||
int fin;
|
int fin;
|
||||||
int frame;
|
int frame;
|
||||||
int play;
|
int play;
|
||||||
|
@ -28,9 +28,9 @@ struct sound {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wav {
|
struct wav {
|
||||||
int ch;
|
unsigned int ch;
|
||||||
int samplerate;
|
unsigned int samplerate;
|
||||||
int frames;
|
unsigned int frames;
|
||||||
double gain;
|
double gain;
|
||||||
void *data;
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <stb_ds.h>
|
#include <stb_ds.h>
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
char *key;
|
char *key;
|
||||||
|
@ -167,25 +168,7 @@ void tex_anim_calc_uv(struct TexAnimation *anim)
|
||||||
anim->uv = uv;
|
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)
|
void tex_bind(struct Texture *tex)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue