/** ** 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]; } }