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