mirror of
https://github.com/ZDoom/ZMusic.git
synced 2024-12-03 17:12:08 +00:00
72c23d98a3
## 1.5.0 2020-09-28 * Drum note length expanding is now supported in real-time mode (Thanks to [Jean Pierre Cimalando](https://github.com/jpcima) for a work!) * Added support for OPNA chip with Neko Project II Kai YM2602 emulator usage (Thanks to [Jean Pierre Cimalando](https://github.com/jpcima) for a work!) * Added VGM file dumper which allows to output OPN2 commands into VGM file. (A new MIDI to VGM tool is now created with basing on libOPNMIDI) * Fixed an incorrect work of CC-121 (See https://github.com/Wohlstand/libADLMIDI/issues/227 for details) * Internality has been refactored and improved
115 lines
2.7 KiB
C++
115 lines
2.7 KiB
C++
// ---------------------------------------------------------------------------
|
|
// PSG-like sound generator
|
|
// Copyright (C) cisc 1997, 1999.
|
|
// ---------------------------------------------------------------------------
|
|
// $Id: psg.h,v 1.8 2003/04/22 13:12:53 cisc Exp $
|
|
|
|
#ifndef PSG_H
|
|
#define PSG_H
|
|
|
|
#include "fmgen_types.h"
|
|
|
|
// libOPNMIDI: change int32 to int16
|
|
#define PSG_SAMPLETYPE int16 // int32 or int16
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// class PSG
|
|
// PSG に良く似た音を生成する音源ユニット
|
|
//
|
|
// interface:
|
|
// bool SetClock(uint clock, uint rate)
|
|
// 初期化.このクラスを使用する前にかならず呼んでおくこと.
|
|
// PSG のクロックや PCM レートを設定する
|
|
//
|
|
// clock: PSG の動作クロック
|
|
// rate: 生成する PCM のレート
|
|
// retval 初期化に成功すれば true
|
|
//
|
|
// void Mix(Sample* dest, int nsamples)
|
|
// PCM を nsamples 分合成し, dest で始まる配列に加える(加算する)
|
|
// あくまで加算なので,最初に配列をゼロクリアする必要がある
|
|
//
|
|
// void Reset()
|
|
// リセットする
|
|
//
|
|
// void SetReg(uint reg, uint8 data)
|
|
// レジスタ reg に data を書き込む
|
|
//
|
|
// uint GetReg(uint reg)
|
|
// レジスタ reg の内容を読み出す
|
|
//
|
|
// void SetVolume(int db)
|
|
// 各音源の音量を調節する
|
|
// 単位は約 1/2 dB
|
|
//
|
|
struct PSGData {
|
|
uint8 reg[16];
|
|
uint olevel[3];
|
|
uint32 scount[3];
|
|
uint32 speriod[3];
|
|
uint32 ecount;
|
|
uint32 eperiod;
|
|
uint32 ncount;
|
|
uint32 nperiod;
|
|
uint32 tperiodbase;
|
|
uint32 eperiodbase;
|
|
uint32 nperiodbase;
|
|
int volume;
|
|
int mask;
|
|
};
|
|
|
|
class PSG
|
|
{
|
|
public:
|
|
typedef PSG_SAMPLETYPE Sample;
|
|
|
|
enum
|
|
{
|
|
noisetablesize = 1 << 11, // ←メモリ使用量を減らしたいなら減らして
|
|
toneshift = 24,
|
|
envshift = 22,
|
|
noiseshift = 14,
|
|
oversampling = 2 // ← 音質より速度が優先なら減らすといいかも
|
|
};
|
|
|
|
public:
|
|
PSG();
|
|
~PSG();
|
|
|
|
void Mix(Sample* dest, int nsamples);
|
|
void SetClock(int clock, int rate);
|
|
|
|
void SetVolume(int vol);
|
|
void SetChannelMask(int c);
|
|
|
|
void Reset();
|
|
void SetReg(uint regnum, uint8 data);
|
|
uint GetReg(uint regnum) { return reg[regnum & 0x0f]; }
|
|
|
|
void DataSave(struct PSGData* data);
|
|
void DataLoad(struct PSGData* data);
|
|
|
|
protected:
|
|
void MakeNoiseTable();
|
|
void MakeEnvelopTable();
|
|
static void StoreSample(Sample& dest, int32 data);
|
|
|
|
uint8 reg[16];
|
|
|
|
const uint* envelop;
|
|
uint olevel[3];
|
|
uint32 scount[3], speriod[3];
|
|
uint32 ecount, eperiod;
|
|
uint32 ncount, nperiod;
|
|
uint32 tperiodbase;
|
|
uint32 eperiodbase;
|
|
uint32 nperiodbase;
|
|
int volume;
|
|
int mask;
|
|
|
|
static uint enveloptable[16][64];
|
|
static uint noisetable[noisetablesize];
|
|
static int EmitTable[32];
|
|
};
|
|
|
|
#endif // PSG_H
|