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  */
22 
23 #ifndef ULTIMA8_AUDIO_AUDIOPROCESS_H
24 #define ULTIMA8_AUDIO_AUDIOPROCESS_H
25 
26 #include "ultima/ultima8/kernel/process.h"
27 #include "ultima/ultima8/usecode/intrinsics.h"
28 #include "ultima/shared/std/string.h"
29 #include "ultima/ultima8/misc/classtype.h"
30 
31 namespace Ultima {
32 namespace Ultima8 {
33 
34 class AudioSample;
35 
36 class AudioProcess : public Process {
37 public:
38 
39 	static const uint32 PITCH_SHIFT_NONE;
40 
41 	struct SampleInfo {
42 		int32       _sfxNum;
43 		int32       _priority;
44 		ObjId       _objId;
45 		int32       _loops;
46 		int32       _channel;
47 		Std::string _barked;
48 		uint32      _curSpeechStart, _curSpeechEnd;
49 		uint32      _pitchShift;    // PITCH_SHIFT_NONE is normal
50 		uint16      _volume;         // 0-255
51 		int16       _lVol;
52 		int16       _rVol;
53 		bool		_ambient;
54 
SampleInfoSampleInfo55 		SampleInfo() : _sfxNum(-1) { }
SampleInfoSampleInfo56 		SampleInfo(int32 s, int32 p, ObjId o, int32 l, int32 c, uint32 ps, uint16 v, int16 lv, int16 rv, bool ambient) :
57 			_sfxNum(s), _priority(p), _objId(o), _loops(l), _channel(c),
58 			_pitchShift(ps), _volume(v), _lVol(lv), _rVol(rv),
59 			_curSpeechStart(0), _curSpeechEnd(0), _ambient(ambient) { }
SampleInfoSampleInfo60 		SampleInfo(const Std::string &b, int32 shpnum, ObjId o, int32 c,
61 				   uint32 s, uint32 e, uint32 ps, uint16 v, int16 lv, int16 rv, bool ambient) :
62 			_sfxNum(-1), _priority(shpnum), _objId(o), _loops(0), _channel(c), _barked(b),
63 			_curSpeechStart(s), _curSpeechEnd(e), _pitchShift(ps), _volume(v),
64 			_lVol(lv), _rVol(rv), _ambient(ambient) { }
65 	};
66 
67 	Std::list<SampleInfo> _sampleInfo;
68 public:
69 	// p_dynamic_class stuff
70 	ENABLE_RUNTIME_CLASSTYPE()
71 
72 	AudioProcess(void);
73 	~AudioProcess(void) override;
74 
75 	//! Get the current instance of the Audio Processes
get_instance()76 	static AudioProcess *get_instance() {
77 		return _theAudioProcess;
78 	}
79 
80 	INTRINSIC(I_playSFX);
81 	INTRINSIC(I_playAmbientSFX);
82 	INTRINSIC(I_playSFXCru);
83 	INTRINSIC(I_playAmbientSFXCru);
84 	INTRINSIC(I_isSFXPlaying);
85 	INTRINSIC(I_isSFXPlayingForObject);
86 	INTRINSIC(I_setVolumeSFX);
87 	INTRINSIC(I_stopSFX);
88 	INTRINSIC(I_stopSFXCru);
89 	INTRINSIC(I_stopAllSFX);
90 
91 	void run() override;
92 
93 	void playSFX(int sfxNum, int priority, ObjId objId, int loops,
94 				 bool no_duplicates, uint32 pitchShift,
95 				 uint16 volume, int16 lVol, int16 rVol,
96 				 bool ambient);
97 
98 	void playSFX(int sfxNum, int priority, ObjId objId, int loops,
99 				 bool no_duplicates = false, uint32 pitchShift = PITCH_SHIFT_NONE,
100 				 uint16 volume = 0x80, bool ambient = false) {
101 		playSFX(sfxNum, priority, objId, loops, no_duplicates, pitchShift, volume, -1, -1, ambient);
102 	}
103 
104 	//! stop sfx on object.  set sfxNum = -1 to stop all for object.
105 	void stopSFX(int sfxNum, ObjId objId);
106 	bool isSFXPlaying(int sfxNum);
107 	bool isSFXPlayingForObject(int sfxNum, ObjId objId);
108 	void setVolumeSFX(int sfxNum, uint8 volume);
109 
110 	bool playSpeech(const Std::string &barked, int shapenum, ObjId objId,
111 					uint32 pitchShift = PITCH_SHIFT_NONE, uint16 volume = 255);
112 	void stopSpeech(const Std::string &barked, int shapenum, ObjId objId);
113 	bool isSpeechPlaying(const Std::string &barked, int shapenum);
114 
115 	//! get length (in milliseconds) of speech
116 	uint32 getSpeechLength(const Std::string &barked, int shapenum) const;
117 
118 	//! play a sample (without storing a SampleInfo)
119 	//! returns channel sample is played on, or -1
120 	int playSample(AudioSample *sample, int priority, int loops, bool isSpeech = false,
121 				   uint32 pitchShift = PITCH_SHIFT_NONE, int16 lVol = 255,
122 				   int16 rVol = 255, bool ambient = false);
123 
124 	//! pause all currently playing samples
125 	void pauseAllSamples();
126 	//! unpause all currently playing samples
127 	void unpauseAllSamples();
128 
129 	//! stop all samples except speech
130 	void stopAllExceptSpeech();
131 
132 	bool loadData(Common::ReadStream *rs, uint32 version);
133 	void saveData(Common::WriteStream *ws) override;
134 
135 private:
136 	uint32 _paused;
137 
138 	//! play the next speech sample for the text in this SampleInfo
139 	//! note: si is reused if successful
140 	//! returns true if there was speech left to play, or false if finished
141 	bool continueSpeech(SampleInfo &si);
142 
143 	bool calculateSoundVolume(ObjId objId, int16 &lVol, int16 &rVol) const;
144 
145 	static AudioProcess *_theAudioProcess;
146 };
147 
148 } // End of namespace Ultima8
149 } // End of namespace Ultima
150 
151 #endif
152