2021-12-18 20:58:21 +00:00
|
|
|
// audio.c
|
|
|
|
|
2021-12-21 01:37:24 +00:00
|
|
|
void sound_src_frame(Sound_src *s, s8 *mix[]) {
|
2021-12-20 02:06:02 +00:00
|
|
|
if s -> state == LOOPING do
|
|
|
|
for int i = 0; i < FRAME_SAMPLES; i += 1 do {
|
|
|
|
for int c = 0; c < CHANNELS; c += 1 do
|
2021-12-21 01:37:24 +00:00
|
|
|
mix[c][i] += s -> tracks[c][(int) s -> pos];
|
2021-12-20 02:06:02 +00:00
|
|
|
|
|
|
|
s -> pos += s -> speed;
|
|
|
|
while s -> pos < 0.0f do
|
|
|
|
s -> pos += s -> len;
|
2021-12-21 01:37:24 +00:00
|
|
|
while s -> pos >= s -> len do
|
2021-12-20 02:06:02 +00:00
|
|
|
s -> pos -= s -> len;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-18 20:58:21 +00:00
|
|
|
int audio_frame(Ampler_state *state) {
|
|
|
|
int queued = SDL_GetQueuedAudioSize(state -> playdev);
|
|
|
|
queued /= sizeof s16; // queued is in bytes
|
|
|
|
|
2021-12-19 22:44:48 +00:00
|
|
|
if queued > FRAME_SAMPLES * CHANNELS * 2 do return 0;
|
2021-12-18 20:58:21 +00:00
|
|
|
// else puts("queued audio.");
|
|
|
|
|
2021-12-21 01:37:24 +00:00
|
|
|
// TODO: We should use CHANNELS here
|
2021-12-20 02:06:02 +00:00
|
|
|
static s8 mix_l[FRAME_SAMPLES] = { 0 }, mix_r[FRAME_SAMPLES] = { 0 };
|
|
|
|
SDL_memset(mix_l, 0, sizeof mix_l);
|
|
|
|
SDL_memset(mix_r, 0, sizeof mix_r);
|
2021-12-20 00:03:14 +00:00
|
|
|
|
2021-12-20 02:06:02 +00:00
|
|
|
s8 *mix[] = { mix_l, mix_r };
|
|
|
|
for int s = 0; s < arraylen(state -> sounds); s += 1 do
|
2021-12-21 01:37:24 +00:00
|
|
|
sound_src_frame(&(state -> sounds[s]), mix);
|
2021-12-20 02:06:02 +00:00
|
|
|
|
|
|
|
const int vol = 100;
|
|
|
|
static s16 frame[FRAME_SAMPLES * CHANNELS] = { 0 };
|
|
|
|
for int i = 0; i < FRAME_SAMPLES; i += 1 do
|
2021-12-20 00:03:14 +00:00
|
|
|
for int t = 0; t < CHANNELS; t += 1 do
|
2021-12-20 02:06:02 +00:00
|
|
|
frame[i * CHANNELS + t] = ((s16) (mix[t][i])) * vol;
|
2021-12-20 00:03:14 +00:00
|
|
|
|
2021-12-19 22:44:48 +00:00
|
|
|
if SDL_QueueAudio(state -> playdev, frame, sizeof frame) do
|
2021-12-18 20:58:21 +00:00
|
|
|
puts(SDL_GetError());
|
|
|
|
|
|
|
|
return 1; // audio was qued
|
|
|
|
}
|
|
|
|
|
2021-12-19 22:44:48 +00:00
|
|
|
void load_track(Ampler_state *state) {
|
|
|
|
SDL_AudioSpec spec;
|
|
|
|
s16 *buffer = NULL;
|
|
|
|
u32 bytes = 0;
|
|
|
|
|
|
|
|
SDL_LoadWAV("sample.wav", &spec, &buffer, &bytes);
|
|
|
|
|
|
|
|
if spec.format != AUDIO_S16 do {
|
|
|
|
puts("error: sample.wav is not s16");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-20 00:03:14 +00:00
|
|
|
const int chans = spec.channels;
|
2021-12-21 01:37:24 +00:00
|
|
|
const int length = (bytes / sizeof s16) / chans;
|
2021-12-20 00:03:14 +00:00
|
|
|
|
2021-12-21 01:37:24 +00:00
|
|
|
// TODO: Actually find free sound_src
|
|
|
|
Sound_src *snd = &(state -> sounds[0]);
|
|
|
|
snd -> len = length;
|
|
|
|
snd -> speed = 1.0f;
|
|
|
|
snd -> pos = 0.0f;
|
|
|
|
snd -> state = LOOPING; // TOOD: Should be STOPPED
|
2021-12-19 22:44:48 +00:00
|
|
|
|
2021-12-21 01:37:24 +00:00
|
|
|
for int i = 0; i < CHANNELS; i += 1 do
|
|
|
|
snd -> tracks[i] = malloc(snd -> len);
|
2021-12-19 22:44:48 +00:00
|
|
|
|
2021-12-21 01:37:24 +00:00
|
|
|
for int i = 0; i < CHANNELS; i += 1 do
|
|
|
|
if !snd -> tracks[i] do
|
|
|
|
puts("fffuuuck");
|
2021-12-19 22:44:48 +00:00
|
|
|
|
2021-12-21 01:37:24 +00:00
|
|
|
for int i = 0; i < snd -> len; i += 1 do
|
|
|
|
for int t = 0; t < chans; t += 1 do
|
|
|
|
snd -> tracks[t][i] = (s8) (buffer[i * chans + t] >> 8);
|
2021-12-20 02:06:02 +00:00
|
|
|
|
2021-12-19 22:44:48 +00:00
|
|
|
SDL_FreeWAV((void *) buffer);
|
2021-12-21 01:37:24 +00:00
|
|
|
|
|
|
|
printf("loaded sample.wav %f seconds.\n",
|
|
|
|
((f32) length) / ((f32) SAMPLE_RATE));
|
2021-12-19 22:44:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void load_track_f32() { // idk if we're ever gonna be loading floats
|
|
|
|
/*
|
|
|
|
f32 max = 0.0f;
|
|
|
|
for int i = 0; i < len; i++ do
|
|
|
|
if buffer[i] > max do
|
|
|
|
max = buffer[i];
|
|
|
|
else if buffer[i] < -max do
|
|
|
|
max = -buffer[i];
|
|
|
|
printf("%f max\n", max);
|
|
|
|
for int i = 0; i < len; i += 2 do {
|
|
|
|
buffer[i] /= max;
|
|
|
|
buffer[i + 1] /= max;
|
|
|
|
state -> track_l[i] = ((s8)(buffer[i] * 127.0f));
|
|
|
|
state -> track_r[i] = ((s8)(buffer[i + 1] * 127.0f));
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|