1 // AudioAdapterNode.cpp 2 3 #include "AudioAdapterNode.h" 4 #include "AudioAdapterParams.h" 5 6 #include "SoundUtils.h" 7 8 #include <cstdio> 9 #include <cstring> 10 11 // -------------------------------------------------------- // 12 // ctor/dtor 13 // -------------------------------------------------------- // 14 15 _AudioAdapterNode::~_AudioAdapterNode() {} 16 17 _AudioAdapterNode::_AudioAdapterNode( 18 const char* name, 19 IAudioOpFactory* opFactory, 20 BMediaAddOn* addOn) : 21 22 BMediaNode(name), 23 AudioFilterNode(name, opFactory, addOn) { 24 25 // PRINT(( 26 // "\n" 27 // "--*-- _AudioAdapterNode() [%s] --*--\n\n", 28 // __BUILD_DATE__)); 29 } 30 31 // -------------------------------------------------------- // 32 // AudioFilterNode 33 // -------------------------------------------------------- // 34 35 status_t _AudioAdapterNode::getRequiredInputFormat( 36 media_format& ioFormat) { 37 38 status_t err = getPreferredInputFormat(ioFormat); 39 if(err < B_OK) 40 return err; 41 42 // 16sep99: input byte-swapping now supported 43 ioFormat.u.raw_audio.byte_order = media_raw_audio_format::wildcard.byte_order; 44 45 // ioFormat.u.raw_audio.format = media_raw_audio_format::wildcard.format; 46 // ioFormat.u.raw_audio.channel_count = media_raw_audio_format::wildcard.channel_count; 47 _AudioAdapterParams* p = dynamic_cast<_AudioAdapterParams*>(parameterSet()); 48 ASSERT(p); 49 50 // media_raw_audio_format& w = media_raw_audio_format::wildcard; 51 52 // copy user preferences 53 ioFormat.u.raw_audio.format = p->inputFormat.format; 54 ioFormat.u.raw_audio.channel_count = p->inputFormat.channel_count; 55 56 57 // don't require a buffer size until format & channel_count are known [16sep99] 58 ioFormat.u.raw_audio.buffer_size = media_raw_audio_format::wildcard.buffer_size; 59 60 if(output().destination == media_destination::null) { 61 // frame rate isn't constrained yet 62 ioFormat.u.raw_audio.frame_rate = media_raw_audio_format::wildcard.frame_rate; 63 } 64 65 return B_OK; 66 } 67 68 // +++++ 17sep99: use parameter data! 69 70 status_t _AudioAdapterNode::getPreferredInputFormat( 71 media_format& ioFormat) { 72 73 status_t err = _inherited::getPreferredInputFormat(ioFormat); 74 if(err < B_OK) 75 return err; 76 77 _AudioAdapterParams* p = dynamic_cast<_AudioAdapterParams*>(parameterSet()); 78 ASSERT(p); 79 80 media_raw_audio_format& f = ioFormat.u.raw_audio; 81 media_raw_audio_format& w = media_raw_audio_format::wildcard; 82 83 // copy user preferences 84 if(p->inputFormat.format != w.format) 85 f.format = p->inputFormat.format; 86 if(p->inputFormat.channel_count != w.channel_count) 87 f.channel_count = p->inputFormat.channel_count; 88 89 // // if one end is connected, prefer not to do channel conversions [15sep99] 90 // if(output().destination != media_destination::null) 91 // ioFormat.u.raw_audio.channel_count = output().format.u.raw_audio.channel_count; 92 93 // if output connected, constrain: 94 // buffer_size 95 // frame_rate 96 if(output().destination != media_destination::null) { 97 // if the user doesn't care, default to the output's frame format 98 if(f.format == w.format) 99 f.format = output().format.u.raw_audio.format; 100 if(f.channel_count == w.channel_count) 101 f.channel_count = output().format.u.raw_audio.channel_count; 102 103 f.buffer_size = 104 bytes_per_frame(f) * 105 frames_per_buffer(output().format.u.raw_audio); 106 f.frame_rate = output().format.u.raw_audio.frame_rate; 107 } 108 109 return B_OK; 110 } 111 112 status_t _AudioAdapterNode::getRequiredOutputFormat( 113 media_format& ioFormat) { 114 115 status_t err = getPreferredOutputFormat(ioFormat); 116 if(err < B_OK) 117 return err; 118 119 ioFormat.u.raw_audio.format = media_raw_audio_format::wildcard.format; 120 ioFormat.u.raw_audio.channel_count = media_raw_audio_format::wildcard.channel_count; 121 122 _AudioAdapterParams* p = dynamic_cast<_AudioAdapterParams*>(parameterSet()); 123 ASSERT(p); 124 125 // media_raw_audio_format& w = media_raw_audio_format::wildcard; 126 127 // copy user preferences 128 ioFormat.u.raw_audio.format = p->outputFormat.format; 129 ioFormat.u.raw_audio.channel_count = p->outputFormat.channel_count; 130 131 // don't require a buffer size until format & channel_count are known [16sep99] 132 ioFormat.u.raw_audio.buffer_size = media_raw_audio_format::wildcard.buffer_size; 133 134 if(input().source == media_source::null) { 135 // frame rate isn't constrained yet 136 ioFormat.u.raw_audio.frame_rate = media_raw_audio_format::wildcard.frame_rate; 137 } 138 139 return B_OK; 140 } 141 142 // +++++ 17sep99: use parameter data! 143 144 status_t _AudioAdapterNode::getPreferredOutputFormat( 145 media_format& ioFormat) { 146 147 status_t err = _inherited::getPreferredOutputFormat(ioFormat); 148 if(err < B_OK) 149 return err; 150 151 _AudioAdapterParams* p = dynamic_cast<_AudioAdapterParams*>(parameterSet()); 152 ASSERT(p); 153 154 media_raw_audio_format& w = media_raw_audio_format::wildcard; 155 156 // copy user preferences 157 if(p->outputFormat.format != w.format) 158 ioFormat.u.raw_audio.format = p->outputFormat.format; 159 if(p->outputFormat.channel_count != w.channel_count) 160 ioFormat.u.raw_audio.channel_count = p->outputFormat.channel_count; 161 162 //// // if one end is connected, prefer not to do channel conversions [15sep99] 163 //// if(input().source != media_source::null) 164 //// ioFormat.u.raw_audio.channel_count = input().format.u.raw_audio.channel_count; 165 166 // if input connected, constrain: 167 // buffer_size 168 // frame_rate 169 if(input().source != media_source::null) { 170 // if the user doesn't care, default to the input's frame format 171 if(ioFormat.u.raw_audio.format == w.format) 172 ioFormat.u.raw_audio.format = input().format.u.raw_audio.format; 173 if(ioFormat.u.raw_audio.channel_count == w.channel_count) 174 ioFormat.u.raw_audio.channel_count = input().format.u.raw_audio.channel_count; 175 176 ioFormat.u.raw_audio.buffer_size = 177 bytes_per_frame(ioFormat.u.raw_audio) * 178 frames_per_buffer(input().format.u.raw_audio); 179 PRINT(("##### preferred output buffer_size: %ld (%x)\n", ioFormat.u.raw_audio.buffer_size, ioFormat.u.raw_audio.buffer_size)); 180 ioFormat.u.raw_audio.frame_rate = input().format.u.raw_audio.frame_rate; 181 182 } 183 184 185 return B_OK; 186 } 187 188 status_t _AudioAdapterNode::validateProposedInputFormat( 189 const media_format& preferredFormat, 190 media_format& ioProposedFormat) { 191 192 status_t err = _inherited::validateProposedInputFormat( 193 preferredFormat, ioProposedFormat); 194 195 media_raw_audio_format& w = media_raw_audio_format::wildcard; 196 197 if(output().destination != media_destination::null) { 198 199 // an output connection exists; constrain the input format 200 201 // is there enough information to suggest a buffer size? 202 if( 203 ioProposedFormat.u.raw_audio.format != w.format && 204 ioProposedFormat.u.raw_audio.channel_count != w.channel_count) { 205 206 size_t target_buffer_size = 207 bytes_per_frame(ioProposedFormat.u.raw_audio) * 208 frames_per_buffer(output().format.u.raw_audio); 209 210 if(ioProposedFormat.u.raw_audio.buffer_size != target_buffer_size) { 211 if(ioProposedFormat.u.raw_audio.buffer_size != w.buffer_size) 212 err = B_MEDIA_BAD_FORMAT; 213 214 ioProposedFormat.u.raw_audio.buffer_size = target_buffer_size; 215 } 216 } 217 218 // require output frame rate 219 if(ioProposedFormat.u.raw_audio.frame_rate != output().format.u.raw_audio.frame_rate) { 220 if(ioProposedFormat.u.raw_audio.frame_rate != w.frame_rate) 221 err = B_MEDIA_BAD_FORMAT; 222 223 ioProposedFormat.u.raw_audio.frame_rate = output().format.u.raw_audio.frame_rate; 224 } 225 } 226 227 char fmt_string[256]; 228 string_for_format(ioProposedFormat, fmt_string, 255); 229 PRINT(( 230 "### _AudioAdapterNode::validateProposedInputFormat():\n" 231 " %s\n", fmt_string)); 232 return err; 233 } 234 235 status_t _AudioAdapterNode::validateProposedOutputFormat( 236 const media_format& preferredFormat, 237 media_format& ioProposedFormat) { 238 239 status_t err = _inherited::validateProposedOutputFormat( 240 preferredFormat, ioProposedFormat); 241 242 media_raw_audio_format& w = media_raw_audio_format::wildcard; 243 244 if(input().source != media_source::null) { 245 246 // an input connection exists; constrain the output format 247 248 // is there enough information to suggest a buffer size? 249 if( 250 ioProposedFormat.u.raw_audio.format != w.format && 251 ioProposedFormat.u.raw_audio.channel_count != w.channel_count) { 252 253 size_t target_buffer_size = 254 bytes_per_frame(ioProposedFormat.u.raw_audio) * 255 frames_per_buffer(input().format.u.raw_audio); 256 257 if(ioProposedFormat.u.raw_audio.buffer_size != target_buffer_size) { 258 if(ioProposedFormat.u.raw_audio.buffer_size != w.buffer_size) 259 err = B_MEDIA_BAD_FORMAT; 260 261 ioProposedFormat.u.raw_audio.buffer_size = target_buffer_size; 262 } 263 } 264 265 // require same frame rate as input 266 if(ioProposedFormat.u.raw_audio.frame_rate != input().format.u.raw_audio.frame_rate) { 267 if(ioProposedFormat.u.raw_audio.frame_rate != w.frame_rate) 268 err = B_MEDIA_BAD_FORMAT; 269 270 ioProposedFormat.u.raw_audio.frame_rate = input().format.u.raw_audio.frame_rate; 271 } 272 } 273 274 char fmt_string[256]; 275 string_for_format(ioProposedFormat, fmt_string, 255); 276 PRINT(( 277 "### _AudioAdapterNode::validateProposedOutputFormat():\n" 278 " %s\n", fmt_string)); 279 return err; 280 } 281 282 void 283 _AudioAdapterNode::SetParameterValue(int32 id, bigtime_t changeTime, const void *value, size_t size) 284 { 285 switch(id) { 286 case _AudioAdapterParams::P_INPUT_FORMAT: 287 if(input().source != media_source::null) { 288 media_multi_audio_format f = input().format.u.raw_audio; 289 if(size != 4) 290 return; 291 f.format = *(uint32*)value; 292 _attemptInputFormatChange(f); 293 return; 294 } 295 break; 296 case _AudioAdapterParams::P_INPUT_CHANNEL_COUNT: 297 if(input().source != media_source::null) { 298 media_multi_audio_format f = input().format.u.raw_audio; 299 if(size != 4) 300 return; 301 f.channel_count = *(uint32*)value; 302 _attemptInputFormatChange(f); 303 return; 304 } 305 break; 306 case _AudioAdapterParams::P_OUTPUT_FORMAT: 307 if(output().source != media_source::null) { 308 media_multi_audio_format f = output().format.u.raw_audio; 309 if(size != 4) 310 return; 311 f.format = *(uint32*)value; 312 _attemptOutputFormatChange(f); 313 return; 314 } 315 break; 316 case _AudioAdapterParams::P_OUTPUT_CHANNEL_COUNT: 317 if(output().source != media_source::null) { 318 media_multi_audio_format f = output().format.u.raw_audio; 319 if(size != 4) 320 return; 321 f.channel_count = *(uint32*)value; 322 _attemptOutputFormatChange(f); 323 return; 324 } 325 break; 326 } 327 328 return _inherited::SetParameterValue(id, changeTime, value, size); 329 } 330 331 332 // -------------------------------------------------------- // 333 // BBufferProducer/Consumer 334 // -------------------------------------------------------- // 335 336 status_t _AudioAdapterNode::Connected( 337 const media_source& source, 338 const media_destination& destination, 339 const media_format& format, 340 media_input* outInput) { 341 342 status_t err = _inherited::Connected( 343 source, destination, format, outInput); 344 345 if(err == B_OK) { 346 _AudioAdapterParams* p = dynamic_cast<_AudioAdapterParams*>(parameterSet()); 347 ASSERT(p); 348 p->inputFormat = format.u.raw_audio; 349 350 _broadcastInputFormatParams(); 351 } 352 353 return err; 354 } 355 356 void _AudioAdapterNode::Connect( 357 status_t status, 358 const media_source& source, 359 const media_destination& destination, 360 const media_format& format, 361 char* ioName) { 362 363 if(status == B_OK) { 364 _AudioAdapterParams* p = dynamic_cast<_AudioAdapterParams*>(parameterSet()); 365 ASSERT(p); 366 p->outputFormat = format.u.raw_audio; 367 368 _broadcastOutputFormatParams(); 369 } 370 371 _inherited::Connect( 372 status, source, destination, format, ioName); 373 } 374 375 376 void _AudioAdapterNode::_attemptInputFormatChange( 377 const media_multi_audio_format& format) { 378 // +++++ 379 380 char fmtString[256]; 381 media_format f; 382 f.type = B_MEDIA_RAW_AUDIO; 383 f.u.raw_audio = format; 384 string_for_format(f, fmtString, 256); 385 PRINT(( 386 "_AudioAdapterNode::attemptInputFormatChange():\n '%s'\n", 387 fmtString)); 388 389 390 391 // +++++ reject attempt: broadcast params for current format 392 _broadcastInputFormatParams(); 393 } 394 395 void _AudioAdapterNode::_attemptOutputFormatChange( 396 const media_multi_audio_format& format) { 397 398 // +++++ 399 char fmtString[256]; 400 media_format f; 401 f.type = B_MEDIA_RAW_AUDIO; 402 f.u.raw_audio = format; 403 string_for_format(f, fmtString, 256); 404 PRINT(( 405 "_AudioAdapterNode::attemptOutputFormatChange():\n '%s'\n", 406 fmtString)); 407 408 media_destination dest = output().destination; 409 if(dest == media_destination::null) { 410 PRINT(( 411 "! output not connected!\n")); 412 return; 413 } 414 415 _AudioAdapterParams* p = dynamic_cast<_AudioAdapterParams*>(parameterSet()); 416 ASSERT(p); 417 status_t err; 418 419 // disallow wildcards 420 if(format.format == media_raw_audio_format::wildcard.format || 421 format.channel_count == media_raw_audio_format::wildcard.channel_count) { 422 PRINT(( 423 "! wildcards not allowed\n")); 424 goto broadcast; 425 } 426 427 err = prepareFormatChange(f); 428 if(err < B_OK) 429 { 430 PRINT(( 431 "! format not supported\n")); 432 goto broadcast; 433 } 434 435 err = ProposeFormatChange(&f, dest); 436 if(err < B_OK) 437 { 438 PRINT(( 439 "! format rejected\n")); 440 goto broadcast; 441 } 442 443 err = ChangeFormat( 444 output().source, 445 dest, 446 &f); 447 448 if(err < B_OK) { 449 PRINT(("! ChangeFormat(): %s\n", strerror(err))); 450 goto broadcast; 451 } 452 453 // store new format 454 p->outputFormat = format; 455 456 // inform AudioFilterNode of format change 457 doFormatChange(f); 458 459 broadcast: 460 _broadcastOutputFormatParams(); 461 } 462 463 464 void 465 _AudioAdapterNode::_broadcastInputFormatParams() 466 { 467 PRINT(("_AudioAdapterNode::_broadcastInputFormatParams()\n")); 468 BroadcastNewParameterValue( 469 0LL, 470 _AudioAdapterParams::P_INPUT_FORMAT, 471 (void*)&input().format.u.raw_audio.format, 472 4); 473 BroadcastNewParameterValue( 474 0LL, 475 _AudioAdapterParams::P_INPUT_CHANNEL_COUNT, 476 (void*)&input().format.u.raw_audio.channel_count, 477 4); 478 // BroadcastChangedParameter(_AudioAdapterParams::P_INPUT_FORMAT); 479 // BroadcastChangedParameter(_AudioAdapterParams::P_INPUT_CHANNEL_COUNT); 480 } 481 482 void 483 _AudioAdapterNode::_broadcastOutputFormatParams() 484 { 485 PRINT(("_AudioAdapterNode::_broadcastOutputFormatParams()\n")); 486 487 BroadcastNewParameterValue( 488 0LL, 489 _AudioAdapterParams::P_OUTPUT_FORMAT, 490 (void*)&output().format.u.raw_audio.format, 491 4); 492 BroadcastNewParameterValue( 493 0LL, 494 _AudioAdapterParams::P_OUTPUT_CHANNEL_COUNT, 495 (void*)&output().format.u.raw_audio.channel_count, 496 4); 497 // BroadcastChangedParameter(_AudioAdapterParams::P_OUTPUT_FORMAT); 498 // BroadcastChangedParameter(_AudioAdapterParams::P_OUTPUT_CHANNEL_COUNT); 499 } 500 501 502 503 // END -- AudioAdapterNode.cpp -- 504