~ubuntu-branches/ubuntu/raring/scummvm/raring

« back to all changes in this revision

Viewing changes to sound/softsynth/emumidi.h

  • Committer: Bazaar Package Importer
  • Author(s): Moritz Muehlenhoff
  • Date: 2011-05-25 19:02:23 UTC
  • mto: (21.1.2 sid)
  • mto: This revision was merged to the branch mainline in revision 24.
  • 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-1-2-1/sound/softsynth/emumidi.h $
22
 
 * $Id: emumidi.h 40932 2009-05-27 00:34:31Z lordhoto $
23
 
 */
24
 
 
25
 
#ifndef SOUND_SOFTSYNTH_EMUMIDI_H
26
 
#define SOUND_SOFTSYNTH_EMUMIDI_H
27
 
 
28
 
#include "sound/audiostream.h"
29
 
#include "sound/mididrv.h"
30
 
#include "sound/mixer.h"
31
 
 
32
 
#define FIXP_SHIFT 16
33
 
 
34
 
class MidiDriver_Emulated : public Audio::AudioStream, public MidiDriver {
35
 
protected:
36
 
        bool _isOpen;
37
 
        Audio::Mixer *_mixer;
38
 
        Audio::SoundHandle _mixerSoundHandle;
39
 
 
40
 
private:
41
 
        Common::TimerManager::TimerProc _timerProc;
42
 
        void *_timerParam;
43
 
 
44
 
        int _nextTick;
45
 
        int _samplesPerTick;
46
 
 
47
 
protected:
48
 
        virtual void generateSamples(int16 *buf, int len) = 0;
49
 
        virtual void onTimer() {}
50
 
 
51
 
        int _baseFreq;
52
 
 
53
 
public:
54
 
        MidiDriver_Emulated(Audio::Mixer *mixer) : _mixer(mixer) {
55
 
                _isOpen = false;
56
 
 
57
 
                _timerProc = 0;
58
 
                _timerParam = 0;
59
 
 
60
 
                _nextTick = 0;
61
 
                _samplesPerTick = 0;
62
 
 
63
 
                _baseFreq = 250;
64
 
        }
65
 
 
66
 
        int open() {
67
 
                _isOpen = true;
68
 
 
69
 
                int d = getRate() / _baseFreq;
70
 
                int r = getRate() % _baseFreq;
71
 
 
72
 
                // This is equivalent to (getRate() << FIXP_SHIFT) / BASE_FREQ
73
 
                // but less prone to arithmetic overflow.
74
 
 
75
 
                _samplesPerTick = (d << FIXP_SHIFT) + (r << FIXP_SHIFT) / _baseFreq;
76
 
                return 0;
77
 
        }
78
 
 
79
 
        void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc) {
80
 
                _timerProc = timer_proc;
81
 
                _timerParam = timer_param;
82
 
        }
83
 
 
84
 
        uint32 getBaseTempo() { return 1000000 / _baseFreq; }
85
 
 
86
 
 
87
 
        // AudioStream API
88
 
        int readBuffer(int16 *data, const int numSamples) {
89
 
                const int stereoFactor = isStereo() ? 2 : 1;
90
 
                int len = numSamples / stereoFactor;
91
 
                int step;
92
 
 
93
 
                do {
94
 
                        step = len;
95
 
                        if (step > (_nextTick >> FIXP_SHIFT))
96
 
                                step = (_nextTick >> FIXP_SHIFT);
97
 
 
98
 
                        generateSamples(data, step);
99
 
 
100
 
                        _nextTick -= step << FIXP_SHIFT;
101
 
                        if (!(_nextTick >> FIXP_SHIFT)) {
102
 
                                if (_timerProc)
103
 
                                        (*_timerProc)(_timerParam);
104
 
                                onTimer();
105
 
                                _nextTick += _samplesPerTick;
106
 
                        }
107
 
                        data += step * stereoFactor;
108
 
                        len -= step;
109
 
                } while (len);
110
 
 
111
 
                return numSamples;
112
 
        }
113
 
        bool endOfData() const { return false; }
114
 
};
115
 
 
116
 
#endif