// audio.c void sound_src_frame(Sound_src *s, 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] += s -> tracks[c][(int) 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 queued = SDL_GetQueuedAudioSize(state -> playdev); queued /= sizeof s16; // queued is in bytes if queued > FRAME_SAMPLES * CHANNELS * 2 do return 0; // else puts("queued audio."); // TODO: We should use CHANNELS here 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); s8 *mix[] = { mix_l, mix_r }; for int s = 0; s < arraylen(state -> sounds); s += 1 do sound_src_frame(&(state -> sounds[s]), 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 frame[i * CHANNELS + t] = ((s16) (mix[t][i])) * vol; if SDL_QueueAudio(state -> playdev, frame, sizeof frame) do puts(SDL_GetError()); return 1; // audio was qued } 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; } const int chans = spec.channels; const int length = (bytes / sizeof s16) / chans; // 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 for int i = 0; i < CHANNELS; i += 1 do snd -> tracks[i] = malloc(snd -> len); for int i = 0; i < CHANNELS; i += 1 do if !snd -> tracks[i] do puts("fffuuuck"); 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); SDL_FreeWAV((void *) buffer); printf("loaded sample.wav %f seconds.\n", ((f32) length) / ((f32) SAMPLE_RATE)); } 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)); } */ }