1/*
2 * Copyright 2009-2010, 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
16class BContinuousParameter;
17class BParameterWeb;
18class BSound;
19namespace BPrivate {
20	class SoundPlayNode;
21}
22
23
24class sound_error : public std::exception {
25			const char*			m_str_const;
26public:
27								sound_error(const char* string);
28			const char*			what() const throw();
29};
30
31
32class BSoundPlayer {
33public:
34	enum sound_player_notification {
35		B_STARTED = 1,
36		B_STOPPED,
37		B_SOUND_DONE
38	};
39
40	typedef void (*BufferPlayerFunc)(void*, void* buffer, size_t size,
41		const media_raw_audio_format& format);
42	typedef void (*EventNotifierFunc)(void*, sound_player_notification what,
43		...);
44
45public:
46								BSoundPlayer(const char* name = NULL,
47									BufferPlayerFunc playerFunction = NULL,
48									EventNotifierFunc
49										eventNotifierFunction = NULL,
50									void* cookie = NULL);
51								BSoundPlayer(
52									const media_raw_audio_format* format,
53									const char* name = NULL,
54									BufferPlayerFunc playerFunction = NULL,
55									EventNotifierFunc
56										eventNotifierFunction = NULL,
57									void* cookie = NULL);
58								BSoundPlayer(
59									const media_node& toNode,
60									const media_multi_audio_format*
61										format = NULL,
62									const char* name = NULL,
63									const media_input* input = NULL,
64									BufferPlayerFunc playerFunction = NULL,
65									EventNotifierFunc
66										eventNotifierFunction = NULL,
67									void* cookie = NULL);
68	virtual						~BSoundPlayer();
69
70			status_t			InitCheck();
71			media_raw_audio_format Format() const;
72
73			status_t			Start();
74			void				Stop(bool block = true, bool flush = true);
75
76			BufferPlayerFunc	BufferPlayer() const;
77			void				SetBufferPlayer(void (*PlayBuffer)(void*,
78									void* buffer, size_t size,
79									const media_raw_audio_format& format));
80
81			EventNotifierFunc	EventNotifier() const;
82			void				SetNotifier(
83									EventNotifierFunc eventNotifierFunction);
84			void*				Cookie() const;
85			void				SetCookie(void* cookie);
86			void				SetCallbacks(
87									BufferPlayerFunc playerFunction = NULL,
88									EventNotifierFunc
89										eventNotifierFunction = NULL,
90									void* cookie = NULL);
91
92	typedef int32 play_id;
93
94			bigtime_t			CurrentTime();
95			bigtime_t			PerformanceTime();
96			status_t			Preroll();
97			play_id				StartPlaying(BSound* sound,
98									bigtime_t atTime = 0);
99			play_id 			StartPlaying(BSound* sound,
100									bigtime_t atTime,
101									float withVolume);
102			status_t 			SetSoundVolume(play_id sound, float newVolume);
103			bool 				IsPlaying(play_id id);
104			status_t 			StopPlaying(play_id id);
105			status_t		 	WaitForSound(play_id id);
106
107			// On [0..1]
108			float 				Volume();
109			void 				SetVolume(float volume);
110
111			// -xx - +xx (see GetVolumeInfo())
112			// If 'forcePoll' is false, a cached value will be used if new
113			// enough.
114			float				VolumeDB(bool forcePoll = false);
115			void				SetVolumeDB(float dB);
116			status_t			GetVolumeInfo(media_node* _node,
117									int32* _parameterID, float* _minDB,
118									float* _maxDB);
119			bigtime_t			Latency();
120
121	virtual	bool				HasData();
122			void				SetHasData(bool hasData);
123
124	// TODO: Needs Perform() method for FBC!
125
126protected:
127
128			void				SetInitError(status_t error);
129
130private:
131	static	void				_SoundPlayBufferFunc(void* cookie,
132									void* buffer, size_t size,
133									const media_raw_audio_format& format);
134
135	// FBC padding
136	virtual	status_t			_Reserved_SoundPlayer_0(void*, ...);
137	virtual	status_t			_Reserved_SoundPlayer_1(void*, ...);
138	virtual	status_t			_Reserved_SoundPlayer_2(void*, ...);
139	virtual	status_t			_Reserved_SoundPlayer_3(void*, ...);
140	virtual	status_t			_Reserved_SoundPlayer_4(void*, ...);
141	virtual	status_t			_Reserved_SoundPlayer_5(void*, ...);
142	virtual	status_t			_Reserved_SoundPlayer_6(void*, ...);
143	virtual	status_t			_Reserved_SoundPlayer_7(void*, ...);
144
145			void				_Init(const media_node* node,
146									const media_multi_audio_format* format,
147									const char* name, const media_input* input,
148									BufferPlayerFunc playerFunction,
149									EventNotifierFunc eventNotifierFunction,
150									void* cookie);
151			void				_GetVolumeSlider();
152
153			void				_NotifySoundDone(play_id sound, bool gotToPlay);
154
155	// TODO: those two shouldn't be virtual
156	virtual	void				Notify(sound_player_notification what, ...);
157	virtual	void				PlayBuffer(void* buffer, size_t size,
158									const media_raw_audio_format& format);
159
160private:
161	friend class BPrivate::SoundPlayNode;
162
163	struct playing_sound {
164		playing_sound*	next;
165		off_t			current_offset;
166		BSound*			sound;
167		play_id			id;
168		int32			delta;
169		int32			rate;
170		sem_id			wait_sem;
171		float			volume;
172	};
173
174	struct waiting_sound {
175		waiting_sound*	next;
176		bigtime_t		start_time;
177		BSound*			sound;
178		play_id			id;
179		int32			rate;
180		float			volume;
181	};
182
183			BPrivate::SoundPlayNode* fPlayerNode;
184
185			playing_sound*		fPlayingSounds;
186			waiting_sound*		fWaitingSounds;
187
188			BufferPlayerFunc	fPlayBufferFunc;
189			EventNotifierFunc	fNotifierFunc;
190
191			BLocker				fLocker;
192			float				fVolumeDB;
193			media_input			fMediaInput;
194				// Usually the system mixer
195			media_output		fMediaOutput;
196				// The playback node
197			void*				fCookie;
198				// Opaque handle passed to hooks
199			int32				fFlags;
200
201			status_t			fInitStatus;
202			BContinuousParameter* fVolumeSlider;
203			bigtime_t			fLastVolumeUpdate;
204			BParameterWeb*		fParameterWeb;
205
206			uint32				_reserved[15];
207};
208
209#endif // _SOUND_PLAYER_H
210