Changeset 90723 in vbox for trunk/src/VBox/ValidationKit/utils/audio/vkatCmdGeneric.cpp
- Timestamp:
- Aug 18, 2021 3:41:36 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/utils/audio/vkatCmdGeneric.cpp
r90087 r90723 31 31 #include <iprt/errcore.h> 32 32 #include <iprt/message.h> 33 #include <iprt/rand.h> 33 34 #include <iprt/test.h> 34 35 … … 366 367 } 367 368 369 /** 370 * Worker for audioTestCmdPlayHandler that plays one test tone. 371 */ 372 static RTEXITCODE audioTestPlayTestToneOne(PAUDIOTESTTONEPARMS pToneParms, 373 PCPDMDRVREG pDrvReg, const char *pszDevId, uint32_t cMsBufferSize, 374 uint32_t cMsPreBuffer, uint32_t cMsSchedulingHint, 375 uint8_t cChannels, uint8_t cbSample, uint32_t uHz, 376 bool fWithDrvAudio, bool fWithMixer) 377 { 378 char szTmp[128]; 379 380 AUDIOTESTSTREAM TstStream; 381 RT_ZERO(TstStream); 382 383 /* 384 * Construct the driver stack. 385 */ 386 RTEXITCODE rcExit = RTEXITCODE_FAILURE; 387 AUDIOTESTDRVSTACK DrvStack; 388 int rc = audioTestDriverStackInit(&DrvStack, pDrvReg, fWithDrvAudio); 389 if (RT_SUCCESS(rc)) 390 { 391 /* 392 * Set the output device if one is specified. 393 */ 394 rc = audioTestDriverStackSetDevice(&DrvStack, PDMAUDIODIR_OUT, pszDevId); 395 if (RT_SUCCESS(rc)) 396 { 397 /* 398 * Open a stream for the output. 399 */ 400 PDMAUDIOPCMPROPS ReqProps = pToneParms->Props; 401 if (cChannels != 0 && PDMAudioPropsChannels(&ReqProps) != cChannels) 402 PDMAudioPropsSetChannels(&ReqProps, cChannels); 403 if (cbSample != 0) 404 PDMAudioPropsSetSampleSize(&ReqProps, cbSample); 405 if (uHz != 0) 406 ReqProps.uHz = uHz; 407 408 rc = audioTestDriverStackStreamCreateOutput(&DrvStack, &ReqProps, cMsBufferSize, 409 cMsPreBuffer, cMsSchedulingHint, &TstStream.pStream, &TstStream.Cfg); 410 if (RT_SUCCESS(rc)) 411 { 412 /* 413 * Automatically enable the mixer if the wave file and the 414 * output parameters doesn't match. 415 */ 416 if ( !fWithMixer 417 && !PDMAudioPropsAreEqual(&pToneParms->Props, &TstStream.pStream->Cfg.Props)) 418 { 419 RTMsgInfo("Enabling the mixer buffer.\n"); 420 fWithMixer = true; 421 } 422 423 /* 424 * Create a mixer wrapper. This is just a thin wrapper if fWithMixer 425 * is false, otherwise it's doing mixing, resampling and recoding. 426 */ 427 rc = AudioTestMixStreamInit(&TstStream.Mix, &DrvStack, TstStream.pStream, fWithMixer ? &pToneParms->Props : NULL, 100 /*ms*/); 428 if (RT_SUCCESS(rc)) 429 { 430 if (g_uVerbosity > 0) 431 RTMsgInfo("Stream: %s cbBackend=%#RX32%s\n", 432 PDMAudioPropsToString(&TstStream.pStream->Cfg.Props, szTmp, sizeof(szTmp)), 433 TstStream.pStream->cbBackend, fWithMixer ? " mixed" : ""); 434 435 /* 436 * Enable the stream and start playing. 437 */ 438 rc = AudioTestMixStreamEnable(&TstStream.Mix); 439 if (RT_SUCCESS(rc)) 440 { 441 rc = audioTestPlayTone(NULL /* pTstEnv */, &TstStream, pToneParms); 442 if (RT_SUCCESS(rc)) 443 rcExit = RTEXITCODE_SUCCESS; 444 } 445 else 446 rcExit = RTMsgErrorExitFailure("Enabling the output stream failed: %Rrc", rc); 447 448 /* 449 * Clean up. 450 */ 451 AudioTestMixStreamTerm(&TstStream.Mix); 452 } 453 audioTestDriverStackStreamDestroy(&DrvStack, TstStream.pStream); 454 } 455 else 456 rcExit = RTMsgErrorExitFailure("Creating output stream failed: %Rrc", rc); 457 } 458 else 459 rcExit = RTMsgErrorExitFailure("Failed to set output device to '%s': %Rrc", pszDevId, rc); 460 audioTestDriverStackDelete(&DrvStack); 461 } 462 else 463 rcExit = RTMsgErrorExitFailure("Driver stack construction failed: %Rrc", rc); 464 return rcExit; 465 } 466 368 467 369 468 /** … … 377 476 { "--frequency", 'f', RTGETOPT_REQ_UINT32 }, 378 477 { "--sample-size", 'z', RTGETOPT_REQ_UINT8 }, 478 { "--test-tone", 't', RTGETOPT_REQ_NOTHING }, 379 479 { "--output-device", 'o', RTGETOPT_REQ_STRING }, 380 480 { "--with-drv-audio", 'd', RTGETOPT_REQ_NOTHING }, … … 388 488 switch (pOpt->iShort) 389 489 { 390 case 'b': return "The audio backend to use .";490 case 'b': return "The audio backend to use"; 391 491 case 'c': return "Number of backend output channels"; 392 case 'd': return "Go via DrvAudio instead of directly interfacing with the backend .";492 case 'd': return "Go via DrvAudio instead of directly interfacing with the backend"; 393 493 case 'f': return "Output frequency (Hz)"; 394 494 case 'z': return "Output sample size (bits)"; 395 case 'm': return "Go via the mixer."; 396 case 'o': return "The ID of the output device to use."; 495 case 't': return "Plays a test tone. Can be specified multiple times"; 496 case 'm': return "Go via the mixer"; 497 case 'o': return "The ID of the output device to use"; 397 498 default: return NULL; 398 499 } … … 416 517 bool fWithDrvAudio = false; 417 518 bool fWithMixer = false; 519 uint32_t cTestTones = 0; 418 520 uint8_t cbSample = 0; 419 521 uint8_t cChannels = 0; … … 453 555 break; 454 556 557 case 't': 558 cTestTones++; 559 break; 560 455 561 case 'z': 456 562 cbSample = ValueUnion.u8 / 8; … … 459 565 case VINF_GETOPT_NOT_OPTION: 460 566 { 567 if (cTestTones) 568 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Playing test tones (-t) cannot be combined with playing files"); 569 461 570 RTEXITCODE rcExit = audioTestPlayOne(ValueUnion.psz, pDrvReg, pszDevId, cMsBufferSize, cMsPreBuffer, 462 571 cMsSchedulingHint, cChannels, cbSample, uHz, fWithDrvAudio, fWithMixer); … … 472 581 } 473 582 } 583 584 while (cTestTones--) 585 { 586 AUDIOTESTTONEPARMS ToneParms; 587 RT_ZERO(ToneParms); 588 589 /* Use some sane defaults if no PCM props are set by the user. */ 590 PDMAudioPropsInit(&ToneParms.Props, 591 cbSample ? cbSample : 4, true /* fSigned */, cChannels ? cChannels : 2, uHz ? uHz : 44100); 592 593 ToneParms.dbFreqHz = AudioTestToneGetRandomFreq(); 594 ToneParms.msPrequel = 0; /** @todo Implement analyzing this first! */ 595 #ifdef DEBUG_andy 596 ToneParms.msDuration = RTRandU32Ex(50, 2500); 597 #else 598 ToneParms.msDuration = RTRandU32Ex(0, RT_MS_10SEC); /** @todo Probably a bit too long, but let's see. */ 599 #endif 600 ToneParms.msSequel = 0; /** @todo Implement analyzing this first! */ 601 ToneParms.uVolumePercent = 100; /** @todo Implement analyzing this first! */ 602 603 RTEXITCODE rcExit = audioTestPlayTestToneOne(&ToneParms, pDrvReg, pszDevId, cMsBufferSize, cMsPreBuffer, 604 cMsSchedulingHint, cChannels, cbSample, uHz, fWithDrvAudio, fWithMixer); 605 if (rcExit != RTEXITCODE_SUCCESS) 606 return rcExit; 607 } 608 474 609 return RTEXITCODE_SUCCESS; 475 610 }
Note:
See TracChangeset
for help on using the changeset viewer.