- improved limiter - VCO: Waveform "Impulse" hase now amplitude of 100 git-svn-id: http://moon:8086/svn/software/trunk/projects/JaySynth@715 b431acfa-c32f-4a4a-93f1-934dc6c82436
210 lines
4.9 KiB
C
210 lines
4.9 KiB
C
// --------------------------------------------------------------
|
|
// --------------------------------------------------------------
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
#include "synth_defs.h"
|
|
#include "blit.h"
|
|
#include "vco.h"
|
|
#include "wavetable.h"
|
|
#include "fir/fir2.h"
|
|
|
|
extern unsigned char _g_wave_rawdata[38400];
|
|
extern wt_descr_t _g_wt_descr[WT_NUM_WAVETABLES];
|
|
|
|
// --------------------------------------------------------------
|
|
// internal funcs
|
|
// --------------------------------------------------------------
|
|
// --------------------------------------------------------------
|
|
// Exported functions
|
|
// --------------------------------------------------------------
|
|
void VCO_ModInit(vco_common_t *pCom)
|
|
{
|
|
BLIT_ModInit(&pCom->blit);
|
|
}
|
|
|
|
void VCO_ModFree(vco_common_t *pCom)
|
|
{
|
|
BLIT_ModFree(&pCom->blit);
|
|
}
|
|
|
|
void VCO_Init(osc_t *pObj, UINT32 id, vco_common_t *pCom, synth_float_t fs)
|
|
{
|
|
pObj->pCom = pCom;
|
|
pObj->id = id;
|
|
pObj->fs = fs;
|
|
|
|
if (pObj->id == 0)
|
|
{
|
|
VCO_ModInit(pCom);
|
|
}
|
|
|
|
pObj->pOut = NULL;
|
|
pObj->bufsize = 0;
|
|
VCO_SetBufsize(pObj, SYNTH_MAX_BUFSIZE);
|
|
|
|
pObj->param[OSC_PARAM2_WAVEFORM] = OSC_WAVEFORM_SAWTOOTH;
|
|
|
|
Sine_Init(&pObj->sine, fs);
|
|
BLIT_Init(&pObj->blep, &pCom->blit, fs);
|
|
WT_Init(&pObj->wt, id, &pCom->wt, fs);
|
|
pObj->impulse = OSC_IMPULS_HEIGHT;
|
|
}
|
|
|
|
void VCO_Free(osc_t *pObj)
|
|
{
|
|
Sine_Free(&pObj->sine);
|
|
BLIT_Free(&pObj->blep);
|
|
WT_Free(&pObj->wt);
|
|
|
|
VCO_SetBufsize(pObj, 0);
|
|
|
|
if (pObj->id == 0)
|
|
{
|
|
VCO_ModFree(pObj->pCom);
|
|
}
|
|
}
|
|
|
|
void VCO_SetFS(osc_t *pObj, synth_float_t fs)
|
|
{
|
|
pObj->fs = fs;
|
|
Sine_SetFS(&pObj->sine, fs);
|
|
BLIT_SetFS(&pObj->blep, fs);
|
|
WT_SetFS(&pObj->wt, fs);
|
|
|
|
}
|
|
|
|
void VCO_SetBufsize(osc_t *pObj, UINT32 size)
|
|
{
|
|
BLIT_SetBufsize(&pObj->blep, size);
|
|
|
|
if (pObj->bufsize == size)
|
|
return;
|
|
|
|
pObj->bufsize = size;
|
|
|
|
if (pObj->pOut)
|
|
free(pObj->pOut);
|
|
|
|
pObj->pOut = NULL;
|
|
|
|
if (!size)
|
|
return;
|
|
|
|
pObj->pOut = (synth_float_t*)malloc(pObj->bufsize*sizeof(synth_float_t));
|
|
|
|
}
|
|
|
|
void VCO_Reset(osc_t *pObj, synth_float_t phase)
|
|
{
|
|
Sine_Reset(&pObj->sine, phase);
|
|
BLIT_Reset(&pObj->blep, phase);
|
|
WT_Reset(&pObj->wt, phase);
|
|
pObj->impulse = OSC_IMPULS_HEIGHT;
|
|
}
|
|
|
|
void VCO_Start(osc_t *pObj)
|
|
{
|
|
Sine_Start(&pObj->sine);
|
|
BLIT_Start(&pObj->blep);
|
|
WT_Start(&pObj->wt);
|
|
}
|
|
|
|
void VCO_Param2Set(osc_t *pObj, UINT32 type, synth_float_t value)
|
|
{
|
|
UINT32 wt_table;
|
|
|
|
switch(type)
|
|
{
|
|
case OSC_PARAM2_WAVEFORM:
|
|
if (pObj->param[type] == (UINT32)value)
|
|
break;
|
|
pObj->param[type] = (UINT32)value;
|
|
if ((pObj->param[OSC_PARAM2_WAVEFORM] >= OSC_WAVEFORM_WAVETABLE) && (pObj->param[OSC_PARAM2_WAVEFORM] < (OSC_WAVEFORM_WAVETABLE+WT_NUM_WAVETABLES)))
|
|
{
|
|
wt_table = (UINT32)(pObj->param[OSC_PARAM2_WAVEFORM]-OSC_WAVEFORM_WAVETABLE);
|
|
// WT_Param2Set(&pObj->wt, WT_PARAM2_WAVEFORM, WT_WAVEFORM_REGULAR);
|
|
WT_Param2Set(&pObj->wt, WT_PARAM2_WAVEFORM, WT_WAVEFORM_INTERPOLATED);
|
|
WT_Param2Set(&pObj->wt, WT_PARAM2_WAVETABLE_ID, wt_table);
|
|
}
|
|
Sine_Prepare(&pObj->sine);
|
|
BLIT_Prepare(&pObj->blep, 1024);
|
|
WT_Prepare(&pObj->wt);
|
|
break;
|
|
|
|
case OSC_PARAM2_DUTYCYCLE:
|
|
pObj->param[type] = value;
|
|
BLIT_SetDutyCycle(&pObj->blep, value);
|
|
WT_Param2Set(&pObj->wt, WT_PARAM2_WAVETABLE_ENTRY, value);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void VCO_ProcessDataV(osc_t *pObj, synth_float_t *pPitch, synth_float_t *pCV_fm, synth_float_t *pCV_pwm, UINT32 *pSyncIn, UINT32 *pSyncOut, UINT32 len)
|
|
{
|
|
UINT32 i, is_slave;
|
|
synth_float_t *pOut;
|
|
synth_float_t out;
|
|
|
|
pOut = pObj->pOut;
|
|
|
|
is_slave = (pSyncIn != NULL) && (pSyncOut == NULL);
|
|
|
|
if (pSyncOut)
|
|
memset(pSyncOut, 0, len*sizeof(synth_float_t));
|
|
|
|
// Create output
|
|
if (pObj->param[OSC_PARAM2_WAVEFORM] == OSC_WAVEFORM_SAWTOOTH)
|
|
{
|
|
BLIT_Process_SAW_Vector(&pObj->blep, pPitch, pCV_fm, pSyncIn, pSyncOut, pObj->pOut, len);
|
|
}
|
|
|
|
if (pObj->param[OSC_PARAM2_WAVEFORM] == OSC_WAVEFORM_SQUARE)
|
|
{
|
|
BLIT_Process_SQR_Vector(&pObj->blep, pPitch, pCV_fm, pCV_pwm, pSyncIn, pSyncOut, pObj->pOut, len);
|
|
}
|
|
|
|
if (pObj->param[OSC_PARAM2_WAVEFORM] == OSC_WAVEFORM_TRIANGLE)
|
|
{
|
|
BLIT_Process_TRI_Vector(&pObj->blep, pPitch, pCV_fm, pSyncIn, pSyncOut, pObj->pOut, len);
|
|
}
|
|
|
|
if (pObj->param[OSC_PARAM2_WAVEFORM] == OSC_WAVEFORM_SINE)
|
|
{
|
|
for (i=0; i< len; i++)
|
|
{
|
|
out = Sine_Process_Scalar(&pObj->sine, pPitch[i], pCV_fm[i]);
|
|
if(is_slave && pSyncIn[i])
|
|
{
|
|
Sine_Reset(&pObj->sine, 0);
|
|
}
|
|
*(pOut++) = out;
|
|
}
|
|
}
|
|
|
|
if (pObj->param[OSC_PARAM2_WAVEFORM] == OSC_WAVEFORM_IMPULSE)
|
|
{
|
|
for (i=0; i< len; i++)
|
|
{
|
|
out = pObj->impulse;
|
|
pObj->impulse = 0;
|
|
*(pOut++) = out;
|
|
}
|
|
}
|
|
|
|
if ((pObj->param[OSC_PARAM2_WAVEFORM] >= OSC_WAVEFORM_WAVETABLE) && (pObj->param[OSC_PARAM2_WAVEFORM] < (OSC_WAVEFORM_WAVETABLE+WT_NUM_WAVETABLES)))
|
|
{
|
|
WT_ProcessDataV(&pObj->wt, pPitch, pCV_fm, pCV_pwm, pObj->pOut, len);
|
|
}
|
|
}
|
|
|
|
synth_float_t* VCO_GetProcessBuffer(osc_t *pObj)
|
|
{
|
|
return pObj->pOut;
|
|
}
|
|
|