Mixer and a few filters
This commit is contained in:
parent
1c556a70bc
commit
eb49f0fcc5
2
Makefile
2
Makefile
|
@ -79,7 +79,7 @@ COMPINCLUDE = $(edirs) $(eddirs) $(pindirs) $(bsdirs)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
WARNING_FLAGS = -Wall -Wwrite-strings -Wunsupported #-Wall -Wextra -Wwrite-strings -Wno-unused-parameter -Wno-unused-function -Wno-missing-braces -Wno-incompatible-function-pointer-types -Wno-gnu-statement-expression -Wno-complex-component-init -pedantic
|
WARNING_FLAGS = -Wall -Wwrite-strings -Wunsupported -Wall -Wextra -Wwrite-strings -Wno-unused-parameter -Wno-unused-function -Wno-missing-braces -Wno-incompatible-function-pointer-types -Wno-gnu-statement-expression -Wno-complex-component-init -pedantic
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,16 +22,16 @@ struct fileasset {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct editorVars {
|
struct editorVars {
|
||||||
bool showStats :1 ;
|
bool showStats;
|
||||||
bool showHierarchy :1 ;
|
bool showHierarchy;
|
||||||
bool showLighting :1 ;
|
bool showLighting;
|
||||||
bool showGameSettings :1 ;
|
bool showGameSettings;
|
||||||
bool showViewmode :1 ;
|
bool showViewmode;
|
||||||
bool showDebugMenu :1 ;
|
bool showDebugMenu;
|
||||||
bool showAssetMenu :1 ;
|
bool showAssetMenu;
|
||||||
bool showREPL :1 ;
|
bool showREPL;
|
||||||
bool showExport :1 ;
|
bool showExport;
|
||||||
bool showLevel :1 ;
|
bool showLevel;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gameproject {
|
struct gameproject {
|
||||||
|
|
|
@ -7,7 +7,6 @@ struct circbuf circbuf_init(size_t size, unsigned int len)
|
||||||
{
|
{
|
||||||
struct circbuf new;
|
struct circbuf new;
|
||||||
new.len = powof2(len);
|
new.len = powof2(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;
|
||||||
|
|
||||||
|
@ -23,7 +22,7 @@ int cbuf_empty(struct circbuf *buf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int cbuf_full(struct circbuf *buf) {
|
int cbuf_full(struct circbuf *buf) {
|
||||||
return cbuf_size(buf) == buf->len;
|
return cbuf_size(buf) >= buf->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t cbuf_mask(struct circbuf *buf, uint32_t n) {
|
uint32_t cbuf_mask(struct circbuf *buf, uint32_t n) {
|
||||||
|
@ -31,13 +30,13 @@ uint32_t cbuf_mask(struct circbuf *buf, uint32_t n) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void cbuf_push(struct circbuf *buf, short data) {
|
void cbuf_push(struct circbuf *buf, short data) {
|
||||||
assert(!cbuf_full(buf));
|
//assert(!cbuf_full(buf));
|
||||||
|
|
||||||
buf->data[cbuf_mask(buf,buf->write++)] = data;
|
buf->data[cbuf_mask(buf,buf->write++)] = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
short cbuf_shift(struct circbuf *buf) {
|
short cbuf_shift(struct circbuf *buf) {
|
||||||
assert(!cbuf_empty(buf));
|
//assert(!cbuf_empty(buf));
|
||||||
return buf->data[cbuf_mask(buf, buf->read++)];
|
return buf->data[cbuf_mask(buf, buf->read++)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include "mix.h"
|
||||||
|
#include "limits.h"
|
||||||
|
|
||||||
struct mShader *vid_shader;
|
struct mShader *vid_shader;
|
||||||
|
|
||||||
|
@ -31,7 +33,12 @@ static void render_frame(plm_t * mpeg, plm_frame_t * frame, void *user)
|
||||||
static void render_audio(plm_t * mpeg, plm_samples_t * samples, void *user)
|
static void render_audio(plm_t * mpeg, plm_samples_t * samples, void *user)
|
||||||
{
|
{
|
||||||
struct datastream *ds = user;
|
struct datastream *ds = user;
|
||||||
play_raw(ds->audio_device, samples->interleaved, samples->count * 2);
|
short t;
|
||||||
|
|
||||||
|
for (int i = 0; i < samples->count * CHANNELS; i++) {
|
||||||
|
t = (short)(samples->interleaved[i] * SHRT_MAX);
|
||||||
|
cbuf_push(&ds->astream.buf, t*5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Texture *ds_maketexture(struct datastream *ds)
|
struct Texture *ds_maketexture(struct datastream *ds)
|
||||||
|
@ -62,6 +69,14 @@ void ds_openvideo(struct datastream *ds, const char *video, const char *adriver)
|
||||||
plm_get_duration(ds->plm)
|
plm_get_duration(ds->plm)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ds->astream = soundstream_make();
|
||||||
|
struct dsp_filter astream_filter;
|
||||||
|
astream_filter.data = &ds->astream;
|
||||||
|
astream_filter.filter = soundstream_fillbuf;
|
||||||
|
first_free_bus(astream_filter);
|
||||||
|
|
||||||
|
printf("Circbuf size is %u.\n", ds->astream.buf.len);
|
||||||
|
|
||||||
plm_set_video_decode_callback(ds->plm, render_frame, ds);
|
plm_set_video_decode_callback(ds->plm, render_frame, ds);
|
||||||
plm_set_audio_decode_callback(ds->plm, render_audio, ds);
|
plm_set_audio_decode_callback(ds->plm, render_audio, ds);
|
||||||
plm_set_loop(ds->plm, false);
|
plm_set_loop(ds->plm, false);
|
||||||
|
@ -118,7 +133,7 @@ void ds_advance(struct datastream *ds, double s)
|
||||||
|
|
||||||
void ds_seek(struct datastream *ds, double time)
|
void ds_seek(struct datastream *ds, double time)
|
||||||
{
|
{
|
||||||
clear_raw(ds->audio_device);
|
//clear_raw(ds->audio_device);
|
||||||
plm_seek(ds->plm, time, false);
|
plm_seek(ds->plm, time, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <pl_mpeg.h>
|
#include <pl_mpeg.h>
|
||||||
|
#include "sound.h"
|
||||||
|
|
||||||
struct datastream {
|
struct datastream {
|
||||||
plm_t *plm;
|
plm_t *plm;
|
||||||
|
@ -13,6 +14,7 @@ struct datastream {
|
||||||
uint32_t texture_y;
|
uint32_t texture_y;
|
||||||
uint32_t texture_cb;
|
uint32_t texture_cb;
|
||||||
uint32_t texture_cr;
|
uint32_t texture_cr;
|
||||||
|
struct soundstream astream;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Texture;
|
struct Texture;
|
||||||
|
|
|
@ -3,13 +3,28 @@
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
#include "limits.h"
|
#include "limits.h"
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
|
#include "stdlib.h"
|
||||||
|
|
||||||
#define PI 3.14159265
|
#define PI 3.14159265
|
||||||
|
|
||||||
void am_mod(short *a, short *b, short *c, int n)
|
struct dsp_filter make_dsp(void *data, void (*in)(void *data, short *out, int n)) {
|
||||||
|
struct dsp_filter new;
|
||||||
|
new.data = data;
|
||||||
|
new.filter = in;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dsp_run(struct dsp_filter filter, short *out, int n) {
|
||||||
|
filter.filter(filter.data, out, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void am_mod(struct dsp_ammod *mod, short *c, int n)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < n; i++) {
|
dsp_run(mod->ina, mod->abuf, n);
|
||||||
c[i] = (a[i]*b[i])>>15;
|
dsp_run(mod->inb, mod->bbuf, n);
|
||||||
|
|
||||||
|
for (int i = 0; i < n*2; i++) {
|
||||||
|
c[i] = (mod->abuf[i]*mod->bbuf[i])>>15;
|
||||||
|
//c[i] = mod->abuf[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,10 +53,11 @@ struct wav gen_sine(float amp, float freq, int sr, int ch)
|
||||||
|
|
||||||
for (int j = 0; j < new.ch; j++) {
|
for (int j = 0; j < new.ch; j++) {
|
||||||
data[i*new.ch+j] = val;
|
data[i*new.ch+j] = val;
|
||||||
printf("Element %i gets val %i.\n", i*new.frames+j, val);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("Made sine with %i frames.\n", new.frames);
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,4 +128,106 @@ void make_dsp_filter()
|
||||||
void dsp_filter(short *in, short *out, int samples, struct dsp_delay *d)
|
void dsp_filter(short *in, short *out, int samples, struct dsp_delay *d)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void dsp_rectify(short *in, short *out, int n)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
out[i] = abs(in[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct phasor phasor_make(unsigned int sr, float freq)
|
||||||
|
{
|
||||||
|
struct phasor new;
|
||||||
|
new.sr = sr;
|
||||||
|
new.cur = 0.f;
|
||||||
|
new.freq = freq;
|
||||||
|
|
||||||
|
new.cstep = 0;
|
||||||
|
new.clen = new.sr / new.freq;
|
||||||
|
new.cache = malloc(new.clen * sizeof(float));
|
||||||
|
|
||||||
|
for (int i = 0; i < new.clen; i++) {
|
||||||
|
new.cache[i] = (float)i / new.clen;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
float phasor_step(struct phasor *p)
|
||||||
|
{
|
||||||
|
p->cur += p->freq/p->sr;
|
||||||
|
if (p->cur >= 1.f) p->cur = 0.f;
|
||||||
|
return p->cur;
|
||||||
|
|
||||||
|
/*
|
||||||
|
float ret = p->cache[p->cstep++];
|
||||||
|
if (p->cstep ==p->clen) p->cstep = 0;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
float sin_phasor(float p)
|
||||||
|
{
|
||||||
|
return sin(2*PI*p);
|
||||||
|
}
|
||||||
|
|
||||||
|
float square_phasor(float p)
|
||||||
|
{
|
||||||
|
return lround(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
float saw_phasor(float p)
|
||||||
|
{
|
||||||
|
return 2*p-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
float tri_phasor(float p)
|
||||||
|
{
|
||||||
|
return 4*(p * 0.5f ? p : (1-p)) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void osc_fillbuf(struct osc *osc, short *buf, int n)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
short val = SHRT_MAX * osc->f(phasor_step(&osc->p));
|
||||||
|
buf[i*2] = buf[i*2+1] = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gen_whitenoise(void *data, short *buf, int n)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
for (int j = 0; j < 2; j++) {
|
||||||
|
buf[i*2+j] = (rand()>>15) - USHRT_MAX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dsp_delay dsp_delay_make(unsigned int ms_delay)
|
||||||
|
{
|
||||||
|
struct dsp_delay new;
|
||||||
|
new.ms_delay = ms_delay;
|
||||||
|
|
||||||
|
/* Circular buffer size is enough to have the delay */
|
||||||
|
unsigned int datasize = ms_delay * CHANNELS * (SAMPLERATE / 1000);
|
||||||
|
new.buf = circbuf_init(sizeof(short), datasize);
|
||||||
|
new.buf.write = datasize;
|
||||||
|
|
||||||
|
printf("Buffer size is %u.\n", new.buf.len);
|
||||||
|
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dsp_delay_filbuf(struct dsp_delay *delay, short *buf, int n)
|
||||||
|
{
|
||||||
|
static short cache[BUF_FRAMES*2];
|
||||||
|
dsp_run(delay->in, cache, n);
|
||||||
|
|
||||||
|
for (int i = 0; i < n*2; i++) {
|
||||||
|
cbuf_push(&delay->buf, cache[i] / 2);
|
||||||
|
buf[i] = cache[i] + cbuf_shift(&delay->buf);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,18 +1,70 @@
|
||||||
#ifndef DSP_H
|
#ifndef DSP_H
|
||||||
#define DSP_H
|
#define DSP_H
|
||||||
|
|
||||||
|
#define SAMPLERATE 48000
|
||||||
|
#define BUF_FRAMES 4096
|
||||||
|
#define CHANNELS 2
|
||||||
|
#define MUSIZE 2
|
||||||
|
|
||||||
#include "circbuf.h"
|
#include "circbuf.h"
|
||||||
|
|
||||||
void am_mod(short *a, short *b, short *c, int n);
|
|
||||||
|
void dsp_rectify(short *in, short *out, int n);
|
||||||
|
|
||||||
struct dsp_filter {
|
struct dsp_filter {
|
||||||
void (*filter)(short *in, short *out, int samples, void *data);
|
void (*filter)(void *data, short *out, int samples);
|
||||||
void *data;
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dsp_delay {
|
struct dsp_delay {
|
||||||
unsigned int ms_delay;
|
unsigned int ms_delay;
|
||||||
struct circbuf buf;
|
struct circbuf buf;
|
||||||
|
struct dsp_filter in;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dsp_delay dsp_delay_make(unsigned int ms_delay);
|
||||||
|
void dsp_delay_filbuf(struct dsp_delay *delay, short *buf, int n);
|
||||||
|
|
||||||
|
struct dsp_ammod {
|
||||||
|
struct dsp_filter ina;
|
||||||
|
struct dsp_filter inb;
|
||||||
|
short abuf[BUF_FRAMES*2];
|
||||||
|
short bbuf[BUF_FRAMES*2];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dsp_compressor {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dsp_limiter {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dsp_hpf {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dsp_lpf {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct phasor {
|
||||||
|
unsigned int sr;
|
||||||
|
float cur;
|
||||||
|
float freq;
|
||||||
|
unsigned int clen;
|
||||||
|
unsigned int cstep;
|
||||||
|
float *cache;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct phasor phasor_make(unsigned int sr, float freq);
|
||||||
|
|
||||||
|
struct osc {
|
||||||
|
float (*f)(float p);
|
||||||
|
struct phasor p;
|
||||||
|
unsigned int frames;
|
||||||
|
unsigned int frame;
|
||||||
|
short *cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wav;
|
struct wav;
|
||||||
|
@ -22,4 +74,14 @@ 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);
|
struct wav gen_saw(float amp, float freq, int sr, int ch);
|
||||||
|
|
||||||
|
|
||||||
|
float sin_phasor(float p);
|
||||||
|
float square_phasor(float p);
|
||||||
|
float saw_phasor(float p);
|
||||||
|
float tri_phasor(float p);
|
||||||
|
|
||||||
|
void osc_fillbuf(struct osc *osc, short *buf, int n);
|
||||||
|
|
||||||
|
void am_mod(struct dsp_ammod *mod, short *c, int n);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -1,42 +1,41 @@
|
||||||
#include "mix.h"
|
#include "mix.h"
|
||||||
#include "stddef.h"
|
#include "stddef.h"
|
||||||
|
#include "time.h"
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
|
|
||||||
static struct bus bus[256];
|
static struct bus bus[256];
|
||||||
short mastermix[BUF_FRAMES*CHANNELS];
|
short mastermix[BUF_FRAMES*CHANNELS];
|
||||||
|
|
||||||
struct bus *first_free_bus() {
|
struct bus *first_free_bus(struct dsp_filter in) {
|
||||||
for (int i = 0; i < 256; i++) {
|
for (int i = 0; i < 256; i++) {
|
||||||
if (!bus[i].on) return &bus[i];
|
if (!bus[i].on) {
|
||||||
|
bus[i].on = 1;
|
||||||
|
bus[i].in = in;
|
||||||
|
return &bus[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bus_fill_buffers() {
|
void bus_fill_buffers(short *master, int n) {
|
||||||
|
//clock_t sa = clock();
|
||||||
for (int i = 0; i < 256; i++) {
|
for (int i = 0; i < 256; i++) {
|
||||||
if (!bus[i].on) continue;
|
if (bus[i].on != 1) continue;
|
||||||
|
dsp_run(bus[i].in, bus[i].buf, BUF_FRAMES);
|
||||||
short *s = (short*)bus[i].sound->data->data;
|
|
||||||
|
|
||||||
for (int k = 0; k < BUF_FRAMES; k++) {
|
|
||||||
for (int j = 0; j < CHANNELS; j++) {
|
|
||||||
bus[i].buf[k*CHANNELS + j] = s[bus[i].sound->frame++];
|
|
||||||
if (bus[i].sound->frame == bus[i].sound->data->frames) {
|
|
||||||
bus[i].sound->frame = 0;
|
|
||||||
if (!bus[i].sound->loop) bus[i].on = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
//printf("DSP run took %f.\n", (double)(clock() - sa)/CLOCKS_PER_SEC);
|
||||||
|
|
||||||
for (int i = 0; i < BUF_FRAMES*CHANNELS; i++) {
|
//sa = clock();
|
||||||
mastermix[i] = 0;
|
|
||||||
|
memset(master, 0, BUF_FRAMES*CHANNELS*sizeof(short));
|
||||||
|
|
||||||
for (int j = 0; j < 256; j++) {
|
for (int j = 0; j < 256; j++) {
|
||||||
if (!bus[j].on) continue;
|
if (!bus[j].on) continue;
|
||||||
mastermix[i] += bus[j].buf[i];
|
for (int i = 0; i < BUF_FRAMES*CHANNELS; i++) {
|
||||||
|
master[i] += bus[j].buf[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
//printf("Mix took %f.\n", (double)(clock() - sa)/CLOCKS_PER_SEC);
|
||||||
}
|
}
|
|
@ -1,23 +1,21 @@
|
||||||
#ifndef MIX_H
|
#ifndef MIX_H
|
||||||
#define MIX_H
|
#define MIX_H
|
||||||
|
|
||||||
#define BUF_FRAMES 4096
|
#include "dsp.h"
|
||||||
#define CHANNELS 2
|
|
||||||
#define MUSIZE 2
|
|
||||||
|
|
||||||
struct sound;
|
struct sound;
|
||||||
|
|
||||||
|
|
||||||
struct bus {
|
struct bus {
|
||||||
int on;
|
int on;
|
||||||
struct sound *sound;
|
struct dsp_filter in;
|
||||||
short buf[BUF_FRAMES*CHANNELS];
|
short buf[BUF_FRAMES*CHANNELS];
|
||||||
};
|
};
|
||||||
|
|
||||||
extern short mastermix[BUF_FRAMES*CHANNELS];
|
extern short mastermix[BUF_FRAMES*CHANNELS];
|
||||||
|
|
||||||
struct bus *first_free_bus();
|
struct bus *first_free_bus(struct dsp_filter in);
|
||||||
void bus_fill_buffers();
|
void bus_fill_buffers(short *master, int n);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -11,7 +11,6 @@
|
||||||
#include "SDL2/SDL.h"
|
#include "SDL2/SDL.h"
|
||||||
|
|
||||||
#include "mix.h"
|
#include "mix.h"
|
||||||
|
|
||||||
#include "dsp.h"
|
#include "dsp.h"
|
||||||
|
|
||||||
#define TSF_IMPLEMENTATION
|
#define TSF_IMPLEMENTATION
|
||||||
|
@ -75,21 +74,7 @@ static int patestCallback(const void *inputBuffer, void *outputBuffer, unsigned
|
||||||
/* Cast data passed through stream to our structure. */
|
/* Cast data passed through stream to our structure. */
|
||||||
short *out = (short*)outputBuffer;
|
short *out = (short*)outputBuffer;
|
||||||
|
|
||||||
bus_fill_buffers();
|
bus_fill_buffers(outputBuffer, framesPerBuffer);
|
||||||
|
|
||||||
for (int i = 0; i < framesPerBuffer * 2; i++) {
|
|
||||||
out[i] = mastermix[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!vidplaying) return 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < framesPerBuffer; i++) {
|
|
||||||
out[i*2] += cbuf_shift(&vidbuf) * 5;
|
|
||||||
out[i*2+1] += cbuf_shift(&vidbuf) * 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -118,6 +103,13 @@ void normalize_gain(struct wav *w, double lv)
|
||||||
w->gain = log10((float)tarmax/max) * 20;
|
w->gain = log10((float)tarmax/max) * 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct osc sin600;
|
||||||
|
struct osc sin20;
|
||||||
|
struct dsp_ammod dspammod;
|
||||||
|
struct dsp_delay dspdel;
|
||||||
|
struct wav s600wav;
|
||||||
|
struct sound s600wavsound;
|
||||||
|
|
||||||
void sound_init()
|
void sound_init()
|
||||||
{
|
{
|
||||||
vidbuf = circbuf_init(sizeof(short), 262144);
|
vidbuf = circbuf_init(sizeof(short), 262144);
|
||||||
|
@ -139,13 +131,54 @@ void sound_init()
|
||||||
|
|
||||||
//play_sound(&wavsound);
|
//play_sound(&wavsound);
|
||||||
|
|
||||||
sin440 = gen_sine(0.4f, 30, 48000, 2);
|
sin440 = gen_sine(0.4f, 30, SAMPLERATE, 2);
|
||||||
a440.data = &sin440;
|
a440.data = &sin440;
|
||||||
a440.loop = 1;
|
a440.loop = 1;
|
||||||
play_sound(&a440);
|
//play_sound(&a440);
|
||||||
|
|
||||||
printf("Playing wav with %i frames.\n", wavsound.data->frames);
|
printf("Playing wav with %i frames.\n", wavsound.data->frames);
|
||||||
|
|
||||||
|
sin600.f = tri_phasor;
|
||||||
|
sin600.p = phasor_make(SAMPLERATE, 200);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
sin20.f = square_phasor;
|
||||||
|
sin20.p.sr = SAMPLERATE;
|
||||||
|
sin20.p.freq = 4;
|
||||||
|
|
||||||
|
s600wav = gen_sine(0.6f, 600, SAMPLERATE, CHANNELS);
|
||||||
|
|
||||||
|
s600wavsound.loop = -1;
|
||||||
|
s600wavsound.data = &s600wav;
|
||||||
|
|
||||||
|
|
||||||
|
struct dsp_filter s600;
|
||||||
|
s600.data = &s600wavsound;
|
||||||
|
s600.filter = sound_fillbuf;
|
||||||
|
|
||||||
|
struct dsp_filter s20;
|
||||||
|
s20.data = &sin20;
|
||||||
|
s20.filter = osc_fillbuf;
|
||||||
|
|
||||||
|
struct dsp_filter am_filter;
|
||||||
|
|
||||||
|
|
||||||
|
dspammod.ina = s600;
|
||||||
|
dspammod.inb = s20;
|
||||||
|
|
||||||
|
am_filter.filter = am_mod;
|
||||||
|
am_filter.data = &dspammod;
|
||||||
|
|
||||||
|
dspdel = dsp_delay_make(150);
|
||||||
|
dspdel.in = am_filter;
|
||||||
|
struct dsp_filter del_filter;
|
||||||
|
del_filter.filter = dsp_delay_filbuf;
|
||||||
|
del_filter.data = &dspdel;
|
||||||
|
|
||||||
|
//first_free_bus(s600);
|
||||||
|
first_free_bus(del_filter);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (!drmp3_init_file(&mp3, "sounds/circus.mp3", NULL)) {
|
if (!drmp3_init_file(&mp3, "sounds/circus.mp3", NULL)) {
|
||||||
YughError("Could not open mp3.",0);
|
YughError("Could not open mp3.",0);
|
||||||
|
@ -154,7 +187,7 @@ void sound_init()
|
||||||
printf("CIrcus mp3 channels: %ui, samplerate: %ui\n", mp3.channels, mp3.sampleRate);
|
printf("CIrcus mp3 channels: %ui, samplerate: %ui\n", mp3.channels, mp3.sampleRate);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PaError err = Pa_Initialize();
|
PaError err = Pa_Initialize();
|
||||||
check_pa_err(err);
|
check_pa_err(err);
|
||||||
|
|
||||||
int numDevices = Pa_GetDeviceCount();
|
int numDevices = Pa_GetDeviceCount();
|
||||||
|
@ -178,7 +211,7 @@ void sound_init()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//err = Pa_OpenStream(&stream_def, NULL, &outparams, 48000, 4096, paNoFlag, patestCallback, &data);
|
//err = Pa_OpenStream(&stream_def, NULL, &outparams, 48000, 4096, paNoFlag, patestCallback, &data);
|
||||||
err = Pa_OpenDefaultStream(&stream_def, 0, 2, paInt16, 48000, 4096, patestCallback, NULL);
|
err = Pa_OpenDefaultStream(&stream_def, 0, 2, paInt16, SAMPLERATE, BUF_FRAMES, patestCallback, NULL);
|
||||||
check_pa_err(err);
|
check_pa_err(err);
|
||||||
|
|
||||||
err = Pa_StartStream(stream_def);
|
err = Pa_StartStream(stream_def);
|
||||||
|
@ -221,13 +254,6 @@ struct sound *make_music(const char *ogg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void play_sound(struct sound *sound)
|
|
||||||
{
|
|
||||||
struct bus *b = first_free_bus();
|
|
||||||
b->sound = sound;
|
|
||||||
b->on = 1;
|
|
||||||
sound->frame = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void play_music(struct sound *music)
|
void play_music(struct sound *music)
|
||||||
{
|
{
|
||||||
|
@ -282,45 +308,22 @@ void audio_init()
|
||||||
//audioDriver = SDL_GetAudioDeviceName(0,0);
|
//audioDriver = SDL_GetAudioDeviceName(0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void play_raw(int device, void *data, int size)
|
|
||||||
{
|
|
||||||
|
|
||||||
float *d = data;
|
|
||||||
short t;
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
t = (short)(d[i]*32767);
|
|
||||||
cbuf_push(&vidbuf, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
vidplaying = 1;
|
|
||||||
/*
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
short temp = (short)(d[i] * 32767);
|
|
||||||
cbuf_append(&vidbuf, &temp, 1);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void close_audio_device(int device)
|
void close_audio_device(int device)
|
||||||
{
|
{
|
||||||
//SDL_CloseAudioDevice(device);
|
//SDL_CloseAudioDevice(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear_raw(int device)
|
|
||||||
{
|
|
||||||
//SDL_ClearQueuedAudio(device);
|
|
||||||
}
|
|
||||||
|
|
||||||
int open_device(const char *adriver)
|
int open_device(const char *adriver)
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SDL_AudioSpec audio_spec;
|
SDL_AudioSpec audio_spec;
|
||||||
SDL_memset(&audio_spec, 0, sizeof(audio_spec));
|
SDL_memset(&audio_spec, 0, sizeof(audio_spec));
|
||||||
audio_spec.freq = 48000;
|
audio_spec.freq = SAMPLERATE;
|
||||||
audio_spec.format = AUDIO_F32;
|
audio_spec.format = AUDIO_F32;
|
||||||
audio_spec.channels = 2;
|
audio_spec.channels = 2;
|
||||||
audio_spec.samples = 4096;
|
audio_spec.samples = BUF_FRAMES;
|
||||||
int dev = (int) SDL_OpenAudioDevice(adriver, 0, &audio_spec, NULL, 0);
|
int dev = (int) SDL_OpenAudioDevice(adriver, 0, &audio_spec, NULL, 0);
|
||||||
SDL_PauseAudioDevice(dev, 0);
|
SDL_PauseAudioDevice(dev, 0);
|
||||||
|
|
||||||
|
@ -328,3 +331,43 @@ int open_device(const char *adriver)
|
||||||
*/
|
*/
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void play_sound(struct sound *sound)
|
||||||
|
{
|
||||||
|
sound->frame = 0;
|
||||||
|
//struct bus *b = first_free_bus(sound, sound_fillbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void sound_fillbuf(struct sound *s, short *buf, int n)
|
||||||
|
{
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
s->frame++;
|
||||||
|
if (s->frame == s->data->frames) {
|
||||||
|
s->frame = 0;
|
||||||
|
if (s->loop > 0) {
|
||||||
|
s->loop--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct soundstream soundstream_make()
|
||||||
|
{
|
||||||
|
struct soundstream new;
|
||||||
|
new.buf = circbuf_init(sizeof(short), BUF_FRAMES*CHANNELS*2);
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
void soundstream_fillbuf(struct soundstream *s, short *buf, int n)
|
||||||
|
{
|
||||||
|
int max = s->buf.write - s->buf.read;
|
||||||
|
for (int i = 0; i < n*CHANNELS; i++) {
|
||||||
|
buf[i] = (i < max) ? cbuf_shift(&s->buf) : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef SOUND_H
|
#ifndef SOUND_H
|
||||||
#define SOUND_H
|
#define SOUND_H
|
||||||
|
|
||||||
|
#include "circbuf.h"
|
||||||
|
|
||||||
struct Mix_Chunk {
|
struct Mix_Chunk {
|
||||||
int i;
|
int i;
|
||||||
};
|
};
|
||||||
|
@ -15,6 +17,12 @@ enum MUS {
|
||||||
MUS_PAUSE
|
MUS_PAUSE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct soundstream {
|
||||||
|
struct circbuf buf;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct soundstream soundstream_make();
|
||||||
|
|
||||||
struct sound {
|
struct sound {
|
||||||
int loop;
|
int loop;
|
||||||
int frame;
|
int frame;
|
||||||
|
@ -36,6 +44,8 @@ void sound_init();
|
||||||
void audio_open(const char *device);
|
void audio_open(const char *device);
|
||||||
void audio_close();
|
void audio_close();
|
||||||
|
|
||||||
|
void sound_fillbuf(struct sound *s, short *buf, int n);
|
||||||
|
|
||||||
struct sound *make_sound(const char *wav);
|
struct sound *make_sound(const char *wav);
|
||||||
struct sound *make_music(const char *ogg);
|
struct sound *make_music(const char *ogg);
|
||||||
|
|
||||||
|
@ -52,9 +62,9 @@ void music_resume();
|
||||||
void music_pause();
|
void music_pause();
|
||||||
void music_stop();
|
void music_stop();
|
||||||
|
|
||||||
|
void soundstream_fillbuf(struct soundstream *stream, short *buf, int n);
|
||||||
|
|
||||||
void close_audio_device(int device);
|
void close_audio_device(int device);
|
||||||
void clear_raw(int device);
|
|
||||||
void play_raw(int device, void *data, int size);
|
|
||||||
int open_device(const char *adriver);
|
int open_device(const char *adriver);
|
||||||
|
|
||||||
void audio_init();
|
void audio_init();
|
||||||
|
|
Loading…
Reference in a new issue