diff --git a/ampler.c b/ampler.c index e5fc61e..4b157f1 100644 --- a/ampler.c +++ b/ampler.c @@ -67,9 +67,10 @@ int ampler_main(SDL_Window *w, SDL_Renderer *r, Ampler_state **u_data) { state -> played_audio_last_frame = audio_frame(state); draw_frame(w, r, state); - // CLEAR UDP MESSAGES - foreach_ptr(Udp_msg, msg, state -> messages) - msg -> state = MSG_FREE; + // CLEAR UDP MESSAGES, but only after we've played them + if state -> played_audio_last_frame do + foreach_ptr(Udp_msg, msg, state -> messages) + msg -> state = MSG_FREE; SDL_Delay(1); diff --git a/ampler.h b/ampler.h index 35c1dda..f69be8b 100644 --- a/ampler.h +++ b/ampler.h @@ -40,9 +40,11 @@ for ; N##_i < arraylen(ARRAY); N##_i += 1, N = &((ARRAY)[N##_i]) do typedef struct Sound_src Sound_src; struct Sound_src { s8 *tracks[CHANNELS]; - s32 len; // in samples + s32 track_len; // size of track buffers, in samples f32 pos; // position in samples f32 speed; // in samples, per sample, can be negative + s32 start; // play start in samples + s32 end; // play end in samples enum { SND_FREE = 0, SND_STOPPED, SND_PLAYING, SND_LOOPING, } state; }; diff --git a/audio.c b/audio.c index 893eb0b..686ca85 100644 --- a/audio.c +++ b/audio.c @@ -3,17 +3,48 @@ // TODO: add something to make sure, we KNOW if we've dropped audio // eg. buffer has gone unfilled for a frame or more +void trigger_sounds(Ampler_state *state) { + // TODO: Check sound names + // TODO: func to decode orca numbers + + // TODO: NOTE SPEED + foreach_ptr(Udp_msg, m, state -> messages) + if m -> state == MSG_TRIGGER do + foreach_ptr(Sound_src, s, state -> sounds) + if s -> state == SND_STOPPED do { + s -> state = SND_PLAYING; + s -> speed = 7.01f; + s -> pos = 0.0f; + break; + } + else if s -> state == SND_PLAYING do { + s -> speed = -1.51f; + break; + } +} + void sound_src_frame(Sound_src *s, s8 *mix[]) { - if s -> state == SND_LOOPING do + if s -> state == SND_LOOPING or s -> state == SND_PLAYING 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; + + if s -> state == SND_LOOPING do { + while s -> pos < s -> start do + s -> pos += (s->end - s->start); + while s -> pos >= s -> end do + s -> pos -= (s->end - s->start); + } + + // TODO: THIS WILL BREAK REVERSE SOUNDS + // FIXME: CHECK SIGN OF SPEED + if s -> state == SND_PLAYING do + if s->pos < s->start or s->pos >= s->end do { + s -> pos = s->start; + s -> state = SND_STOPPED; + } } } @@ -24,6 +55,8 @@ int audio_frame(Ampler_state *state) { if queued > FRAME_SAMPLES * CHANNELS * 2 do return 0; // else puts("queued audio."); + trigger_sounds(state); + // 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); @@ -71,20 +104,25 @@ void load_track(Ampler_state *state) { const int chans = spec.channels; const int length = (bytes / sizeof s16) / chans; - snd -> len = length; + snd -> track_len = length; snd -> speed = 1.0f; snd -> pos = 0.0f; - // snd -> state = SND_LOOPING; + snd -> start = 0; + snd -> end = snd->track_len; snd -> state = SND_STOPPED; + snd -> state = SND_LOOPING; + snd -> end /= 2; + snd -> start = snd -> end / 2; + for int i = 0; i < CHANNELS; i += 1 do - snd -> tracks[i] = malloc(snd -> len); + snd -> tracks[i] = malloc(snd -> track_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 i = 0; i < snd -> track_len; i += 1 do for int t = 0; t < chans; t += 1 do snd -> tracks[t][i] = (s8) (buffer[i * chans + t] >> 8); diff --git a/draw.c b/draw.c index f89bf8f..6a2035d 100644 --- a/draw.c +++ b/draw.c @@ -5,6 +5,7 @@ void draw_frame(SDL_Window *w, SDL_Renderer *r, Ampler_state *state) { //SDL_SetRenderDrawColor(r, 10, 10, 10, 100); SDL_RenderClear(r); + // TODO: DRAW WITH X SCALE FACTOR // TODO: DRAW SMOLER SDL_SetRenderDrawColor(r, 0xFF, 0x00, 0x4D, 255); const space = (44100 * 8) / 512; @@ -20,10 +21,13 @@ void draw_frame(SDL_Window *w, SDL_Renderer *r, Ampler_state *state) { } if state -> played_audio_last_frame do - foreach_ptr(Sound_src, snd, state -> sounds) { - const int x = snd -> pos / space; - SDL_RenderDrawLine(r, x, 0, x, 512); - } + foreach_ptr(Sound_src, snd, state -> sounds) + if snd->state == SND_PLAYING or snd->state == SND_LOOPING do { + const int x = snd -> pos / space; + SDL_RenderDrawLine(r, x, 0, x, 512); + SDL_RenderDrawLine(r, snd->start / space, 0, snd->start / space, 512); + SDL_RenderDrawLine(r, snd->end / space, 0, snd->end / space, 512); + } SDL_RenderPresent(r); }