switched to floats for speed+pos

master
bxwtf 2021-12-20 02:06:02 +00:00
parent 596dfd49e2
commit 349051e4de
4 changed files with 55 additions and 9 deletions

View File

@ -65,7 +65,7 @@ int ampler_main(SDL_Window *w, SDL_Renderer *r, Ampler_state **u_data) {
if e.type == SDL_QUIT do if e.type == SDL_QUIT do
return 1; return 1;
audio_frame(state); state -> played_audio_last_frame = audio_frame(state);
draw_frame(w, r, state); draw_frame(w, r, state);
SDL_Delay(1); SDL_Delay(1);

View File

@ -5,6 +5,8 @@
#define for for( #define for for(
#define do ) #define do )
#define or ||
typedef int8_t s8; typedef int8_t s8;
typedef int16_t s16; typedef int16_t s16;
typedef int32_t s32; typedef int32_t s32;
@ -25,10 +27,21 @@ typedef double f64;
#define CHANNELS (2) #define CHANNELS (2)
#define FRAME_SAMPLES (SAMPLE_RATE / 60) #define FRAME_SAMPLES (SAMPLE_RATE / 60)
typedef struct Sound_src Sound_src;
struct Sound_src {
s32 start; // in samples
s32 len; // in samples
f32 pos; // position in samples
f32 speed; // in samples, per sample, can be negative
enum { FREE = 0, STOPPED, PLAYING, LOOPING } state;
};
typedef struct Ampler_state Ampler_state; typedef struct Ampler_state Ampler_state;
struct Ampler_state { struct Ampler_state {
u32 size; // in bytes, off this struct u32 size; // in bytes, off this struct
SDL_AudioDeviceID playdev; SDL_AudioDeviceID playdev;
s8 tracks[CHANNELS][SAMPLE_RATE * 480]; // 8 minutes s8 tracks[CHANNELS][SAMPLE_RATE * 480]; // 8 minutes
Sound_src sounds[64];
s32 played_audio_last_frame;
}; };

39
audio.c
View File

@ -1,5 +1,19 @@
// audio.c // audio.c
void sound_src_frame(Sound_src *s, s8 *tracks[], s8 *mix[]) {
if s -> state == LOOPING do
for int i = 0; i < FRAME_SAMPLES; i += 1 do {
for int c = 0; c < CHANNELS; c += 1 do
mix[c][i] += tracks[c][(int) (s -> start + s -> pos)];
s -> pos += s -> speed;
while s -> pos < 0.0f do
s -> pos += s -> len;
while s -> pos > s -> len do
s -> pos -= s -> len;
}
}
int audio_frame(Ampler_state *state) { int audio_frame(Ampler_state *state) {
int queued = SDL_GetQueuedAudioSize(state -> playdev); int queued = SDL_GetQueuedAudioSize(state -> playdev);
queued /= sizeof s16; // queued is in bytes queued /= sizeof s16; // queued is in bytes
@ -7,14 +21,20 @@ int audio_frame(Ampler_state *state) {
if queued > FRAME_SAMPLES * CHANNELS * 2 do return 0; if queued > FRAME_SAMPLES * CHANNELS * 2 do return 0;
// else puts("queued audio."); // else puts("queued audio.");
// TODO: ITERATE SOUNDS AND MIX IN SEP CHANNELS static s8 mix_l[FRAME_SAMPLES] = { 0 }, mix_r[FRAME_SAMPLES] = { 0 };
// TODO: THEN, CONVERT TO INTERLEAVED AND OUTPUT SDL_memset(mix_l, 0, sizeof mix_l);
SDL_memset(mix_r, 0, sizeof mix_r);
static s16 frame[SAMPLE_RATE * CHANNELS * 7] = { 0 }; s8 *mix[] = { mix_l, mix_r };
const int vol = 64; s8 *tracks[] = { state -> tracks[0], state -> tracks[1] };
for int i = 0; i < arraylen(frame) / CHANNELS; i += 1 do for int s = 0; s < arraylen(state -> sounds); s += 1 do
sound_src_frame(&(state -> sounds[s]), tracks, mix);
const int vol = 100;
static s16 frame[FRAME_SAMPLES * CHANNELS] = { 0 };
for int i = 0; i < FRAME_SAMPLES; i += 1 do
for int t = 0; t < CHANNELS; t += 1 do for int t = 0; t < CHANNELS; t += 1 do
frame[i * CHANNELS + t] = ((s16) (state -> tracks[t][i])) * vol; frame[i * CHANNELS + t] = ((s16) (mix[t][i])) * vol;
if SDL_QueueAudio(state -> playdev, frame, sizeof frame) do if SDL_QueueAudio(state -> playdev, frame, sizeof frame) do
puts(SDL_GetError()); puts(SDL_GetError());
@ -46,6 +66,13 @@ void load_track(Ampler_state *state) {
for int t = 0; t < chans; t += 1 do for int t = 0; t < chans; t += 1 do
state -> tracks[t][i] = (s8) (buffer[i * chans + t] >> 8); state -> tracks[t][i] = (s8) (buffer[i * chans + t] >> 8);
// TODO: Find actually free sound_src
state -> sounds[0].start = 0;
state -> sounds[0].len = len;
state -> sounds[0].speed = 1.0f;
state -> sounds[0].pos = 0.0f;
state -> sounds[0].state = LOOPING;
SDL_FreeWAV((void *) buffer); SDL_FreeWAV((void *) buffer);
} }

10
draw.c
View File

@ -10,8 +10,14 @@ void draw_frame(SDL_Window *w, SDL_Renderer *r, Ampler_state *state) {
for int x = 0; x < 512; x += 1 do { for int x = 0; x < 512; x += 1 do {
const int y = 128 + 256 * t; const int y = 128 + 256 * t;
const int val = state -> tracks[t][x * space]; const int val = state -> tracks[t][x * space];
SDL_RenderDrawLine(r, x, y + val / 8, x, y + val); SDL_RenderDrawLine(r, y + val / 8, x, y + val, x);
//SDL_RenderDrawPoint(r, x, y + val); //SDL_RenderDrawPoint(r, y + val, x);
}
if state -> played_audio_last_frame do
for int i = 0; i < arraylen(state -> sounds); i += 1 do {
const int x = (state -> sounds[i].start + state -> sounds[i].pos) / space;
SDL_RenderDrawLine(r, 0, x, 512, x);
} }
SDL_RenderPresent(r); SDL_RenderPresent(r);