Files
JaySynth/Source/synth/vco.c
T
jens eecd6c5005 - increased to version 0.5.8
- 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
2020-07-23 15:42:35 +00:00

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;
}