xref: /haiku/src/kits/media/SoundPlayer.cpp (revision 7120e97489acbf17d86d3f33e3b2e68974fd4b23)
1 /***********************************************************************
2  * AUTHOR: Marcus Overhagen
3  *   FILE: SoundPlayer.cpp
4  *  DESCR:
5  ***********************************************************************/
6 #include <TimeSource.h>
7 #include <SoundPlayer.h>
8 #include <MediaRoster.h>
9 #include <math.h>
10 
11 #include "debug.h"
12 #include "SoundPlayNode.h"
13 
14 /* this is the normal volume DB range of 16 bit integer */
15 const float minDB = -96;
16 const float maxDB = 0;
17 
18 /*************************************************************
19  * public sound_error
20  *************************************************************/
21 
22 //final
23 sound_error::sound_error(const char *str)
24 {
25 	CALLED();
26 	m_str_const = str;
27 }
28 
29 //final
30 const char *
31 sound_error::what() const
32 {
33 	CALLED();
34 	return m_str_const;
35 }
36 
37 /*************************************************************
38  * public BSoundPlayer
39  *************************************************************/
40 
41 BSoundPlayer::BSoundPlayer(const char * name,
42 						   void (*PlayBuffer)(void *, void * buffer, size_t size, const media_raw_audio_format & format),
43 						   void (*Notifier)(void *, sound_player_notification what, ...),
44 						   void * cookie)
45 {
46 	CALLED();
47 
48 	Init(NULL,&media_multi_audio_format::wildcard,name,NULL,PlayBuffer,Notifier,cookie);
49 }
50 
51 BSoundPlayer::BSoundPlayer(const media_raw_audio_format * format,
52 						   const char * name,
53 						   void (*PlayBuffer)(void *, void * buffer, size_t size, const media_raw_audio_format & format),
54 						   void (*Notifier)(void *, sound_player_notification what, ...),
55 						   void * cookie)
56 {
57 	CALLED();
58 	media_multi_audio_format fmt = media_multi_audio_format::wildcard;
59 	memcpy(&fmt,format,sizeof(*format));
60 	Init(NULL,&fmt,name,NULL,PlayBuffer,Notifier,cookie);
61 }
62 
63 BSoundPlayer::BSoundPlayer(const media_node & toNode,
64 						   const media_multi_audio_format * format,
65 						   const char * name,
66 						   const media_input * input,
67 						   void (*PlayBuffer)(void *, void * buffer, size_t size, const media_raw_audio_format & format),
68 						   void (*Notifier)(void *, sound_player_notification what, ...),
69 						   void * cookie)
70 {
71 	CALLED();
72 	if (toNode.kind & B_BUFFER_CONSUMER == 0)
73 		debugger("BSoundPlayer: toNode must have B_BUFFER_CONSUMER kind!\n");
74 	Init(&toNode,format,name,input,PlayBuffer,Notifier,cookie);
75 }
76 
77 /* virtual */
78 BSoundPlayer::~BSoundPlayer()
79 {
80 	CALLED();
81 	if (_m_node)
82 		_m_node->Release();
83 	delete _m_node;
84 	delete [] _m_buf;
85 }
86 
87 
88 status_t
89 BSoundPlayer::InitCheck()
90 {
91 	CALLED();
92 	return _m_init_err;
93 }
94 
95 
96 media_raw_audio_format
97 BSoundPlayer::Format() const
98 {
99 	CALLED();
100 
101 	media_raw_audio_format temp = media_raw_audio_format::wildcard;
102 
103 	if (_m_node) {
104 		media_multi_audio_format fmt;
105 		fmt = _m_node->Format();
106 		memcpy(&temp,&fmt,sizeof(temp));
107 	}
108 
109 	return temp;
110 }
111 
112 
113 status_t
114 BSoundPlayer::Start()
115 {
116 	CALLED();
117 
118 	if (!_m_node)
119 		return B_ERROR;
120 
121 	_m_node->Start();
122 	return B_OK;
123 }
124 
125 
126 void
127 BSoundPlayer::Stop(bool block,
128 				   bool flush)
129 {
130 	CALLED();
131 
132 	if (!_m_node)
133 		return;
134 
135 	_m_node->Stop();
136 }
137 
138 BSoundPlayer::BufferPlayerFunc
139 BSoundPlayer::BufferPlayer() const
140 {
141 	CALLED();
142 	return _PlayBuffer;
143 }
144 
145 void BSoundPlayer::SetBufferPlayer(void (*PlayBuffer)(void *, void * buffer, size_t size, const media_raw_audio_format & format))
146 {
147 	CALLED();
148 	_m_lock.Lock();
149 	_PlayBuffer = PlayBuffer;
150 	_m_lock.Unlock();
151 }
152 
153 BSoundPlayer::EventNotifierFunc
154 BSoundPlayer::EventNotifier() const
155 {
156 	CALLED();
157 	return _Notifier;
158 }
159 
160 void BSoundPlayer::SetNotifier(void (*Notifier)(void *, sound_player_notification what, ...))
161 {
162 	CALLED();
163 	_m_lock.Lock();
164 	_Notifier = Notifier;
165 	_m_lock.Unlock();
166 }
167 
168 void *
169 BSoundPlayer::Cookie() const
170 {
171 	CALLED();
172 	return _m_cookie;
173 }
174 
175 void
176 BSoundPlayer::SetCookie(void *cookie)
177 {
178 	CALLED();
179 	_m_lock.Lock();
180 	_m_cookie = cookie;
181 	_m_lock.Unlock();
182 }
183 
184 void BSoundPlayer::SetCallbacks(void (*PlayBuffer)(void *, void * buffer, size_t size, const media_raw_audio_format & format),
185 								void (*Notifier)(void *, sound_player_notification what, ...),
186 								void * cookie)
187 {
188 	CALLED();
189 	_m_lock.Lock();
190 	SetBufferPlayer(PlayBuffer);
191 	SetNotifier(Notifier);
192 	SetCookie(cookie);
193 	_m_lock.Unlock();
194 }
195 
196 
197 bigtime_t
198 BSoundPlayer::CurrentTime()
199 {
200 	CALLED();
201 	if (!_m_node)
202 		return system_time();
203 #if 0 /* we don't have a media roster, or real media nodes yet */
204 	return _m_node->TimeSource()->Now(); /* either this one is wrong */
205 #endif
206 	return system_time();
207 }
208 
209 
210 bigtime_t
211 BSoundPlayer::PerformanceTime()
212 {
213 	CALLED();
214 	if (!_m_node)
215 		return (bigtime_t) B_ERROR;
216 #if 0 /* we don't have a media roster, or real media nodes yet */
217 	return _m_node->TimeSource()->Now(); /* or this one is wrong */
218 #endif
219 	return system_time();
220 }
221 
222 
223 status_t
224 BSoundPlayer::Preroll()
225 {
226 	UNIMPLEMENTED();
227 
228 	return B_OK;
229 }
230 
231 
232 BSoundPlayer::play_id
233 BSoundPlayer::StartPlaying(BSound *sound,
234 						   bigtime_t at_time)
235 {
236 	UNIMPLEMENTED();
237 	return 1;
238 }
239 
240 
241 BSoundPlayer::play_id
242 BSoundPlayer::StartPlaying(BSound *sound,
243 						   bigtime_t at_time,
244 						   float with_volume)
245 {
246 	UNIMPLEMENTED();
247 	return 1;
248 }
249 
250 
251 status_t
252 BSoundPlayer::SetSoundVolume(play_id sound,
253 							 float new_volume)
254 {
255 	UNIMPLEMENTED();
256 
257 	return B_OK;
258 }
259 
260 
261 bool
262 BSoundPlayer::IsPlaying(play_id id)
263 {
264 	UNIMPLEMENTED();
265 
266 	return true;
267 }
268 
269 
270 status_t
271 BSoundPlayer::StopPlaying(play_id id)
272 {
273 	UNIMPLEMENTED();
274 
275 	return B_OK;
276 }
277 
278 
279 status_t
280 BSoundPlayer::WaitForSound(play_id id)
281 {
282 	UNIMPLEMENTED();
283 
284 	return B_OK;
285 }
286 
287 
288 float
289 BSoundPlayer::Volume()
290 {
291 	CALLED();
292 	return _m_volume;
293 }
294 
295 
296 void
297 BSoundPlayer::SetVolume(float new_volume)
298 {
299 	CALLED();
300 	_m_lock.Lock();
301 	if (new_volume >= 0.0f)
302 		_m_volume = new_volume;
303 	_m_lock.Unlock();
304 }
305 
306 
307 float
308 BSoundPlayer::VolumeDB(bool forcePoll)
309 {
310 	CALLED();
311 	return 20.0f * log10(_m_volume);
312 }
313 
314 
315 void
316 BSoundPlayer::SetVolumeDB(float volume_dB)
317 {
318 	CALLED();
319 	_m_lock.Lock();
320 	_m_volume = pow(10.0f,volume_dB / 20.0f);
321 	_m_lock.Unlock();
322 }
323 
324 
325 status_t
326 BSoundPlayer::GetVolumeInfo(media_node *out_node,
327 							int32 *out_parameter,
328 							float *out_min_dB,
329 							float *out_max_dB)
330 {
331 	BROKEN();
332 
333 	*out_node = m_output.node;
334 	*out_parameter = -1; /* is the parameter ID for the volume control */
335 	*out_min_dB = minDB;
336 	*out_max_dB = maxDB;
337 
338 	return B_OK;
339 }
340 
341 
342 bigtime_t
343 BSoundPlayer::Latency()
344 {
345 	BROKEN();
346 	return 50000;
347 }
348 
349 
350 /* virtual */ bool
351 BSoundPlayer::HasData()
352 {
353 	CALLED();
354 
355 	return _m_has_data != 0;
356 }
357 
358 
359 void
360 BSoundPlayer::SetHasData(bool has_data)
361 {
362 	CALLED();
363 	_m_lock.Lock();
364 	_m_has_data = has_data ? 1 : 0;
365 	_m_lock.Unlock();
366 }
367 
368 
369 /*************************************************************
370  * protected BSoundPlayer
371  *************************************************************/
372 
373 //final
374 void
375 BSoundPlayer::SetInitError(status_t in_error)
376 {
377 	CALLED();
378 	_m_init_err = in_error;
379 }
380 
381 
382 /*************************************************************
383  * private BSoundPlayer
384  *************************************************************/
385 
386 status_t BSoundPlayer::_Reserved_SoundPlayer_0(void *, ...) { return B_ERROR; }
387 status_t BSoundPlayer::_Reserved_SoundPlayer_1(void *, ...) { return B_ERROR; }
388 status_t BSoundPlayer::_Reserved_SoundPlayer_2(void *, ...) { return B_ERROR; }
389 status_t BSoundPlayer::_Reserved_SoundPlayer_3(void *, ...) { return B_ERROR; }
390 status_t BSoundPlayer::_Reserved_SoundPlayer_4(void *, ...) { return B_ERROR; }
391 status_t BSoundPlayer::_Reserved_SoundPlayer_5(void *, ...) { return B_ERROR; }
392 status_t BSoundPlayer::_Reserved_SoundPlayer_6(void *, ...) { return B_ERROR; }
393 status_t BSoundPlayer::_Reserved_SoundPlayer_7(void *, ...) { return B_ERROR; }
394 
395 
396 void
397 BSoundPlayer::NotifySoundDone(play_id sound,
398 							  bool got_to_play)
399 {
400 	UNIMPLEMENTED();
401 }
402 
403 
404 void
405 BSoundPlayer::get_volume_slider()
406 {
407 	UNIMPLEMENTED();
408 }
409 
410 void
411 BSoundPlayer::Init(
412 					const media_node * node,
413 					const media_multi_audio_format * format,
414 					const char * name,
415 					const media_input * input,
416 					void (*PlayBuffer)(void *, void * buffer, size_t size, const media_raw_audio_format & format),
417 					void (*Notifier)(void *, sound_player_notification what, ...),
418 					void * cookie)
419 {
420 	BROKEN();
421 	_m_node = NULL;
422 	_m_sounds = NULL;
423 	_m_waiting = NULL;
424 	_PlayBuffer = PlayBuffer;
425 	_Notifier = Notifier;
426 	//_m_lock;
427 	_m_volume = 0.0f;
428 	//m_input;
429 	//m_output;
430 	_m_mix_buffer = 0;
431 	_m_mix_buffer_size = 0;
432 	_m_cookie = cookie;
433 	_m_buf = NULL;
434 	_m_bufsize = 0;
435 	_m_has_data = 0;
436 	_m_init_err = B_ERROR;
437 	_m_perfTime = 0;
438 	_m_volumeSlider = NULL;
439 	_m_gotVolume = 0;
440 
441 	_m_node = 0;
442 
443 #if 0 /* we don't have a media roster, or real media nodes yet */
444 	status_t status;
445 	BMediaRoster *roster;
446 	media_node outnode;
447 	roster = BMediaRoster::Roster();
448 	if (!roster) {
449 		TRACE("BSoundPlayer::Init: Couldn't get BMediaRoster\n");
450 		return;
451 	}
452 
453 	//connect our producer node either to the
454 	//system mixer or to the supplied out node
455 	if (!node) {
456 		status = roster->GetAudioMixer(&outnode);
457 		if (status != B_OK) {
458 			TRACE("BSoundPlayer::Init: Couldn't GetAudioMixer\n");
459 			SetInitError(status);
460 			return;
461 		}
462 		node = &outnode;
463 	}
464 #endif
465 
466 	media_multi_audio_format fmt;
467 	memcpy(&fmt,format,sizeof(fmt));
468 
469 	if (fmt.frame_rate == media_multi_audio_format::wildcard.frame_rate)
470 		fmt.frame_rate = 44100.0f;
471 	if (fmt.channel_count == media_multi_audio_format::wildcard.channel_count)
472 		fmt.channel_count = 2;
473 	if (fmt.format == media_multi_audio_format::wildcard.format)
474 		fmt.format = media_raw_audio_format::B_AUDIO_FLOAT;
475 	if (fmt.byte_order == media_multi_audio_format::wildcard.byte_order)
476 		fmt.byte_order = B_MEDIA_HOST_ENDIAN;
477 	if (fmt.buffer_size == media_multi_audio_format::wildcard.buffer_size)
478 		fmt.buffer_size = 4096;
479 
480 	if (fmt.channel_count != 1 && fmt.channel_count != 2)
481 		debugger("BSoundPlayer: not a 1 or 2 channel audio format\n");
482 	if (fmt.frame_rate <= 0.0f)
483 		debugger("BSoundPlayer: framerate must be > 0\n");
484 
485 	_m_bufsize = fmt.buffer_size;
486 	_m_buf = new char[_m_bufsize];
487 	_m_node = new _SoundPlayNode(name,&fmt,this);
488 
489 
490 /*
491 	m_input = ;
492 	m_output = ;
493 
494 
495 tryFormat = fileAudioOutput.format;
496    err = roster->Connect(fileAudioOutput.source, audioInput.destination,
497                &tryFormat, &m_output, &m_input);
498 
499 
500  err = roster->GetStartLatencyFor(timeSourceNode, &startTime);
501    startTime += b_timesource->PerformanceTimeFor(BTimeSource::RealTime()
502                + 1000000 / 50);
503    
504    err = roster->StartNode(mediaFileNode, startTime);
505    err = roster->StartNode(codecNode, startTime);
506    err = roster->StartNode(videoNode, startTime);
507 
508 */
509 
510 	SetInitError(B_OK);
511 }
512 
513 /* virtual */ void
514 BSoundPlayer::Notify(sound_player_notification what,
515 					 ...)
516 {
517 	CALLED();
518 	_m_lock.Lock();
519 	if (_Notifier)
520 		(*_Notifier)(_m_cookie,what);
521 	else {
522 	}
523 	_m_lock.Unlock();
524 }
525 
526 
527 /* virtual */ void
528 BSoundPlayer::PlayBuffer(void *buffer,
529 						 size_t size,
530 						 const media_raw_audio_format &format)
531 {
532 //	CALLED();
533 	_m_lock.Lock();
534 	if (_PlayBuffer)
535 		(*_PlayBuffer)(_m_cookie,buffer,size,format);
536 	else {
537 	}
538 	_m_lock.Unlock();
539 }
540 
541 
542