File: sound_clip.h

package info (click to toggle)
scummvm 2.9.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 450,580 kB
  • sloc: cpp: 4,299,825; asm: 28,322; python: 12,901; sh: 11,302; java: 9,289; xml: 7,895; perl: 2,639; ansic: 2,465; yacc: 1,670; javascript: 1,020; makefile: 933; lex: 578; awk: 275; objc: 82; sed: 11; php: 1
file content (254 lines) | stat: -rw-r--r-- 7,168 bytes parent folder | download | duplicates (3)
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
/* 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 3 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, see <http://www.gnu.org/licenses/>.
 *
 */

//=============================================================================
//
// ACSOUND - AGS sound system wrapper
//
//=============================================================================

#ifndef AGS_ENGINE_MEDIA_AUDIO_SOUNDCLIP_H
#define AGS_ENGINE_MEDIA_AUDIO_SOUNDCLIP_H

#include "audio/mixer.h"
#include "audio/audiostream.h"
#include "common/stream.h"

namespace AGS3 {

// SOUNDCLIP's state and parameter updates sync with the audio core in
// batches, only when the engine updates the game, never while the user script
// is being executed. The sync is performed by calling update().
// This is to ensure that the clip reference, state and properties don't change
// in the middle of the script's command sequence.

// TODO: one of the biggest problems with sound clips currently is that it
// provides several methods of applying volume, which may ignore or override
// each other, and does not shape a consistent interface.
// Improving this situation is only possible with massive refactory of
// sound clip use, taking backwards-compatible audio system in account.

enum SoundClipState {
	SoundClipInitial, SoundClipPlaying, SoundClipPaused, SoundClipStopped
};

struct SOUNDCLIP {
	SOUNDCLIP();
	virtual ~SOUNDCLIP() {}

	// TODO: move these to private
	int _sourceClipID;
	int _sourceClipType;
	bool _repeat;
	int _priority;
	int _xSource, _ySource;     // Used for positioning sounds in game rooms
	int _maximumPossibleDistanceAway;

	int _vol255;
	int _vol100;
	int _volModifier;
	int _panning;
	int _panningAsPercentage;
	int _directionalVolModifier;

	virtual int play() = 0;
	virtual void pause() = 0;
	virtual void resume() = 0;

	/**
	 * Seeks to the position, where pos units depend on the audio type:
	 *  - MIDI - the beat number
	 *  - MOD / XM / S3M - the pattern number
	 *  - WAV / VOC - the sample number
	 *  - OGG / MP3 - milliseconds
	 */
	virtual void seek(int offset) = 0;

	/**
	 * Seeks to the position in milliseconds
	 */
	virtual void seek_ms(int pos_ms) = 0;

	virtual int play_from(int position) = 0;
	virtual bool is_playing() = 0; // true if playing or paused. false if never played or stopped.
	virtual bool is_paused() = 0; // true if paused

	/**
	 * Get legacy sound format type
	 */
	virtual int get_sound_type() const = 0;

	/**
	 * Return current position in frames
	 */
	virtual int get_pos() = 0;

	/**
	 * Return the position in milliseconds
	 */
	virtual int get_pos_ms() = 0;

	/**
	 * Return total track length in ms (or 0)
	 */
	virtual int get_length_ms() = 0;

	virtual void set_panning(int newPanning) = 0;
	virtual void set_speed(int new_speed) = 0;
	virtual void poll() = 0;

	/**
	 * Gets clip's volume property, as percentage (0 - 100);
	 * note this may not be the real volume of playback (which could e.g. be muted)
	 */
	inline int get_volume100() const { return _vol100; }

	/**
	 * Gets clip's volume measured in 255 units
	 */
    inline int get_volume255() const { return _vol255; }

	/**
	 * Gets clip's panning (-100 - +100)
	 */
    inline int get_panning() const { return _panning; }

	/**
	 * Gets clip's playback speed in clip ms per real second
	 */
    inline int get_speed() const { return _speed; }

	/**
	 * Gets if clip is muted (without changing the volume setting)
	 */
    inline bool is_muted() const { return _muted; }

	/**
	 * Sets the current volume property, as percentage (0 - 100)
	 */
	void set_volume100(int volume);

	/**
	 * Sets the current volume property, as a level (0 - 255)
	 */
	void set_volume255(int volume);

	/**
	 * Explicitly defines both percentage and absolute volume value,
	 * without calculating it from given percentage.
	 * NOTE: this overrides the mute
	 */
	void set_volume_direct(int vol_percent, int vol_absolute);

	/**
	 * Mutes sound clip, while preserving current volume property
	 * for the future reference; when unmuted, that property is
	 * used to restart previous volume.
	 */
	void set_mute(bool mute);

	/**
	 * Apply arbitrary permanent volume modifier, in absolute units (0 - 255);
	 * this is distinct value that is used in conjunction with current volume
	 * (can be both positive and negative).
	 */
	void apply_volume_modifier(int mod);

	/**
	 * Apply permanent directional volume modifier, in absolute units (0 - 255)
	 * this is distinct value that is used in conjunction with current volume
	 * (can be both positive and negative).
	 */
	void apply_directional_modifier(int mod);

	inline bool is_ready() { return is_playing(); }

	/**
	 * Returns if the clip is still playing, otherwise it's finished
	 */
	bool update();

protected:
	virtual void adjust_volume() = 0;

	// mute mode overrides the volume; if set, any volume assigned is stored
	// in properties, but not applied to playback itself
	bool _muted = false;

	// speed of playback, in clip ms per real second
	int _speed = 0;

	bool _paramsChanged = false;

	// helper function for calculating volume with applied modifiers
	inline int get_final_volume() const {
		int final_vol = _vol255 + _volModifier + _directionalVolModifier;
		return final_vol >= 0 ? final_vol : 0;
	}
};

struct SoundClipWaveBase : public SOUNDCLIP {
private:
	Audio::Mixer::SoundType _soundType = Audio::Mixer::kPlainSoundType;

	int pos_to_posms(int pos) const;

public:
	Audio::Mixer *_mixer;
	Audio::AudioStream *_stream;
	Audio::SoundHandle _soundHandle;
	SoundClipState _state;
	bool _waitingToPlay = false;

	SoundClipWaveBase(Audio::AudioStream *stream, bool repeat = false);
	~SoundClipWaveBase() override;

	void setType(Audio::Mixer::SoundType type);

	void poll() override;
	int play() override;
	int play_from(int position) override;
	void pause() override;
	void resume() override;
	bool is_playing() override;
	bool is_paused() override;
	void seek(int offset) override;
	void seek_ms(int pos_ms) override;
	int get_pos() override;
	int get_pos_ms() override;
	int get_length_ms() override;
	void set_panning(int newPanning) override;
	void set_speed(int new_speed) override;
	void adjust_volume() override;
};

template<int SOUND_TYPE>
struct SoundClipWave : public SoundClipWaveBase {
	SoundClipWave(Audio::AudioStream *stream, bool repeat = false) :
		SoundClipWaveBase(stream, repeat) {}
	int get_sound_type() const {
		return SOUND_TYPE;
	}
};

} // namespace AGS3

#endif