// --------------------------------------------------------------
// --------------------------------------------------------------
#ifndef _WAVETABLE_H_
#define	_WAVETABLE_H_

#include "synth_types.h"

#define WT_ROM_NUM_WAVES			300
#define WT_ROM_WAVE_SIZE			64
#define WT_ROM_WAVES_SIZE			(300*64)
#define WT_WAVE_SIZE				(2*WT_ROM_WAVE_SIZE)
#define WT_TOTAL_NUM_WAVES			422
#define WT_NUM_WAVETABLES			40
#define WT_WAVETABLE_NUM_ENTRIES	64

// see
// https://jacajack.github.io/music/2019/12/10/PPG-EPROM.html
// https://dbwbp.com/index.php/9-misc/37-synth-eprom-dumps


// --------------------------------------------------------------
// Types
// --------------------------------------------------------------
enum
{	
	WT_WAVEFORM_REGULAR,
	WT_WAVEFORM_INTERPOLATED,
	WT_NUM_WAVEFORMS
};

enum
{
	WT_PARAM2_WAVEFORM,
	WT_PARAM2_WAVETABLE_ID,
	WT_PARAM2_WAVETABLE_ENTRY,
	WT_NUM_PARAMS
};

typedef struct _swt_descr_entry_t
{
	UINT32 pos, wave_id;

} wt_descr_entry_t;

typedef struct _swt_descr_t
{
	UINT32 num_entries;
	wt_descr_entry_t pEntry[WT_WAVETABLE_NUM_ENTRIES];

} wt_descr_t;

typedef struct _swt_common_t
{
	unsigned char wave_rawdata[WT_ROM_WAVES_SIZE];
	synth_float_t waves[WT_TOTAL_NUM_WAVES][WT_WAVE_SIZE];
	synth_float_t **ppWavetables[WT_NUM_WAVETABLES]; //[WT_WAVETABLE_SIZE][WT_WAVE_SIZE];

} wt_common_t;

typedef struct _swt_t
{
	UINT32 id;
	wt_common_t *pCom;
	synth_float_t fm, x, dx, wt_index;
	UINT32 startup, wt_start;
	synth_float_t param[WT_NUM_PARAMS];
	synth_float_t fs;

} wt_t;

// --------------------------------------------------------------
#if defined(__cplusplus)
extern "C" {
#endif

// --------------------------------------------------------------
// Exported functions
// --------------------------------------------------------------
void WT_ModInit(wt_common_t *pCom);
void WT_ModFree(wt_common_t *pCom);
void WT_Init(wt_t *pObj, UINT32 id, wt_common_t *pCom, synth_float_t fs);
void WT_Free(wt_t *pObj);
void WT_SetFS(wt_t *pObj, synth_float_t fs);
void WT_Reset(wt_t *pObj, synth_float_t phase);
void WT_Param2Set(wt_t *pObj, UINT32 type, synth_float_t value);
void WT_Prepare(wt_t *pObj);
void WT_Start(wt_t *pObj);
void WT_ProcessDataV(wt_t *pObj, synth_float_t *pPitch, synth_float_t *pCV_fm, synth_float_t *pCV_pwm, synth_float_t *pOut, UINT32 len);

#if defined(__cplusplus)
}

#endif

// --------------------------------------------------------------

#endif // _WAVETABLE_H_
