aboutsummaryrefslogtreecommitdiff
path: root/sound/mixer_intern.h
blob: ad162dd162ad0140fc1c50f4cefd3bacfce2bcf2 (plain)
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
/* 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.
 *
 * $URL$
 * $Id$
 *
 */

#ifndef SOUND_MIXER_INTERN_H
#define SOUND_MIXER_INTERN_H

#include "common/scummsys.h"
#include "common/mutex.h"
#include "sound/mixer.h"

namespace Audio {

/**
 * The (default) implementation of the ScummVM audio mixing subsystem.
 *
 * Backends are responsible for allocating (and later releasing) an instance
 * of this class, which engines can access via OSystem::getMixer().
 *
 * Initialisation of instances of this class usually happens as follows:
 * 1) Creat a new Audio::MixerImpl instance.
 * 2) Set the hardware output sample rate via the setSampleRate() method.
 * 3) Hook up the mixCallback() in a suitable audio processing thread/callback.
 * 4) Change the mixer into ready mode via setReady(true).
 * 5) Start audio processing (e.g. by resuming the audio thread, if applicable).
 *
 * In the future, we might make it possible for backends to provide
 * (partial) alternative implementations of the mixer, e.g. to make
 * better use of native sound mixing support on low-end devices.
 *
 * @see OSystem::getMixer()
 */
class MixerImpl : public Mixer {
private:
	enum {
		NUM_CHANNELS = 16
	};

	OSystem *_syst;
	Common::Mutex _mutex;

	uint _sampleRate;
	bool _mixerReady;
	uint32 _handleSeed;

	int _volumeForSoundType[4];
	Channel *_channels[NUM_CHANNELS];


public:
	MixerImpl(OSystem *system);
	~MixerImpl();

	virtual bool isReady() const { return _mixerReady; }

	virtual void playRaw(
		SoundType type,
		SoundHandle *handle,
		void *sound, uint32 size, uint rate, byte flags,
		int id, byte volume, int8 balance,
		uint32 loopStart, uint32 loopEnd);

	virtual void playInputStream(
		SoundType type,
		SoundHandle *handle,
		AudioStream *input,
		int id, byte volume, int8 balance,
		bool autofreeStream,
		bool permanent,
		bool reverseStereo);

	virtual void playInputStreamLooping(
		SoundType type,
		SoundHandle *handle,
		SeekableAudioStream *input,
		uint loopCount,
		Timestamp loopStart, Timestamp loopEnd,
		int id, byte volume, int8 balance,
		bool autofreeStream,
		bool permanent,
		bool reverseStereo);

	virtual void stopAll();
	virtual void stopID(int id);
	virtual void stopHandle(SoundHandle handle);

	virtual void pauseAll(bool paused);
	virtual void pauseID(int id, bool paused);
	virtual void pauseHandle(SoundHandle handle, bool paused);

	virtual bool isSoundIDActive(int id);
	virtual int getSoundID(SoundHandle handle);

	virtual bool isSoundHandleActive(SoundHandle handle);

	virtual void setChannelVolume(SoundHandle handle, byte volume);
	virtual void setChannelBalance(SoundHandle handle, int8 balance);

	virtual uint32 getSoundElapsedTime(SoundHandle handle);

	virtual bool hasActiveChannelOfType(SoundType type);

	virtual void setVolumeForSoundType(SoundType type, int volume);
	virtual int getVolumeForSoundType(SoundType type) const;

	virtual uint getOutputRate() const;

protected:
	void insertChannel(SoundHandle *handle, Channel *chan);

public:
	/**
	 * The mixer callback function, to be called at regular intervals by
	 * the backend (e.g. from an audio mixing thread). All the actual mixing
	 * work is done from here.
	 */
	void mixCallback(byte *samples, uint len);

	/**
	 * Set the internal 'is ready' flag of the mixer.
	 * Backends should invoke Mixer::setReady(true) once initialisation of
	 * their audio system has been completed (and in particular, *after*
	 * setOutputRate() has been called).
	 */
	void setReady(bool ready);

	/**
	 * Set the output sample rate.
	 *
	 * @param sampleRate	the new output sample rate
	 *
	 * @note Right now, this can be done exactly ONCE. That is, the mixer
	 * currently does not support changing the output sample rate after it
	 * has been set for the first time.  This may change in the future.
	 */
	void setOutputRate(uint sampleRate);
};


} // End of namespace Audio

#endif