-
Notifications
You must be signed in to change notification settings - Fork 1
/
eupplayer_townsEmulator.hpp
266 lines (244 loc) · 7.57 KB
/
eupplayer_townsEmulator.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
// $Id: eupplayer_townsEmulator.h,v 1.13 2000/04/12 23:12:51 hayasaka Exp $
/* Artistic Style
*
* ./astyle --style=stroustrup --convert-tabs --add-braces eupplayer_townsEmulator.hpp
*/
#ifndef TJH__EUP_TOWNSEMULATOR_H
#define TJH__EUP_TOWNSEMULATOR_H
#if defined ( __MINGW32__ )
#include <sys/time.h>
#endif // __MINGW32__
#if defined ( __GNUC__ )
#include <sys/time.h>
#endif // __GNUC__
#include <sys/types.h>
#include <iostream>
#include <cstdint>
#include "eupplayer_towns.hpp"
/*
* global data
*
*/
const int streamAudioSampleOctectSize = 2; // it matches with int16_t buffer[] definition below
const int streamAudioRate = 44100; // 44100 Hz rate stream
const int streamAudioSamplesBlock = 512; // a Block counts 512 Samples
const int streamAudioChannelsNum = 2; // 1 = monaural, 2 = stereophonic
const int streamAudioSamplesBlockNum = 16;
// buffer size definitions
const int streamAudioSamplesBuffer = streamAudioSamplesBlock * streamAudioSamplesBlockNum;
const int streamAudioChannelsSamplesBlock = streamAudioSamplesBlock * streamAudioChannelsNum;
const int streamAudioChannelsSamplesBuffer = streamAudioChannelsSamplesBlock * streamAudioSamplesBlockNum;
//const int streamAudioBufferOctectsSize = streamAudioChannelsSamplesBuffer * streamAudioSampleOctectSize;
const int streamBytesPerSecond = streamAudioRate * streamAudioChannelsNum * streamAudioSampleOctectSize;
struct pcm_struct {
bool on;
int stop;
int write_pos;
int read_pos;
int count;
int16_t buffer[streamAudioChannelsSamplesBuffer];
};
extern struct pcm_struct pcm;
class TownsPcmInstrument;
class TownsPcmSound;
class TownsPcmEnvelope;
class EUP_TownsEmulator_MonophonicAudioSynthesizer {
int _rate;
int _velocity;
public:
EUP_TownsEmulator_MonophonicAudioSynthesizer() {}
virtual ~EUP_TownsEmulator_MonophonicAudioSynthesizer() {}
virtual void setControlParameter(int control, int value) = 0;
virtual void setInstrumentParameter(uint8_t const *fmInst,
uint8_t const *pcmInst) = 0;
virtual int velocity() const
{
return _velocity;
}
virtual void velocity(int velo)
{
_velocity = velo;
}
virtual void nextTick(int *outbuf, int buflen) = 0;
virtual int rate() const
{
return _rate;
}
virtual void rate(int r)
{
_rate = r;
}
virtual void note(int n, int onVelo, int offVelo, int gateTime) = 0;
virtual void pitchBend(int value) = 0;
};
class TownsFmEmulator_Operator {
enum State { _s_ready, _s_attacking, _s_decaying, _s_sustaining, _s_releasing };
State _state;
State _oldState;
int64_t _currentLevel;
int _frequency;
int _phase;
int _lastOutput;
int _feedbackLevel;
int _detune;
int _multiple;
int64_t _totalLevel;
int _keyScale;
int _velocity;
int _specifiedTotalLevel;
int _specifiedAttackRate;
int _specifiedDecayRate;
int _specifiedSustainLevel;
int _specifiedSustainRate;
int _specifiedReleaseRate;
int _tickCount;
int _attackTime;
// int64_t _attackRate;
int64_t _decayRate;
int64_t _sustainLevel;
int64_t _sustainRate;
int64_t _releaseRate;
public:
TownsFmEmulator_Operator();
~TownsFmEmulator_Operator();
void feedbackLevel(int level);
void setInstrumentParameter(uint8_t const *instrument);
void velocity(int velo);
void keyOn();
void keyOff();
void frequency(int freq);
int nextTick(int rate, int phaseShift);
};
class TownsFmEmulator : public EUP_TownsEmulator_MonophonicAudioSynthesizer {
enum { _numOfOperators = 4 };
TownsFmEmulator_Operator *_opr;
int _chn_volume;
int _expression;
int _gateTime;
int _offVelocity;
int _note;
int _frequencyOffs;
int _frequency;
int _algorithm;
int _enableL;
int _enableR;
public:
TownsFmEmulator();
~TownsFmEmulator();
void setControlParameter(int control, int value);
void setInstrumentParameter(uint8_t const *fmInst, uint8_t const *pcmInst);
int velocity()
{
return EUP_TownsEmulator_MonophonicAudioSynthesizer::velocity();
}
void velocity(int velo);
void nextTick(int *outbuf, int buflen);
void note(int n, int onVelo, int offVelo, int gateTime);
void pitchBend(int value);
void recalculateFrequency();
};
class TownsPcmEmulator : public EUP_TownsEmulator_MonophonicAudioSynthesizer {
int _chn_volume;
int _expression;
int _envTick;
int _currentLevel;
int _gateTime;
int _offVelocity;
int _note;
int _frequencyOffs;
int _phase;
int _volL;
int _volR;
TownsPcmInstrument const *_currentInstrument;
TownsPcmSound const *_currentSound;
TownsPcmEnvelope *_currentEnvelope;
public:
TownsPcmEmulator();
~TownsPcmEmulator();
void setControlParameter(int control, int value);
void setInstrumentParameter(uint8_t const *fmInst, uint8_t const *pcmInst);
void nextTick(int *outbuf, int buflen);
void note(int n, int onVelo, int offVelo, int gateTime);
void pitchBend(int value);
};
class EUP_TownsEmulator_Channel {
enum { _maxDevices = 16 };
EUP_TownsEmulator_MonophonicAudioSynthesizer *_dev[_maxDevices+1];
int _lastNotedDeviceNum;
public:
EUP_TownsEmulator_Channel();
~EUP_TownsEmulator_Channel();
void add(EUP_TownsEmulator_MonophonicAudioSynthesizer *device);
void note(int note, int onVelo, int offVelo, int gateTime);
void setControlParameter(int control, int value);
void setInstrumentParameter(uint8_t const *fmInst, uint8_t const *pcmInst);
void pitchBend(int value);
void nextTick(int *outbuf, int buflen);
void rate(int r);
};
class EUP_TownsEmulator : public TownsAudioDevice {
FILE *_ostr = nullptr;
enum { _maxChannelNum = 16,
_maxFmInstrumentNum = 128,
_maxPcmInstrumentNum = 32,
_maxPcmSoundNum = 128,
};
EUP_TownsEmulator_Channel *_channel[_maxChannelNum];
bool _enabled[_maxChannelNum];
uint8_t _fmInstrumentData[8 + 48*_maxFmInstrumentNum];
uint8_t *_fmInstrument[_maxFmInstrumentNum]; // pointers into above _fmInstrumentData buffer
TownsPcmInstrument *_pcmInstrument[_maxPcmInstrumentNum];
TownsPcmSound *_pcmSound[_maxPcmSoundNum];
int _rate;
bool _outputSampleUnsigned;
int _outputSampleSize;
int _outputSampleChannels;
bool _outputSampleLSBFirst;
bool _output2File = false;
public:
EUP_TownsEmulator();
~EUP_TownsEmulator();
void outputSampleUnsigned(bool u)
{
_outputSampleUnsigned = u;
}
void outputSampleSize(int l)
{
_outputSampleSize = l;
}
void outputSampleChannels(int l)
{
_outputSampleChannels = l;
}
void outputSampleLSBFirst(bool l)
{
_outputSampleLSBFirst = l;
}
bool outputSampleLSBFirst_read()
{
return _outputSampleLSBFirst;
}
void output2File(bool u)
{
_output2File = u;
}
bool output2File_read()
{
return _output2File;
}
void assignFmDeviceToChannel(int channel);
void assignPcmDeviceToChannel(int channel);
void setFmInstrumentParameter(int num, uint8_t const *instrument);
void setPcmInstrumentParameters(uint8_t const *instrument, size_t size);
void outputStream(FILE* ostr);
FILE* outputStream_get();
void nextTick();
void enable(int ch, bool en=true);
void note(int channel, int n,
int onVelo, int offVelo, int gateTime);
void pitchBend(int channel, int value);
void controlChange(int channel, int control, int value);
void programChange(int channel, int num);
void rate(int r);
};
#endif