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
|
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef AUDIO_SOFTSYNTH_CMS_H
#define AUDIO_SOFTSYNTH_CMS_H
#include "common/scummsys.h"
/* this structure defines a channel */
struct saa1099_channel {
int frequency; /* frequency (0x00..0xff) */
int freq_enable; /* frequency enable */
int noise_enable; /* noise enable */
int octave; /* octave (0x00..0x07) */
int amplitude[2]; /* amplitude (0x00..0x0f) */
int envelope[2]; /* envelope (0x00..0x0f or 0x10 == off) */
/* vars to simulate the square wave */
double counter;
double freq;
int level;
};
/* this structure defines a noise channel */
struct saa1099_noise {
/* vars to simulate the noise generator output */
double counter;
double freq;
int level; /* noise polynomal shifter */
};
/* this structure defines a SAA1099 chip */
struct SAA1099 {
int stream; /* our stream */
int noise_params[2]; /* noise generators parameters */
int env_enable[2]; /* envelope generators enable */
int env_reverse_right[2]; /* envelope reversed for right channel */
int env_mode[2]; /* envelope generators mode */
int env_bits[2]; /* non zero = 3 bits resolution */
int env_clock[2]; /* envelope clock mode (non-zero external) */
int env_step[2]; /* current envelope step */
int all_ch_enable; /* all channels enable */
int sync_state; /* sync all channels */
int selected_reg; /* selected register */
struct saa1099_channel channels[6]; /* channels */
struct saa1099_noise noise[2]; /* noise generators */
};
class CMSEmulator {
public:
CMSEmulator(uint32 sampleRate) {
// In PCs the chips run at 7.15909 MHz instead of 8 MHz.
// Adjust sampling rate upwards to bring pitch down.
_sampleRate = (sampleRate * 352) / 315;
memset(_saa1099, 0, sizeof(SAA1099)*2);
}
~CMSEmulator() { }
void portWrite(int port, int val);
void readBuffer(int16 *buffer, const int numSamples);
private:
uint32 _sampleRate;
SAA1099 _saa1099[2];
void envelope(int chip, int ch);
void update(int chip, int16 *buffer, int length);
void portWriteIntern(int chip, int offset, int data);
};
#endif
|