/**
** Supermodel
** A Sega Model 3 Arcade Emulator.
** Copyright 2011 Bart Trzynadlowski, Nik Henson
**
** This file is part of Supermodel.
**
** Supermodel 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 3 of the License, or (at your option)
** any later version.
**
** Supermodel 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 Supermodel. If not, see .
**/
/*
* SCSPLFO.cpp
*
* SCSP low frequency oscillator emulation. Included directly into SCSP.cpp. Do
* not compile this!
*/
#include
#include
#define LFO_SHIFT 8
struct _LFO
{
unsigned short phase;
UINT32 phase_step;
int *table;
int *scale;
};
#define LFIX(v) ((unsigned int) ((float) (1<phase += LFO->phase_step;
#if LFO_SHIFT!=8
LFO->phase &= (1 << (LFO_SHIFT + 8)) - 1;
#endif
p = LFO->table[LFO->phase >> LFO_SHIFT];
p = LFO->scale[p + 128];
return p << (SHIFT - LFO_SHIFT);
}
signed int inline ALFO_Step(struct _LFO *LFO)
{
int p;
LFO->phase += LFO->phase_step;
#if LFO_SHIFT!=8
LFO->phase &= (1 << (LFO_SHIFT + 8)) - 1;
#endif
p = LFO->table[LFO->phase >> LFO_SHIFT];
p = LFO->scale[p];
return p << (SHIFT - LFO_SHIFT);
}
void LFO_ComputeStep(struct _LFO *LFO, UINT32 LFOF, UINT32 LFOWS, UINT32 LFOS, int ALFO)
{
float step = (float)LFOFreq[LFOF] * 256.0f / 44100.0f;
LFO->phase_step = (unsigned int)((float)(1 << LFO_SHIFT)*step);
if (ALFO)
{
switch (LFOWS)
{
case 0: LFO->table = ALFO_SAW; break;
case 1: LFO->table = ALFO_SQR; break;
case 2: LFO->table = ALFO_TRI; break;
case 3: LFO->table = ALFO_NOI; break;
}
LFO->scale = ASCALES[LFOS];
}
else
{
switch (LFOWS)
{
case 0: LFO->table = PLFO_SAW; break;
case 1: LFO->table = PLFO_SQR; break;
case 2: LFO->table = PLFO_TRI; break;
case 3: LFO->table = PLFO_NOI; break;
}
LFO->scale = PSCALES[LFOS];
}
}