#include "delay.h"
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

void delay_init(
    struct delay* delay)
{
    delay->mix = 0.8;
    delay->feedback = 0.8;
    delay->duration = 0;
    delay->buf_idx = 0;
    delay->buf_capacity = 0;
    delay->buf = NULL;
}

void delay_set_time(
    struct delay* delay,
    uint64_t new_duration)
{
    printf("set delay duration to %lu samples\n", new_duration);
    if (new_duration > delay->buf_capacity) {
        delay->buf_capacity = new_duration;
        delay->buf = realloc(delay->buf, sizeof(float) * new_duration);
    }

    for (int i = delay->duration; i < new_duration; ++i) {
        delay->buf[i] = delay->buf[i - delay->duration];
    }

    delay->duration = new_duration;
    if (new_duration > 0) {
        delay->buf_idx %= new_duration;
    }
}

void delay_process(
    struct delay* delay,
    size_t frame_size,
    float const* in,
    float* out)
{
    for (size_t i = 0; i < frame_size; ++i) {
        if (delay->duration > 0) {
            out[i] = in[i]
                + delay->mix * delay->buf[delay->buf_idx];

            delay->buf[delay->buf_idx] *= delay->feedback;
            delay->buf[delay->buf_idx] += (1.0 - delay->feedback) * in[i];
            delay->buf_idx = (delay->buf_idx + 1) % delay->duration;
        } else {
            out[i] = 0.5 * in[i];
        }
    }
}