#include "ssrc_us_share_buf.h"

/* 改动原因：该 buffer 只在 tile[1] 内被 us_rec_core/us_rec_output_core 使用。
 * us_stereo.S 通过 tail 地址写入；输出任务通过 head 读取并用普通 chan 发回 tile[0]。 */
static int32_t ssrc_us_rb[SSRC_US_RB_WORDS];
static int32_t ssrc_us_head;
/* 改动原因：us_stereo.S 通过指针写 ssrc_us_tail；编译器无法感知，须加 volatile
 * 否则 ssrc_us_share_pop_word_blocking 的 while 循环永远读缓存旧值，导致死锁 */
volatile int32_t ssrc_us_tail;

void ssrc_us_share_reset(void)
{
    ssrc_us_head = 0;
    ssrc_us_tail = 0;
}

uint32_t ssrc_us_share_get_buffer_addr(void)
{
    return (uint32_t)ssrc_us_rb;
}

uint32_t ssrc_us_share_get_tail_addr(void)
{
    return (uint32_t)&ssrc_us_tail;
}

int32_t ssrc_us_share_pop_word_blocking(void)
{
    int32_t sample;

    while (ssrc_us_head == ssrc_us_tail) {
        /* 改动原因：输出任务等待 us_stereo.S 生产数据；只阻塞发送任务，不阻塞采样率转换任务。 */
        asm volatile("nop");
    }

    sample = ssrc_us_rb[ssrc_us_head];
    ssrc_us_head++;
    if (ssrc_us_head >= (SSRC_US_RB_WORDS - 32)) {
        /* 改动原因：us_stereo.S 使用的 ring size 为 NUM_USB_CHAN_OUT*32*5，不包含尾部padding。 */
        ssrc_us_head = 0;
    }
    return sample;
}
