ScummVM API documentation
emumidi.h
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 modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (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, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef AUDIO_SOFTSYNTH_EMUMIDI_H
23 #define AUDIO_SOFTSYNTH_EMUMIDI_H
24 
25 #include "audio/audiostream.h"
26 #include "audio/mididrv.h"
27 #include "audio/mixer.h"
28 
30 protected:
31  bool _isOpen;
32  Audio::Mixer *_mixer;
33  Audio::SoundHandle _mixerSoundHandle;
34 
35 private:
37  void *_timerParam;
38 
39  enum {
40  FIXP_SHIFT = 16
41  };
42 
43  int _nextTick;
44  int _samplesPerTick;
45 
46 protected:
47  int _baseFreq;
48 
49  virtual void generateSamples(int16 *buf, int len) = 0;
50  virtual void onTimer() {}
51 
52 public:
54  _mixer(mixer),
55  _isOpen(false),
56  _timerProc(0),
57  _timerParam(0),
58  _nextTick(0),
59  _samplesPerTick(0),
60  _baseFreq(250) {
61  }
62 
63  // MidiDriver API
64  virtual int open() {
65  _isOpen = true;
66 
67  int d = getRate() / _baseFreq;
68  int r = getRate() % _baseFreq;
69 
70  // This is equivalent to (getRate() << FIXP_SHIFT) / BASE_FREQ
71  // but less prone to arithmetic overflow.
72 
73  _samplesPerTick = (d << FIXP_SHIFT) + (r << FIXP_SHIFT) / _baseFreq;
74 
75  return 0;
76  }
77 
78  bool isOpen() const { return _isOpen; }
79 
80  virtual void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc) {
81  _timerProc = timer_proc;
82  _timerParam = timer_param;
83  }
84 
85  virtual uint32 getBaseTempo() {
86  return 1000000 / _baseFreq;
87  }
88 
89  // AudioStream API
90  virtual int readBuffer(int16 *data, const int numSamples) {
91  const int stereoFactor = isStereo() ? 2 : 1;
92  int len = numSamples / stereoFactor;
93  int step;
94 
95  do {
96  step = len;
97  if (step > (_nextTick >> FIXP_SHIFT))
98  step = (_nextTick >> FIXP_SHIFT);
99 
100  generateSamples(data, step);
101 
102  _nextTick -= step << FIXP_SHIFT;
103  if (!(_nextTick >> FIXP_SHIFT)) {
104  if (_timerProc)
105  (*_timerProc)(_timerParam);
106 
107  onTimer();
108 
109  _nextTick += _samplesPerTick;
110  }
111 
112  data += step * stereoFactor;
113  len -= step;
114  } while (len);
115 
116  return numSamples;
117  }
118 
119  virtual bool endOfData() const {
120  return false;
121  }
122 };
123 
124 #endif
virtual int readBuffer(int16 *data, const int numSamples)
Definition: emumidi.h:90
virtual int getRate() const =0
virtual uint32 getBaseTempo()
Definition: emumidi.h:85
void(* TimerProc)(void *refCon)
Definition: timer.h:42
virtual bool isStereo() const =0
Definition: mididrv.h:309
Definition: mixer.h:49
Definition: mixer.h:59
virtual bool endOfData() const
Definition: emumidi.h:119
virtual int open()
Definition: emumidi.h:64
Definition: audiostream.h:50
bool isOpen() const
Definition: emumidi.h:78
Definition: emumidi.h:29