/**************************************************************************
 * Copyright (C) 2012-2021  Unisound
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 **************************************************************************
 *
 * Description : lvp_buffer.h
 * Author      : yzs.unisound.com
 * Date        : 2021.03.01
 *
 **************************************************************************/

#ifndef __LVP_BUFFER_H__
#define __LVP_BUFFER_H__

#include <autoconf.h>
#include <stdio.h>
#include <lvp_attr.h>
#include <lvp_context.h>

//=================================================================================================

#ifndef CONFIG_LVP_ENABLE_KEYWORD_RECOGNITION
# define CONFIG_KWS_MODEL_OUTPUT_LENGTH          65
# define CONFIG_KWS_MODEL_INPUT_WIN_LENGTH       17
# define CONFIG_KWS_MODEL_FEATURES_DIM_PER_FRAME 40
# define CONFIG_KWS_MODEL_DECODER_WIN_LENGTH     23
# define CONFIG_KWS_SNPU_BUFFER_SIZE             2772
#endif

#ifdef CONFIG_PCM_SAMPLE_RATE_8K
# define PCM_SAMPLE_RATE     8000
#endif

#ifdef CONFIG_PCM_SAMPLE_RATE_16K
# define PCM_SAMPLE_RATE     16000
#endif

#ifdef CONFIG_PCM_SAMPLE_RATE_48K
# define PCM_SAMPLE_RATE     48000
#endif

#ifndef PCM_SAMPLE_RATE
# error "Unknown Sample Rate"
#endif

#ifdef CONFIG_PCM_FRAME_LENGTH_10MS
# define PCM_FRAME_LENGTH    10
#endif

#ifdef CONFIG_PCM_FRAME_LENGTH_16MS
# define PCM_FRAME_LENGTH    16
#endif

#ifndef PCM_FRAME_LENGTH
# error "Unknown Frame Length"
#endif

// size of a channel and a frame
#define PCM_FRAME_SIZE      (PCM_SAMPLE_RATE * PCM_FRAME_LENGTH / 1000)

// size of a fft per frame
#define FFT_FRAME_LEGTH         (10)
#define FFT_DIM_PER_FRAME       (256)

// size of a logfbank per frame
#define LOGFBANK_FRAME_LEGTH    (10)
#define LOGFBANK_DIM_PER_FRAME  (40)

#define MCU_TO_DEV(addr) ((unsigned int)addr & 0x0fffffff)
#define DEV_TO_MCU(addr) ((unsigned int)addr + 0x20000000)

//=================================================================================================

typedef struct {
    LVP_CONTEXT context;
#ifdef CONFIG_OUT_CHANNEL_NUM
    short out_buffer[PCM_FRAME_SIZE * CONFIG_OUT_CHANNEL_NUM * CONFIG_LVP_PCM_FRAME_NUM_PER_CONTEXT];
#endif
#ifdef CONFIG_KWS_SNPU_BUFFER_SIZE
    unsigned char snpu_buffer[CONFIG_KWS_SNPU_BUFFER_SIZE/16*16 + 16] ALIGNED_ATTR(16);
#endif
} ALIGNED_ATTR(16) LVP_CONTEXT_BUFFER;

//=================================================================================================

int LvpInitBuffer(void);
void *LvpGetMicBufferAddr(void);
int LvpGetMicBufferSize(void);
void *LvpGetLogfbankBufferAddr(void);
int LvpGetLogfbankBufferSize(void);
void *LvpGetFftBuffer(void);
int LvpGetFftBufferSize(void);

void *LvpGetContextHeader(void);
void *LvpGetFeatsBuffer(void);
void *LvpGetLogfankBuffer(LVP_CONTEXT *context, unsigned int index);
int LvpGetContext(unsigned int index, LVP_CONTEXT **context, unsigned int *size);

//=================================================================================================
#endif /* __LVP_BUFFER_H__ */
