xref: /haiku/headers/os/media/SoundPlayer.h (revision 49546fa993e8de87ddebffd56f890aec71aa42d3)
1 /*
2  * Copyright 2009, Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef _SOUND_PLAYER_H
6 #define _SOUND_PLAYER_H
7 
8 
9 #include <exception>
10 
11 #include <BufferProducer.h>
12 #include <Locker.h>
13 #include <MediaDefs.h>
14 
15 
16 class BContinuousParameter;
17 class BParameterWeb;
18 class BSound;
19 class _SoundPlayNode;
20 
21 
22 class sound_error : public std::exception {
23 			const char*			m_str_const;
24 public:
25 								sound_error(const char* string);
26 			const char*			what() const throw();
27 };
28 
29 
30 class BSoundPlayer {
31 	friend class _SoundPlayNode;
32 public:
33 			enum sound_player_notification {
34 				B_STARTED = 1,
35 				B_STOPPED,
36 				B_SOUND_DONE
37 			};
38 
39 								BSoundPlayer(const char* name = NULL,
40 									void (*PlayBuffer)(void*, void* buffer,
41 										size_t size,
42 										const media_raw_audio_format& format)
43 										= NULL,
44 									void (*Notifier)(void*,
45 										sound_player_notification what, ...)
46 										= NULL,
47 									void* cookie = NULL);
48 								BSoundPlayer(
49 									const media_raw_audio_format* format,
50 									const char* name = NULL,
51 									void (*PlayBuffer)(void*, void* buffer,
52 										size_t size,
53 										const media_raw_audio_format& format)
54 										= NULL,
55 									void (*Notifier)(void*,
56 										sound_player_notification what, ...)
57 										= NULL,
58 									void* cookie = NULL);
59 								BSoundPlayer(
60 									const media_node& toNode,
61 									const media_multi_audio_format* format
62 										= NULL,
63 									const char* name = NULL,
64 									const media_input* input = NULL,
65 									void (*PlayBuffer)(void*, void* buffer,
66 										size_t size,
67 										const media_raw_audio_format& format)
68 										= NULL,
69 									void (*Notifier)(void*,
70 										sound_player_notification what, ...)
71 										= NULL,
72 									void* cookie = NULL);
73 	virtual						~BSoundPlayer();
74 
75 			status_t			InitCheck();
76 			media_raw_audio_format Format() const;
77 
78 			status_t			Start();
79 			void				Stop(bool block = true, bool flush = true);
80 
81 	typedef void (*BufferPlayerFunc)(void*, void*, size_t,
82 		const media_raw_audio_format&);
83 
84 			BufferPlayerFunc	BufferPlayer() const;
85 			void				SetBufferPlayer(void (*PlayBuffer)(void*,
86 									void* buffer, size_t size,
87 									const media_raw_audio_format& format));
88 	typedef void (*EventNotifierFunc)(void*, sound_player_notification what,
89 		...);
90 			EventNotifierFunc	EventNotifier() const;
91 			void				SetNotifier(void (*Notifier)(void*,
92 									sound_player_notification what, ...));
93 			void*				Cookie() const;
94 			void				SetCookie(void* cookie);
95 			void				SetCallbacks(void (*PlayBuffer)(void*,
96 									void* buffer, size_t size,
97 									const media_raw_audio_format& format)
98 										= NULL,
99 									void (*Notifier)(void*,
100 										sound_player_notification what, ...)
101 										= NULL,
102 									void* cookie = NULL);
103 
104 	typedef int32 play_id;
105 
106 			bigtime_t			CurrentTime();
107 			bigtime_t			PerformanceTime();
108 			status_t			Preroll();
109 			play_id				StartPlaying(BSound* sound,
110 									bigtime_t atTime = 0);
111 			play_id 			StartPlaying(BSound* sound,
112 									bigtime_t atTime,
113 									float withVolume);
114 			status_t 			SetSoundVolume(play_id sound, float newVolume);
115 			bool 				IsPlaying(play_id id);
116 			status_t 			StopPlaying(play_id id);
117 			status_t		 	WaitForSound(play_id id);
118 
119 			// On [0..1]
120 			float 				Volume();
121 			void 				SetVolume(float volume);
122 
123 			// -xx - +xx (see GetVolumeInfo())
124 			// If 'forcePoll' is false, a cached value will be used if new
125 			// enough.
126 			float				VolumeDB(bool forcePoll = false);
127 			void				SetVolumeDB(float dB);
128 			status_t			GetVolumeInfo(media_node* _node,
129 									int32* _parameterID, float* _minDB,
130 									float* _maxDB);
131 			bigtime_t			Latency();
132 
133 	virtual	bool				HasData();
134 			void				SetHasData(bool hasData);
135 
136 	// TODO: Needs Perform() method for FBC!
137 
138 protected:
139 
140 			void				SetInitError(status_t inError);
141 
142 private:
143 	static	void				_SoundPlayBufferFunc(void* cookie,
144 									void* buffer, size_t size,
145 									const media_raw_audio_format& format);
146 
147 	// FBC padding
148 	virtual	status_t			_Reserved_SoundPlayer_0(void*, ...);
149 	virtual	status_t			_Reserved_SoundPlayer_1(void*, ...);
150 	virtual	status_t			_Reserved_SoundPlayer_2(void*, ...);
151 	virtual	status_t			_Reserved_SoundPlayer_3(void*, ...);
152 	virtual	status_t			_Reserved_SoundPlayer_4(void*, ...);
153 	virtual	status_t			_Reserved_SoundPlayer_5(void*, ...);
154 	virtual	status_t			_Reserved_SoundPlayer_6(void*, ...);
155 	virtual	status_t			_Reserved_SoundPlayer_7(void*, ...);
156 
157 private:
158 			_SoundPlayNode*		fPlayerNode;
159 
160 			struct _playing_sound {
161 				_playing_sound*	next;
162 				off_t			current_offset;
163 				BSound*			sound;
164 				play_id			id;
165 				int32			delta;
166 				int32			rate;
167 				sem_id			wait_sem;
168 				float			volume;
169 			};
170 
171 			_playing_sound*		fPlayingSounds;
172 
173 			struct _waiting_sound {
174 				_waiting_sound*	next;
175 				bigtime_t		start_time;
176 				BSound*			sound;
177 				play_id			id;
178 				int32			rate;
179 				float			volume;
180 			};
181 
182 			_waiting_sound*		fWaitingSounds;
183 
184 			void (*fPlayBufferFunc)(void* cookie, void* buffer,
185 				size_t size, const media_raw_audio_format& format);
186 			void (*fNotifierFunc)(void* cookie, sound_player_notification what,
187 				...);
188 
189 			BLocker				fLocker;
190 			float				fVolumeDB;
191 			media_input			fMediaInput;
192 				// Usually the system mixer
193 			media_output		fMediaOutput;
194 				// The playback node
195 			void*				fCookie;
196 				// Opaque handle passed to hooks
197 			int32				fFlags;
198 
199 			status_t			fInitStatus;
200 			BContinuousParameter* fVolumeSlider;
201 			bigtime_t			fLastVolumeUpdate;
202 			BParameterWeb*		fParameterWeb;
203 
204 			uint32				_m_reserved[15];
205 
206 private:
207 			void				NotifySoundDone(play_id sound, bool gotToPlay);
208 
209 			void				get_volume_slider();
210 			void				Init(const media_node* node,
211 									const media_multi_audio_format* format,
212 									const char* name,
213 									const media_input* input,
214 									void (*PlayBuffer)(void*, void* buffer,
215 										size_t size,
216 										const media_raw_audio_format& format),
217 									void (*Notifier)(void*,
218 										sound_player_notification what, ...),
219 									void* cookie);
220 	// For B_STARTED and B_STOPPED, the argument is BSoundPlayer* (this).
221 	// For B_SOUND_DONE, the arguments are play_id and true/false for
222 	// whether it got to play data at all.
223 	virtual	void				Notify(sound_player_notification what,
224 									...);
225 	// Get data into the buffer to play -- this version will use the
226 	// queued BSound system.
227 	virtual	void				PlayBuffer(void* buffer, size_t size,
228 									const media_raw_audio_format& format);
229 };
230 
231 #endif // _SOUND_PLAYER_H
232