168 lines
4.6 KiB
C++
Executable file
168 lines
4.6 KiB
C++
Executable file
/*-----------------------------------------------------------------------------
|
|
|
|
ST-Sound ( YM files player library )
|
|
|
|
Extended YM-2149 Emulator, with ATARI music demos effects.
|
|
(SID-Like, Digidrum, Sync Buzzer, Sinus SID and Pattern SID)
|
|
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* ST-Sound, ATARI-ST Music Emulator
|
|
* Copyright (c) 1995-1999 Arnaud Carre ( http://leonard.oxg.free.fr )
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
|
|
#ifndef __YM2149EX__
|
|
#define __YM2149EX__
|
|
|
|
#define AMSTRAD_CLOCK 1000000L
|
|
#define ATARI_CLOCK 2000000L
|
|
#define SPECTRUM_CLOCK 1773400L
|
|
#define MFP_CLOCK 2457600L
|
|
#define NOISESIZE 16384
|
|
#define DRUM_PREC 15
|
|
|
|
#define PI 3.1415926
|
|
#define SIDSINPOWER 0.7
|
|
|
|
enum
|
|
{
|
|
VOICE_A=0,
|
|
VOICE_B=1,
|
|
VOICE_C=2,
|
|
};
|
|
|
|
struct YmSpecialEffect
|
|
{
|
|
|
|
ymbool bDrum;
|
|
ymu32 drumSize;
|
|
ymu8 * drumData;
|
|
ymu32 drumPos;
|
|
ymu32 drumStep;
|
|
|
|
ymbool bSid;
|
|
ymu32 sidPos;
|
|
ymu32 sidStep;
|
|
ymint sidVol;
|
|
|
|
};
|
|
|
|
static const ymint DC_ADJUST_BUFFERLEN = 512;
|
|
|
|
class CDcAdjuster
|
|
{
|
|
public:
|
|
CDcAdjuster();
|
|
|
|
void AddSample(ymint sample);
|
|
ymint GetDcLevel(void) { return m_sum / DC_ADJUST_BUFFERLEN; }
|
|
void Reset(void);
|
|
|
|
private:
|
|
ymint m_buffer[DC_ADJUST_BUFFERLEN];
|
|
ymint m_pos;
|
|
ymint m_sum;
|
|
};
|
|
|
|
|
|
class CYm2149Ex
|
|
{
|
|
public:
|
|
CYm2149Ex(ymu32 masterClock=ATARI_CLOCK,ymint prediv=1,ymu32 playRate=44100);
|
|
~CYm2149Ex();
|
|
|
|
void reset(void);
|
|
void update(ymsample *pSampleBuffer,ymint nbSample);
|
|
|
|
void setClock(ymu32 _clock);
|
|
void writeRegister(ymint reg,ymint value);
|
|
ymint readRegister(ymint reg);
|
|
void drumStart(ymint voice,ymu8 *drumBuffer,ymu32 drumSize,ymint drumFreq);
|
|
void drumStop(ymint voice);
|
|
void sidStart(ymint voice,ymint freq,ymint vol);
|
|
void sidSinStart(ymint voice,ymint timerFreq,ymint sinPattern);
|
|
void sidStop(ymint voice);
|
|
void syncBuzzerStart(ymint freq,ymint envShape);
|
|
void syncBuzzerStop(void);
|
|
|
|
void setFilter(ymbool bFilter) { m_bFilter = bFilter; }
|
|
|
|
private:
|
|
|
|
CDcAdjuster m_dcAdjust;
|
|
|
|
ymu32 frameCycle;
|
|
ymu32 cyclePerSample;
|
|
inline ymsample nextSample(void);
|
|
ymu32 toneStepCompute(ymu8 rHigh,ymu8 rLow);
|
|
ymu32 noiseStepCompute(ymu8 rNoise);
|
|
ymu32 envStepCompute(ymu8 rHigh,ymu8 rLow);
|
|
void updateEnvGen(ymint nbSample);
|
|
void updateNoiseGen(ymint nbSample);
|
|
void updateToneGen(ymint voice,ymint nbSample);
|
|
ymu32 rndCompute(void);
|
|
|
|
void sidVolumeCompute(ymint voice,ymint *pVol);
|
|
inline int LowPassFilter(int in);
|
|
|
|
ymint replayFrequency;
|
|
ymu32 internalClock;
|
|
ymu8 registers[14];
|
|
|
|
ymu32 cycleSample;
|
|
ymu32 stepA,stepB,stepC;
|
|
ymu32 posA,posB,posC;
|
|
ymint volA,volB,volC,volE;
|
|
ymu32 mixerTA,mixerTB,mixerTC;
|
|
ymu32 mixerNA,mixerNB,mixerNC;
|
|
ymint *pVolA,*pVolB,*pVolC;
|
|
|
|
ymu32 noiseStep;
|
|
ymu32 noisePos;
|
|
ymu32 rndRack;
|
|
ymu32 currentNoise;
|
|
ymu32 bWrite13;
|
|
|
|
ymu32 envStep;
|
|
ymu32 envPos;
|
|
ymint envPhase;
|
|
ymint envShape;
|
|
ymu8 envData[16][2][16*2];
|
|
ymint globalVolume;
|
|
|
|
struct YmSpecialEffect specialEffect[3];
|
|
ymbool bSyncBuzzer;
|
|
ymu32 syncBuzzerStep;
|
|
ymu32 syncBuzzerPhase;
|
|
ymint syncBuzzerShape;
|
|
|
|
int m_lowPassFilter[2];
|
|
ymbool m_bFilter;
|
|
};
|
|
|
|
#endif
|