~ubuntu-branches/debian/jessie/scummvm/jessie

« back to all changes in this revision

Viewing changes to audio/mods/paula.h

  • Committer: Bazaar Package Importer
  • Author(s): Moritz Muehlenhoff
  • Date: 2011-05-25 19:02:23 UTC
  • mto: This revision was merged to the branch mainline in revision 23.
  • Revision ID: james.westby@ubuntu.com-20110525190223-fiqm0oaec714xk31
Tags: upstream-1.3.0
ImportĀ upstreamĀ versionĀ 1.3.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ScummVM - Graphic Adventure Engine
 
2
 *
 
3
 * ScummVM is the legal property of its developers, whose names
 
4
 * are too numerous to list here. Please refer to the COPYRIGHT
 
5
 * file distributed with this source distribution.
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU General Public License
 
9
 * as published by the Free Software Foundation; either version 2
 
10
 * of the License, or (at your option) any later version.
 
11
 
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, write to the Free Software
 
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
20
 *
 
21
 * $URL$
 
22
 * $Id$
 
23
 *
 
24
 */
 
25
 
 
26
#ifndef SOUND_MODS_PAULA_H
 
27
#define SOUND_MODS_PAULA_H
 
28
 
 
29
#include "audio/audiostream.h"
 
30
#include "common/frac.h"
 
31
#include "common/mutex.h"
 
32
 
 
33
namespace Audio {
 
34
 
 
35
/**
 
36
 * Emulation of the "Paula" Amiga music chip
 
37
 * The interrupt frequency specifies the number of mixed wavesamples between
 
38
 * calls of the interrupt method
 
39
 */
 
40
class Paula : public AudioStream {
 
41
public:
 
42
        static const int NUM_VOICES = 4;
 
43
        enum {
 
44
                kPalSystemClock  = 7093790,
 
45
                kNtscSystemClock = 7159090,
 
46
                kPalCiaClock     = kPalSystemClock / 10,
 
47
                kNtscCiaClock    = kNtscSystemClock / 10,
 
48
                kPalPaulaClock   = kPalSystemClock / 2,
 
49
                kNtscPauleClock  = kNtscSystemClock / 2
 
50
        };
 
51
 
 
52
        /* TODO: Document this */
 
53
        struct Offset {
 
54
                uint    int_off;        // integral part of the offset
 
55
                frac_t  rem_off;        // fractional part of the offset, at least 0 and less than 1
 
56
 
 
57
                explicit Offset(int off = 0) : int_off(off), rem_off(0) {}
 
58
        };
 
59
 
 
60
        Paula(bool stereo = false, int rate = 44100, uint interruptFreq = 0);
 
61
        ~Paula();
 
62
 
 
63
        bool playing() const { return _playing; }
 
64
        void setTimerBaseValue( uint32 ticksPerSecond ) { _timerBase = ticksPerSecond; }
 
65
        uint32 getTimerBaseValue() { return _timerBase; }
 
66
        void setSingleInterrupt(uint sampleDelay) { assert(sampleDelay < _intFreq); _curInt = sampleDelay; }
 
67
        void setSingleInterruptUnscaled(uint timerDelay) {
 
68
                setSingleInterrupt((uint)(((double)timerDelay * getRate()) / _timerBase));
 
69
        }
 
70
        void setInterruptFreq(uint sampleDelay) { _intFreq = sampleDelay; _curInt = 0; }
 
71
        void setInterruptFreqUnscaled(uint timerDelay) {
 
72
                setInterruptFreq((uint)(((double)timerDelay * getRate()) / _timerBase));
 
73
        }
 
74
        void clearVoice(byte voice);
 
75
        void clearVoices() { for (int i = 0; i < NUM_VOICES; ++i) clearVoice(i); }
 
76
        void startPlay() { _playing = true; }
 
77
        void stopPlay() { _playing = false; }
 
78
        void pausePlay(bool pause) { _playing = !pause; }
 
79
 
 
80
// AudioStream API
 
81
        int readBuffer(int16 *buffer, const int numSamples);
 
82
        bool isStereo() const { return _stereo; }
 
83
        bool endOfData() const { return _end; }
 
84
        int getRate() const { return _rate; }
 
85
 
 
86
protected:
 
87
        struct Channel {
 
88
                const int8 *data;
 
89
                const int8 *dataRepeat;
 
90
                uint32 length;
 
91
                uint32 lengthRepeat;
 
92
                int16 period;
 
93
                byte volume;
 
94
                Offset offset;
 
95
                byte panning; // For stereo mixing: 0 = far left, 255 = far right
 
96
                int dmaCount;
 
97
        };
 
98
 
 
99
        bool _end;
 
100
        Common::Mutex _mutex;
 
101
 
 
102
        virtual void interrupt() = 0;
 
103
 
 
104
        void startPaula() {
 
105
                _playing = true;
 
106
                _end = false;
 
107
        }
 
108
 
 
109
        void stopPaula() {
 
110
                _playing = false;
 
111
                _end = true;
 
112
        }
 
113
 
 
114
        void setChannelPanning(byte channel, byte panning) {
 
115
                assert(channel < NUM_VOICES);
 
116
                _voice[channel].panning = panning;
 
117
        }
 
118
 
 
119
        void disableChannel(byte channel) {
 
120
                assert(channel < NUM_VOICES);
 
121
                _voice[channel].data = 0;
 
122
        }
 
123
 
 
124
        void enableChannel(byte channel) {
 
125
                assert(channel < NUM_VOICES);
 
126
                Channel &ch = _voice[channel];
 
127
                ch.data = ch.dataRepeat;
 
128
                ch.length = ch.lengthRepeat;
 
129
                // actually first 2 bytes are dropped?
 
130
                ch.offset = Offset(0);
 
131
                // ch.period = ch.periodRepeat;
 
132
        }
 
133
 
 
134
        void setChannelPeriod(byte channel, int16 period) {
 
135
                assert(channel < NUM_VOICES);
 
136
                _voice[channel].period = period;
 
137
        }
 
138
 
 
139
        void setChannelVolume(byte channel, byte volume) {
 
140
                assert(channel < NUM_VOICES);
 
141
                _voice[channel].volume = volume;
 
142
        }
 
143
 
 
144
        void setChannelSampleStart(byte channel, const int8 *data) {
 
145
                assert(channel < NUM_VOICES);
 
146
                _voice[channel].dataRepeat = data;
 
147
        }
 
148
 
 
149
        void setChannelSampleLen(byte channel, uint32 length) {
 
150
                assert(channel < NUM_VOICES);
 
151
                assert(length < 32768/2);
 
152
                _voice[channel].lengthRepeat = 2 * length;
 
153
        }
 
154
 
 
155
        void setChannelData(uint8 channel, const int8 *data, const int8 *dataRepeat, uint32 length, uint32 lengthRepeat, int32 offset = 0) {
 
156
                assert(channel < NUM_VOICES);
 
157
 
 
158
                Channel &ch = _voice[channel];
 
159
 
 
160
                ch.dataRepeat = data;
 
161
                ch.lengthRepeat = length;
 
162
                enableChannel(channel);
 
163
                ch.offset = Offset(offset);
 
164
 
 
165
                ch.dataRepeat = dataRepeat;
 
166
                ch.lengthRepeat = lengthRepeat;
 
167
        }
 
168
 
 
169
        void setChannelOffset(byte channel, Offset offset) {
 
170
                assert(channel < NUM_VOICES);
 
171
                _voice[channel].offset = offset;
 
172
        }
 
173
 
 
174
        Offset getChannelOffset(byte channel) {
 
175
                assert(channel < NUM_VOICES);
 
176
                return _voice[channel].offset;
 
177
        }
 
178
 
 
179
        int getChannelDmaCount(byte channel) {
 
180
                assert(channel < NUM_VOICES);
 
181
                return _voice[channel].dmaCount;
 
182
        }
 
183
 
 
184
        void setChannelDmaCount(byte channel, int dmaVal = 0) {
 
185
                assert(channel < NUM_VOICES);
 
186
                _voice[channel].dmaCount = dmaVal;
 
187
        }
 
188
 
 
189
        void setAudioFilter(bool enable) {
 
190
                // TODO: implement
 
191
        }
 
192
 
 
193
private:
 
194
        Channel _voice[NUM_VOICES];
 
195
 
 
196
        const bool _stereo;
 
197
        const int _rate;
 
198
        const double _periodScale;
 
199
        uint _intFreq;
 
200
        uint _curInt;
 
201
        uint32 _timerBase;
 
202
        bool _playing;
 
203
 
 
204
        template<bool stereo>
 
205
        int readBufferIntern(int16 *buffer, const int numSamples);
 
206
};
 
207
 
 
208
} // End of namespace Audio
 
209
 
 
210
#endif