flac, mp3, wav playing
This commit is contained in:
parent
6dbfb2afd3
commit
f5f5c16f56
3
Makefile
3
Makefile
|
@ -32,6 +32,9 @@ ifdef ED
|
|||
QFLAGS += -DED
|
||||
endif
|
||||
|
||||
QFLAGS += -DHAVE_CEIL -DHAVE_FLOOR -DHAVE_FMOD -DHAVE_LRINT -DHAVE_LRINTF
|
||||
|
||||
|
||||
PTYPE != uname -m
|
||||
|
||||
BIN = bin/$(CC)/$(INFO)/
|
||||
|
|
|
@ -5,6 +5,6 @@ Yugine plays the open source MPEG-TS muxer, using MPEG1 video and MP2 audio.
|
|||
MPEG-1 video works best at about 1.5 Mbit/s, in SD [720x480] video.
|
||||
For HD [1920x1080] video, use 9 Mbit/s.
|
||||
|
||||
ffmpeg -i "input.video" -vcodec mpeg1video -b:v 1.5M -s 720x480 -acodec mp2 "out.ts"
|
||||
ffmpeg -i "input.video" -vcodec mpeg1video -b:v 9M -s 1920x1080 -acodec mp2 "out.ts"
|
||||
ffmpeg -i "input.video" -c:v mpeg1video -b:v 1.5M -s 720x480 -c:a mp2 -format mpeg "out.mpg"
|
||||
ffmpeg -i "input.video" -vcodec mpeg1video -b:v 9M -s 1920x1080 -acodec mp2 -format mpeg "out.mpg"
|
||||
|
||||
|
|
95
source/engine/cbuf.h
Normal file
95
source/engine/cbuf.h
Normal file
|
@ -0,0 +1,95 @@
|
|||
#ifndef CIRCBUF_H
|
||||
#define CIRCBUF_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct circbuf {
|
||||
int16_t *data;
|
||||
uint32_t read;
|
||||
uint32_t write;
|
||||
unsigned int len;
|
||||
};
|
||||
|
||||
struct circbuf *circbuf_make(size_t size, unsigned 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);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CBUF_IMPLEMENT
|
||||
|
||||
#include "circbuf.h"
|
||||
|
||||
#include "util.h"
|
||||
#include "assert.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
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)));
|
||||
}
|
||||
|
||||
struct circbuf *circbuf_make(size_t size, unsigned int len)
|
||||
{
|
||||
struct circbuf *new = malloc(sizeof(*new));
|
||||
new->len = powof2(len);
|
||||
new->data = calloc(sizeof(short), new->len);
|
||||
new->read = new->write = 0;
|
||||
return new;
|
||||
}
|
||||
|
||||
struct circbuf circbuf_init(size_t size, unsigned int len)
|
||||
{
|
||||
struct circbuf new;
|
||||
new.len = powof2(len);
|
||||
new.data = calloc(sizeof(short), new.len);
|
||||
new.read = new.write = 0;
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
int cbuf_size(struct circbuf *buf) {
|
||||
return buf->write - buf->read;
|
||||
}
|
||||
|
||||
int cbuf_empty(struct circbuf *buf) {
|
||||
return buf->read == buf->write;
|
||||
}
|
||||
|
||||
int cbuf_full(struct circbuf *buf) {
|
||||
return cbuf_size(buf) >= buf->len;
|
||||
}
|
||||
|
||||
uint32_t cbuf_mask(struct circbuf *buf, uint32_t n) {
|
||||
return n & (buf->len-1);
|
||||
}
|
||||
|
||||
void cbuf_push(struct circbuf *buf, short data) {
|
||||
//assert(!cbuf_full(buf));
|
||||
|
||||
buf->data[cbuf_mask(buf,buf->write++)] = data;
|
||||
}
|
||||
|
||||
short cbuf_shift(struct circbuf *buf) {
|
||||
//assert(!cbuf_empty(buf));
|
||||
return buf->data[cbuf_mask(buf, buf->read++)];
|
||||
}
|
||||
|
||||
#endif
|
|
@ -16,14 +16,15 @@
|
|||
#include "font.h"
|
||||
#include "openglrender.h"
|
||||
|
||||
#define CBUF_IMPLEMENT
|
||||
#include "cbuf.h"
|
||||
|
||||
#include "sokol/sokol_gfx.h"
|
||||
|
||||
sg_shader vid_shader;
|
||||
sg_pipeline vid_pipeline;
|
||||
sg_bindings vid_bind;
|
||||
|
||||
|
||||
|
||||
static void render_frame(plm_t *mpeg, plm_frame_t *frame, void *user) {
|
||||
struct datastream *ds = user;
|
||||
uint8_t rgb[frame->height*frame->width*4];
|
||||
|
@ -49,26 +50,25 @@ static void render_audio(plm_t *mpeg, plm_samples_t *samples, void *user) {
|
|||
}
|
||||
|
||||
void ds_openvideo(struct datastream *ds, const char *video, const char *adriver) {
|
||||
// ds_stop(ds);
|
||||
char buf[MAXPATH] = {'\0'};
|
||||
sprintf(buf, "%s%s", "video/", video);
|
||||
ds->plm = plm_create_with_filename(buf);
|
||||
ds->plm = plm_create_with_filename(video);
|
||||
|
||||
if (!ds->plm) {
|
||||
YughLog(0, 0, "Couldn't open %s", video);
|
||||
YughError("Couldn't open %s", video);
|
||||
}
|
||||
|
||||
YughWarn("Opened %s - framerate: %f, samplerate: %d, audio streams: %i, duration: %f",
|
||||
video,
|
||||
plm_get_framerate(ds->plm),
|
||||
plm_get_samplerate(ds->plm),
|
||||
|
||||
plm_get_duration(ds->plm));
|
||||
|
||||
|
||||
ds->img = sg_make_image(&(sg_image_desc){
|
||||
.width = plm_get_width(ds->plm),
|
||||
.height = plm_get_height(ds->plm)
|
||||
});
|
||||
|
||||
YughLog(0, 0, "Opened %s - framerate: %f, samplerate: %d, audio streams: %i, duration: %f",
|
||||
video,
|
||||
plm_get_framerate(ds->plm),
|
||||
plm_get_samplerate(ds->plm),
|
||||
plm_get_num_audio_streams(ds->plm),
|
||||
plm_get_duration(ds->plm));
|
||||
|
||||
ds->astream = soundstream_make();
|
||||
struct dsp_filter astream_filter;
|
||||
|
|
|
@ -641,7 +641,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
|||
|
||||
case 14:
|
||||
str = JS_ToCString(js, argv[1]);
|
||||
mini_sound(str);
|
||||
play_oneshot(make_sound(str));
|
||||
break;
|
||||
|
||||
case 15:
|
||||
|
@ -661,7 +661,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
|||
break;
|
||||
|
||||
case 19:
|
||||
mini_master(js2number(argv[1]));
|
||||
// mini_master(js2number(argv[1]));
|
||||
break;
|
||||
|
||||
case 20:
|
||||
|
@ -918,15 +918,15 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
|||
|
||||
case 87:
|
||||
str = JS_ToCString(js, argv[1]);
|
||||
mini_music_play(str);
|
||||
// mini_music_play(str);
|
||||
break;
|
||||
|
||||
case 88:
|
||||
mini_music_pause();
|
||||
// mini_music_pause();
|
||||
return JS_NULL;
|
||||
|
||||
case 89:
|
||||
mini_music_stop();
|
||||
// mini_music_stop();
|
||||
return JS_NULL;
|
||||
|
||||
case 90:
|
||||
|
|
|
@ -25,15 +25,24 @@
|
|||
#define TML_IMPLEMENTATION
|
||||
#include "tml.h"
|
||||
|
||||
#define DR_WAV_IMPLEMENTATION
|
||||
#include "dr_wav.h"
|
||||
|
||||
#define DR_FLAC_IMPLEMENTATION
|
||||
#include "dr_flac.h"
|
||||
|
||||
#define DR_MP3_IMPLEMENTATION
|
||||
#include "dr_mp3.h"
|
||||
|
||||
static struct {
|
||||
char *key;
|
||||
struct wav *value;
|
||||
} *wavhash = NULL;
|
||||
|
||||
static struct wav change_channels(struct wav w, int ch) {
|
||||
short *data = w.data;
|
||||
soundbyte *data = w.data;
|
||||
int samples = ch * w.frames;
|
||||
short *new = malloc(sizeof(short) * samples);
|
||||
soundbyte *new = malloc(sizeof(soundbyte) * samples);
|
||||
|
||||
if (ch > w.ch) {
|
||||
/* Sets all new channels equal to the first one */
|
||||
|
@ -57,23 +66,24 @@ static struct wav change_samplerate(struct wav w, int rate) {
|
|||
float ratio = (float)rate / w.samplerate;
|
||||
int outframes = w.frames * ratio;
|
||||
SRC_DATA ssrc;
|
||||
float floatdata[w.frames * w.ch];
|
||||
src_short_to_float_array(w.data, floatdata, w.frames * w.ch);
|
||||
float resampled[w.ch * outframes];
|
||||
soundbyte *resampled = calloc(w.ch*outframes,sizeof(soundbyte));
|
||||
|
||||
ssrc.data_in = floatdata;
|
||||
ssrc.data_in = w.data;
|
||||
ssrc.data_out = resampled;
|
||||
ssrc.input_frames = w.frames;
|
||||
ssrc.output_frames = outframes;
|
||||
ssrc.src_ratio = ratio;
|
||||
|
||||
src_simple(&ssrc, SRC_SINC_BEST_QUALITY, w.ch);
|
||||
|
||||
short *newdata = malloc(sizeof(short) * outframes * w.ch);
|
||||
src_float_to_short_array(resampled, newdata, outframes * w.ch);
|
||||
int err = src_simple(&ssrc, SRC_LINEAR, w.ch);
|
||||
if (err) {
|
||||
YughError("Resampling error code %d: %s", err, src_strerror(err));
|
||||
free(resampled);
|
||||
return w;
|
||||
}
|
||||
|
||||
free(w.data);
|
||||
w.data = newdata;
|
||||
w.data = resampled;
|
||||
w.frames = outframes;
|
||||
w.samplerate = rate;
|
||||
|
||||
return w;
|
||||
|
@ -98,7 +108,7 @@ void wav_norm_gain(struct wav *w, double lv) {
|
|||
}
|
||||
}
|
||||
|
||||
void push_sound(float *buffer, int frames, int chan)
|
||||
void push_sound(soundbyte *buffer, int frames, int chan)
|
||||
{
|
||||
bus_fill_buffers(buffer, frames*chan);
|
||||
}
|
||||
|
@ -115,30 +125,52 @@ void sound_init() {
|
|||
|
||||
struct wav *make_sound(const char *wav) {
|
||||
int index = shgeti(wavhash, wav);
|
||||
if (index != -1) return wavhash[index].value;
|
||||
if (index != -1) {
|
||||
YughWarn("%s was cached ...", wav);
|
||||
return wavhash[index].value;
|
||||
}
|
||||
char *ext = strrchr(wav, '.')+1;
|
||||
|
||||
if(!ext) {
|
||||
YughWarn("No extension detected for %s.", wav);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct wav mwav;
|
||||
// mwav.data = drwav_open_file_and_read_pcm_frames_s16(wav, &mwav.ch, &mwav.samplerate, &mwav.frames, NULL);
|
||||
|
||||
if (!strcmp(ext, "wav")) {
|
||||
mwav.data = drwav_open_file_and_read_pcm_frames_f32(wav, &mwav.ch, &mwav.samplerate, &mwav.frames, NULL);
|
||||
} else if (!strcmp(ext, "flac")) {
|
||||
mwav.data = drflac_open_file_and_read_pcm_frames_f32(wav, &mwav.ch, &mwav.samplerate, &mwav.frames, NULL);
|
||||
YughWarn("Flac opened with %d ch, %d samplerate", mwav.ch, mwav.samplerate);
|
||||
} else if (!strcmp(ext, "mp3")) {
|
||||
drmp3_config cnf;
|
||||
mwav.data = drmp3_open_file_and_read_pcm_frames_f32(wav, &cnf, &mwav.frames, NULL);
|
||||
mwav.ch = cnf.channels;
|
||||
mwav.samplerate = cnf.sampleRate;
|
||||
} else {
|
||||
YughWarn("Cannot process file type '%s'.", ext);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mwav.samplerate != SAMPLERATE) {
|
||||
YughInfo("Changing samplerate of %s from %d to %d.", wav, mwav.samplerate, SAMPLERATE);
|
||||
// mwav = change_samplerate(mwav, SAMPLERATE);
|
||||
YughWarn("Changing samplerate of %s from %d to %d.", wav, mwav.samplerate, SAMPLERATE);
|
||||
mwav = change_samplerate(mwav, SAMPLERATE);
|
||||
}
|
||||
|
||||
if (mwav.ch != CHANNELS) {
|
||||
YughInfo("Changing channels of %s from %d to %d.", wav, mwav.ch, CHANNELS);
|
||||
YughWarn("Changing channels of %s from %d to %d.", wav, mwav.ch, CHANNELS);
|
||||
mwav = change_channels(mwav, CHANNELS);
|
||||
}
|
||||
|
||||
mwav.gain = 1.f;
|
||||
|
||||
struct wav *newwav = malloc(sizeof(*newwav));
|
||||
*newwav = mwav;
|
||||
|
||||
if (shlen(wavhash) == 0) sh_new_arena(wavhash);
|
||||
|
||||
shput(wavhash, wav, newwav);
|
||||
|
||||
YughWarn("Channels %d, sr %d", newwav->ch,newwav->samplerate);
|
||||
|
||||
return newwav;
|
||||
}
|
||||
|
||||
|
@ -153,37 +185,10 @@ void free_sound(const char *wav) {
|
|||
|
||||
struct soundstream *soundstream_make() {
|
||||
struct soundstream *new = malloc(sizeof(*new));
|
||||
// new->buf = circbuf_make(sizeof(short), BUF_FRAMES * CHANNELS * 2);
|
||||
new->buf = circbuf_make(sizeof(short), BUF_FRAMES * CHANNELS * 2);
|
||||
return new;
|
||||
}
|
||||
|
||||
void mini_sound(char *path) {
|
||||
|
||||
//ma_engine_play_sound(engine, path, NULL);
|
||||
}
|
||||
|
||||
void mini_music_play(char *path) {
|
||||
/* int result = ma_sound_init_from_file(engine, path, MA_SOUND_FLAG_NO_SPATIALIZATION, NULL, NULL, &music_sound);
|
||||
if (result != MA_SUCCESS) {
|
||||
YughInfo("Could not load music at path: %s", path);
|
||||
}
|
||||
|
||||
YughInfo("Loading %s...", path);
|
||||
ma_sound_start(&music_sound);
|
||||
*/
|
||||
}
|
||||
|
||||
void mini_music_pause() {
|
||||
// ma_sound_stop(&music_sound);
|
||||
}
|
||||
|
||||
void mini_music_stop() {
|
||||
// ma_sound_stop(&music_sound);
|
||||
}
|
||||
|
||||
void mini_master(float v) {
|
||||
// ma_engine_set_volume(engine, v);
|
||||
}
|
||||
|
||||
void kill_oneshot(struct sound *s) {
|
||||
free(s);
|
||||
|
@ -257,16 +262,16 @@ int open_device(const char *adriver) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void sound_fillbuf(struct sound *s, short *buf, int n) {
|
||||
void sound_fillbuf(struct sound *s, soundbyte *buf, int n) {
|
||||
float gainmult = pct2mult(s->data->gain);
|
||||
|
||||
short *in = s->data->data;
|
||||
soundbyte *in = s->data->data;
|
||||
for (int i = 0; i < n; i++) {
|
||||
for (int j = 0; j < CHANNELS; j++)
|
||||
buf[i * CHANNELS + j] = in[s->frame + j] * gainmult;
|
||||
buf[i * CHANNELS + j] = in[s->frame*CHANNELS + j] * gainmult;
|
||||
s->frame++;
|
||||
if (s->frame == s->data->frames) {
|
||||
|
||||
if (s->frame == s->data->frames) {
|
||||
bus_free(s->bus);
|
||||
s->bus = NULL;
|
||||
s->endcb(s);
|
||||
|
@ -275,10 +280,10 @@ void sound_fillbuf(struct sound *s, short *buf, int n) {
|
|||
}
|
||||
}
|
||||
|
||||
void mp3_fillbuf(struct sound *s, short *buf, int n) {
|
||||
void mp3_fillbuf(struct sound *s, soundbyte *buf, int n) {
|
||||
}
|
||||
|
||||
void soundstream_fillbuf(struct soundstream *s, short *buf, int n) {
|
||||
void soundstream_fillbuf(struct soundstream *s, soundbyte *buf, int n) {
|
||||
int max = 1;//s->buf->write - s->buf->read;
|
||||
int lim = (max < n * CHANNELS) ? max : n * CHANNELS;
|
||||
for (int i = 0; i < lim; i++) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef SOUND_H
|
||||
#define SOUND_H
|
||||
|
||||
struct circbuf;
|
||||
#include "cbuf.h"
|
||||
|
||||
typedef float soundbyte;
|
||||
|
||||
|
@ -25,7 +25,7 @@ struct soundstream {
|
|||
|
||||
struct soundstream *soundstream_make();
|
||||
|
||||
/* A playing sound */
|
||||
/* A bookmark into a wav, actually playing the sound */
|
||||
struct sound {
|
||||
int loop; /* How many times to loop */
|
||||
unsigned int frame; /* Pointing to the current frame on the wav */
|
||||
|
@ -45,7 +45,7 @@ struct wav {
|
|||
unsigned long long frames;
|
||||
float gain; /* In dB */
|
||||
|
||||
void *data;
|
||||
soundbyte *data;
|
||||
};
|
||||
|
||||
struct mp3 {
|
||||
|
@ -56,7 +56,7 @@ void sound_init();
|
|||
void audio_open(const char *device);
|
||||
void audio_close();
|
||||
|
||||
void sound_fillbuf(struct sound *s, short *buf, int n);
|
||||
void sound_fillbuf(struct sound *s, soundbyte *buf, int n);
|
||||
|
||||
void mini_sound(char *path);
|
||||
void mini_master(float v);
|
||||
|
@ -82,7 +82,7 @@ struct mp3 make_mp3(const char *mp3);
|
|||
|
||||
const char *get_audio_driver();
|
||||
|
||||
void soundstream_fillbuf(struct soundstream *stream, short *buf, int n);
|
||||
void soundstream_fillbuf(struct soundstream *stream, soundbyte *buf, int n);
|
||||
|
||||
void close_audio_device(int device);
|
||||
int open_device(const char *adriver);
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
struct dsp_filter *filters;
|
||||
|
||||
struct dsp_filter make_dsp(void *data, void (*in)(void *data, short *out, int n)) {
|
||||
struct dsp_filter make_dsp(void *data, void (*in)(void *data, soundbyte *out, int n)) {
|
||||
struct dsp_filter new;
|
||||
new.data = data;
|
||||
new.filter = in;
|
||||
|
@ -24,7 +24,7 @@ struct dsp_filter make_dsp(void *data, void (*in)(void *data, short *out, int n)
|
|||
}
|
||||
}
|
||||
|
||||
void dsp_run(struct dsp_filter filter, short *out, int n) {
|
||||
void dsp_run(struct dsp_filter filter, soundbyte *out, int n) {
|
||||
filter.dirty = 1; // Always on for testing
|
||||
|
||||
if (!filter.dirty)
|
||||
|
@ -45,13 +45,13 @@ void dsp_filter_addin(struct dsp_filter filter, struct dsp_filter *in)
|
|||
filter.in[filter.inputs++] = in;
|
||||
}
|
||||
|
||||
void am_mod(struct dsp_ammod *mod, short *c, int n)
|
||||
void am_mod(struct dsp_ammod *mod, soundbyte *c, int n)
|
||||
{
|
||||
dsp_run(mod->ina, mod->abuf, n);
|
||||
dsp_run(mod->inb, mod->bbuf, n);
|
||||
|
||||
for (int i = 0; i < n*CHANNELS; i++)
|
||||
c[i] = (mod->abuf[i]*mod->bbuf[i])>>15;
|
||||
// for (int i = 0; i < n*CHANNELS; i++)
|
||||
// c[i] = (mod->abuf[i]*mod->bbuf[i])>>15;
|
||||
}
|
||||
|
||||
void fm_mod(float *in1, float *in2, float *out, int n)
|
||||
|
@ -64,7 +64,7 @@ static struct wav make_wav(float freq, int sr, int ch) {
|
|||
new.ch = ch;
|
||||
new.samplerate = sr;
|
||||
new.frames = sr/freq;
|
||||
new.data = calloc(new.frames*new.ch, sizeof(short));
|
||||
new.data = calloc(new.frames*new.ch, sizeof(soundbyte));
|
||||
|
||||
return new;
|
||||
}
|
||||
|
@ -75,12 +75,12 @@ struct wav gen_sine(float amp, float freq, int sr, int ch)
|
|||
|
||||
if (amp > 1) amp = 1;
|
||||
if (amp < 0) amp = 0;
|
||||
short samp = amp*SHRT_MAX;
|
||||
soundbyte samp = amp*SHRT_MAX;
|
||||
|
||||
short *data = (short*)new.data;
|
||||
soundbyte *data = (soundbyte*)new.data;
|
||||
|
||||
for (int i = 0; i < new.frames; i++) {
|
||||
short val = samp * sin(2*PI*((float)i / new.frames));
|
||||
soundbyte val = samp * sin(2*PI*((float)i / new.frames));
|
||||
|
||||
for (int j = 0; j < new.ch; j++) {
|
||||
data[i*new.ch+j] = val;
|
||||
|
@ -101,12 +101,12 @@ struct wav gen_square(float amp, float freq, int sr, int ch)
|
|||
if (amp > 1) amp = 1;
|
||||
if (amp < 0) amp = 0;
|
||||
|
||||
short samp = amp * SHRT_MAX;
|
||||
soundbyte samp = amp * SHRT_MAX;
|
||||
|
||||
short *data = (short*)new.data;
|
||||
soundbyte *data = (soundbyte*)new.data;
|
||||
|
||||
for (int i = 0; i < new.frames; i++) {
|
||||
short val = -2 * floor(2 * i / new.frames) + 1;
|
||||
soundbyte val = -2 * floor(2 * i / new.frames) + 1;
|
||||
for (int j = 0; j < new.ch; j++) {
|
||||
data[i*new.frames+j] = val;
|
||||
}
|
||||
|
@ -122,10 +122,10 @@ 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;
|
||||
soundbyte *data = (soundbyte*)new.data;
|
||||
|
||||
for (int i = 0; i < new.frames; i++) {
|
||||
short val = 2 * abs( (i/new.frames) - floor( (i/new.frames) + 0.5));
|
||||
soundbyte val = 2 * abs( (i/new.frames) - floor( (i/new.frames) + 0.5));
|
||||
for (int j = 0; j < new.ch; j++) {
|
||||
data[i+j] = val;
|
||||
}
|
||||
|
@ -141,12 +141,12 @@ struct wav gen_saw(float amp, float freq, int sr, int ch)
|
|||
if (amp > 1) amp = 1;
|
||||
if (amp < 0) amp = 0;
|
||||
|
||||
short samp = amp*SHRT_MAX;
|
||||
soundbyte samp = amp*SHRT_MAX;
|
||||
|
||||
short *data = (short*)new.data;
|
||||
soundbyte *data = (soundbyte*)new.data;
|
||||
|
||||
for (int i = 0; i < new.frames; i++) {
|
||||
short val = samp * 2 * i/sr - samp;
|
||||
soundbyte val = samp * 2 * i/sr - samp;
|
||||
for (int j = 0; j < new.ch; j++) {
|
||||
data[i+j] = val;
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ struct wav gen_saw(float amp, float freq, int sr, int ch)
|
|||
return new;
|
||||
}
|
||||
|
||||
struct dsp_filter dsp_filter(void *data, void (*filter)(void *data, short *out, int samples))
|
||||
struct dsp_filter dsp_filter(void *data, void (*filter)(void *data, soundbyte *out, int samples))
|
||||
{
|
||||
struct dsp_filter new;
|
||||
new.data = data;
|
||||
|
@ -164,7 +164,7 @@ struct dsp_filter dsp_filter(void *data, void (*filter)(void *data, short *out,
|
|||
return new;
|
||||
}
|
||||
|
||||
void dsp_rectify(short *in, short *out, int n)
|
||||
void dsp_rectify(soundbyte *in, soundbyte *out, int n)
|
||||
{
|
||||
for (int i = 0; i < n; i++)
|
||||
out[i] = abs(in[i]);
|
||||
|
@ -215,15 +215,15 @@ float tri_phasor(float p)
|
|||
return 4*(p * 0.5f ? p : (1-p)) - 1;
|
||||
}
|
||||
|
||||
void osc_fillbuf(struct osc *osc, short *buf, int n)
|
||||
void osc_fillbuf(struct osc *osc, soundbyte *buf, int n)
|
||||
{
|
||||
for (int i = 0; i < n; i++) {
|
||||
short val = SHRT_MAX * osc->f(phasor_step(&osc->p));
|
||||
soundbyte val = SHRT_MAX * osc->f(phasor_step(&osc->p));
|
||||
buf[i*CHANNELS] = buf[i*CHANNELS+1] = val;
|
||||
}
|
||||
}
|
||||
|
||||
void gen_whitenoise(void *data, short *out, int n)
|
||||
void gen_whitenoise(void *data, soundbyte *out, int n)
|
||||
{
|
||||
for (int i = 0; i < n; i++) {
|
||||
for (int j = 0; j < CHANNELS; j++) {
|
||||
|
@ -232,7 +232,7 @@ void gen_whitenoise(void *data, short *out, int n)
|
|||
}
|
||||
}
|
||||
|
||||
void gen_pinknoise(void *data, short *out, int n)
|
||||
void gen_pinknoise(void *data, soundbyte *out, int n)
|
||||
{
|
||||
gen_whitenoise(NULL, out, n);
|
||||
|
||||
|
@ -270,7 +270,7 @@ void gen_pinknoise(void *data, short *out, int n)
|
|||
*/
|
||||
}
|
||||
|
||||
short iir_filter(struct dsp_iir *miir, short val)
|
||||
soundbyte iir_filter(struct dsp_iir *miir, soundbyte val)
|
||||
{
|
||||
struct dsp_iir iir = *miir;
|
||||
|
||||
|
@ -297,12 +297,12 @@ short iir_filter(struct dsp_iir *miir, short val)
|
|||
return a * SHRT_MAX;
|
||||
}
|
||||
|
||||
void dsp_iir_fillbuf(struct dsp_iir *iir, short *out, int n)
|
||||
void dsp_iir_fillbuf(struct dsp_iir *iir, soundbyte *out, int n)
|
||||
{
|
||||
dsp_run(iir->in, out, n);
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
short v = iir_filter(iir, out[i*CHANNELS]);
|
||||
soundbyte v = iir_filter(iir, out[i*CHANNELS]);
|
||||
|
||||
for (int j = 0; j < CHANNELS; j++) {
|
||||
out[i*CHANNELS+j] = v;
|
||||
|
@ -369,7 +369,7 @@ struct dsp_filter hpf_make(int poles, float freq)
|
|||
return hpf;
|
||||
}
|
||||
|
||||
short fir_filter(struct dsp_fir *fir, short val)
|
||||
soundbyte fir_filter(struct dsp_fir *fir, soundbyte val)
|
||||
{
|
||||
float ret = 0.f;
|
||||
fir->dx[fir->head] = (float)val/SHRT_MAX;
|
||||
|
@ -383,12 +383,12 @@ short fir_filter(struct dsp_fir *fir, short val)
|
|||
return ret * SHRT_MAX;
|
||||
}
|
||||
|
||||
void dsp_fir_fillbuf(struct dsp_fir *fir, short *out, int n)
|
||||
void dsp_fir_fillbuf(struct dsp_fir *fir, soundbyte *out, int n)
|
||||
{
|
||||
dsp_run(fir->in, out, n);
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
short val = fir_filter(fir, out[i*CHANNELS]);
|
||||
soundbyte val = fir_filter(fir, out[i*CHANNELS]);
|
||||
|
||||
for (int j = 0; j < CHANNELS; j++)
|
||||
out[i*CHANNELS + j] = val*5;
|
||||
|
@ -426,7 +426,7 @@ struct dsp_delay dsp_delay_make(unsigned int 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 = circbuf_init(sizeof(soundbyte), datasize);
|
||||
// new.buf.write = datasize;
|
||||
|
||||
// YughInfo("Buffer size is %u.", new.buf.len);
|
||||
|
@ -434,9 +434,9 @@ struct dsp_delay dsp_delay_make(unsigned int ms_delay)
|
|||
return new;
|
||||
}
|
||||
|
||||
void dsp_delay_filbuf(struct dsp_delay *delay, short *buf, int n)
|
||||
void dsp_delay_filbuf(struct dsp_delay *delay, soundbyte *buf, int n)
|
||||
{
|
||||
static short cache[BUF_FRAMES*2];
|
||||
static soundbyte cache[BUF_FRAMES*2];
|
||||
dsp_run(delay->in, cache, n);
|
||||
|
||||
for (int i = 0; i < n*CHANNELS; i++) {
|
||||
|
@ -452,9 +452,9 @@ double tau2pole(double tau)
|
|||
return exp(-1/(tau*SAMPLERATE));
|
||||
}
|
||||
|
||||
void dsp_adsr_fillbuf(struct dsp_adsr *adsr, short *out, int n)
|
||||
void dsp_adsr_fillbuf(struct dsp_adsr *adsr, soundbyte *out, int n)
|
||||
{
|
||||
short val;
|
||||
soundbyte val;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (adsr->time > adsr->rls) {
|
||||
|
@ -524,7 +524,7 @@ struct dsp_filter make_reverb()
|
|||
|
||||
}
|
||||
|
||||
void dsp_reverb_fillbuf(struct dsp_reverb *r, short *out, int n)
|
||||
void dsp_reverb_fillbuf(struct dsp_reverb *r, soundbyte *out, int n)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -551,7 +551,7 @@ struct dsp_filter dsp_make_compressor()
|
|||
return filter;
|
||||
}
|
||||
|
||||
void dsp_compressor_fillbuf(struct dsp_compressor *comp, short *out, int n)
|
||||
void dsp_compressor_fillbuf(struct dsp_compressor *comp, soundbyte *out, int n)
|
||||
{
|
||||
float val;
|
||||
float db;
|
||||
|
@ -578,7 +578,7 @@ void dsp_compressor_fillbuf(struct dsp_compressor *comp, short *out, int n)
|
|||
}
|
||||
}
|
||||
|
||||
void dsp_pan(float *deg, short *out, int n)
|
||||
void dsp_pan(float *deg, soundbyte *out, int n)
|
||||
{
|
||||
if (*deg < -100) *deg = -100.f;
|
||||
else if (*deg > 100) *deg = 100.f;
|
||||
|
@ -599,8 +599,8 @@ void dsp_pan(float *deg, short *out, int n)
|
|||
|
||||
for (int i = 0; i < n; i++) {
|
||||
double pct = *deg / 100.f;
|
||||
short L = out[i*CHANNELS];
|
||||
short R = out[i*CHANNELS +1];
|
||||
soundbyte L = out[i*CHANNELS];
|
||||
soundbyte R = out[i*CHANNELS +1];
|
||||
|
||||
if (*deg > 0) {
|
||||
out[i*CHANNELS] = short_gain(L, db1);
|
||||
|
@ -614,20 +614,22 @@ void dsp_pan(float *deg, short *out, int n)
|
|||
}
|
||||
}
|
||||
|
||||
void dsp_mono(void *p, short *out, int n)
|
||||
void dsp_mono(void *p, soundbyte *out, int n)
|
||||
{
|
||||
for (int i = 0; i < n; i++) {
|
||||
short val = (out[i*CHANNELS] + out[i*CHANNELS+1]) / 2;
|
||||
soundbyte val = (out[i*CHANNELS] + out[i*CHANNELS+1]) / 2;
|
||||
|
||||
for (int j = 0; j < CHANNELS; j++)
|
||||
out[i*CHANNELS+j] = val;
|
||||
}
|
||||
}
|
||||
|
||||
void dsp_bitcrush(void *p, short *out, int n)
|
||||
void dsp_bitcrush(void *p, soundbyte *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 */
|
||||
}
|
||||
|
||||
// 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 */
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
|
@ -5,25 +5,27 @@
|
|||
#define BUF_FRAMES 128 /* At 48k, 128 needed for 240fps consistency */
|
||||
#define CHANNELS 2
|
||||
|
||||
#include "sound.h"
|
||||
|
||||
//#include "circbuf.h"
|
||||
|
||||
struct dsp_iir;
|
||||
|
||||
|
||||
void dsp_rectify(short *in, short *out, int n);
|
||||
void dsp_rectify(soundbyte *in, soundbyte *out, int n);
|
||||
|
||||
struct dsp_filter {
|
||||
void (*filter)(void *data, short *out, int samples);
|
||||
void (*filter)(void *data, soundbyte *out, int samples);
|
||||
void *data;
|
||||
|
||||
int inputs;
|
||||
struct dsp_filter *in[6];
|
||||
|
||||
short cache[CHANNELS*BUF_FRAMES];
|
||||
soundbyte cache[CHANNELS*BUF_FRAMES];
|
||||
int dirty;
|
||||
};
|
||||
|
||||
struct dsp_filter dsp_filter(void *data, void (*filter)(void *data, short *out, int samples));
|
||||
struct dsp_filter dsp_filter(void *data, void (*filter)(void *data, soundbyte *out, int samples));
|
||||
|
||||
struct dsp_fir {
|
||||
float freq;
|
||||
|
@ -39,7 +41,7 @@ void dsp_filter_addin(struct dsp_filter filter, struct dsp_filter *in);
|
|||
|
||||
struct dsp_filter lp_fir_make(float freq);
|
||||
|
||||
void dsp_iir_fillbuf(struct dsp_iir *iir, short *out, int n);
|
||||
void dsp_iir_fillbuf(struct dsp_iir *iir, soundbyte *out, int n);
|
||||
struct dsp_filter hpf_make(int poles, float freq);
|
||||
struct dsp_filter lpf_make(int poles, float freq);
|
||||
struct dsp_filter bpf_make(int poles, float freq1, float freq2);
|
||||
|
@ -60,7 +62,7 @@ struct dsp_adsr {
|
|||
float out;
|
||||
};
|
||||
|
||||
void dsp_adsr_fillbuf(struct dsp_adsr *adsr, short *out, int n);
|
||||
void dsp_adsr_fillbuf(struct dsp_adsr *adsr, soundbyte *out, int n);
|
||||
struct dsp_filter make_adsr(unsigned int atk, unsigned int dec, unsigned int sus, unsigned int rls);
|
||||
|
||||
struct dsp_delay {
|
||||
|
@ -70,13 +72,13 @@ struct dsp_delay {
|
|||
};
|
||||
|
||||
struct dsp_delay dsp_delay_make(unsigned int ms_delay);
|
||||
void dsp_delay_filbuf(struct dsp_delay *delay, short *buf, int n);
|
||||
void dsp_delay_filbuf(struct dsp_delay *delay, soundbyte *buf, int n);
|
||||
|
||||
struct dsp_ammod {
|
||||
struct dsp_filter ina;
|
||||
struct dsp_filter inb;
|
||||
short abuf[BUF_FRAMES*CHANNELS];
|
||||
short bbuf[BUF_FRAMES*CHANNELS];
|
||||
soundbyte abuf[BUF_FRAMES*CHANNELS];
|
||||
soundbyte bbuf[BUF_FRAMES*CHANNELS];
|
||||
};
|
||||
|
||||
struct dsp_compressor {
|
||||
|
@ -90,14 +92,14 @@ struct dsp_compressor {
|
|||
};
|
||||
|
||||
struct dsp_filter dsp_make_compressor();
|
||||
void dsp_compressor_fillbuf(struct dsp_compressor *comp, short *out, int n);
|
||||
void dsp_compressor_fillbuf(struct dsp_compressor *comp, soundbyte *out, int n);
|
||||
|
||||
struct dsp_limiter {
|
||||
|
||||
};
|
||||
|
||||
struct dsp_filter dsp_make_limiter();
|
||||
void dsp_limiter_fillbuf(struct dsp_limiter *lim, short *out, int n);
|
||||
void dsp_limiter_fillbuf(struct dsp_limiter *lim, soundbyte *out, int n);
|
||||
|
||||
|
||||
struct phasor {
|
||||
|
@ -116,7 +118,7 @@ struct osc {
|
|||
struct phasor p;
|
||||
unsigned int frames;
|
||||
unsigned int frame;
|
||||
short *cache;
|
||||
soundbyte *cache;
|
||||
};
|
||||
|
||||
struct wav;
|
||||
|
@ -126,8 +128,8 @@ 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);
|
||||
|
||||
void gen_whitenoise(void *data, short *out, int n);
|
||||
void gen_pinknoise(void *data, short *out, int n);
|
||||
void gen_whitenoise(void *data, soundbyte *out, int n);
|
||||
void gen_pinknoise(void *data, soundbyte *out, int n);
|
||||
|
||||
|
||||
float sin_phasor(float p);
|
||||
|
@ -135,23 +137,23 @@ 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 osc_fillbuf(struct osc *osc, soundbyte *buf, int n);
|
||||
|
||||
void am_mod(struct dsp_ammod *mod, short *c, int n);
|
||||
void am_mod(struct dsp_ammod *mod, soundbyte *c, int n);
|
||||
|
||||
struct dsp_reverb {
|
||||
unsigned int time; /* Time in miliseconds for the sound to decay out */
|
||||
};
|
||||
|
||||
struct dsp_filter make_reverb();
|
||||
void dsp_reverb_fillbuf(struct dsp_reverb *r, short *out, int n);
|
||||
void dsp_reverb_fillbuf(struct dsp_reverb *r, soundbyte *out, int n);
|
||||
|
||||
void dsp_pan(float *deg, short *out, int n);
|
||||
void dsp_pan(float *deg, soundbyte *out, int n);
|
||||
|
||||
void dsp_mono(void *p, short *out, int n);
|
||||
void dsp_mono(void *p, soundbyte *out, int n);
|
||||
|
||||
void dsp_bitcrush(void *p, short *out, int n);
|
||||
void dsp_bitcrush(void *p, soundbyte *out, int n);
|
||||
|
||||
void dsp_run(struct dsp_filter filter, short *out, int n);
|
||||
void dsp_run(struct dsp_filter filter, soundbyte *out, int n);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,13 +17,13 @@
|
|||
#define CPU_IS_LITTLE_ENDIAN 1
|
||||
|
||||
/* Enable sinc best converter. */
|
||||
#define ENABLE_SINC_BEST_CONVERTER yes
|
||||
#define ENABLE_SINC_BEST_CONVERTER 1
|
||||
|
||||
/* Enable sinc fast converter. */
|
||||
#define ENABLE_SINC_FAST_CONVERTER yes
|
||||
#define ENABLE_SINC_FAST_CONVERTER 1
|
||||
|
||||
/* Enable sinc balanced converter. */
|
||||
#define ENABLE_SINC_MEDIUM_CONVERTER yes
|
||||
#define ENABLE_SINC_MEDIUM_CONVERTER 1
|
||||
|
||||
/* Define to 1 if you have the `alarm' function. */
|
||||
#define HAVE_ALARM 1
|
||||
|
|
|
@ -6,9 +6,7 @@
|
|||
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -6,9 +6,7 @@
|
|||
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
|
|
@ -6,9 +6,7 @@
|
|||
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
|
|
@ -6,9 +6,7 @@
|
|||
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
#include "openglrender.h"
|
||||
#include "window.h"
|
||||
|
||||
#define MINIAUDIO_IMPLEMENTATION
|
||||
#include "miniaudio.h"
|
||||
#include "datastream.h"
|
||||
|
||||
#include "timer.h"
|
||||
|
||||
|
@ -225,6 +224,9 @@ int main(int argc, char **args) {
|
|||
input_init();
|
||||
openglInit();
|
||||
|
||||
MakeDatastream();
|
||||
struct datastream v;
|
||||
ds_openvideo(&v, "bjork.mpg", NULL);
|
||||
|
||||
while (!want_quit()) {
|
||||
double elapsed = glfwGetTime() - lastTick;
|
||||
|
|
|
@ -725,7 +725,7 @@ var Music = {
|
|||
};
|
||||
|
||||
var Sound = {
|
||||
sounds: [],
|
||||
sounds: [], /* array of loaded sound files */
|
||||
play(file) {
|
||||
// var s = Object.create(Sound);
|
||||
// s.path = file;
|
||||
|
|
Loading…
Reference in a new issue