Skip to content

Commit e868465

Browse files
committed
Tweak test_loopback.cpp to have it pass on newer Windows + newer VB-cable
1 parent 0942f63 commit e868465

1 file changed

Lines changed: 43 additions & 7 deletions

File tree

test/test_loopback.cpp

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ const uint32_t TONE_FREQUENCY = 440;
2828
const double OUTPUT_AMPLITUDE = 0.25;
2929
const int32_t NUM_FRAMES_TO_OUTPUT =
3030
SAMPLE_FREQUENCY / 20; /* play ~50ms of samples */
31+
/* data_cb_playback() loops the tone long enough for delayed loopback capture,
32+
* then goes silent before render stop. The tests keep capturing after render
33+
* stop to consume queued virtual-device data. */
34+
const int32_t CONTINUOUS_TONE_FRAMES = SAMPLE_FREQUENCY / 2; /* ~500ms */
35+
const unsigned int LOOPBACK_PLAY_MS = 600;
36+
const unsigned int LOOPBACK_DRAIN_MS = 600;
3137

3238
template <typename T>
3339
T
@@ -266,11 +272,11 @@ data_cb_playback(cubeb_stream * stream, void * user, const void * inputbuffer,
266272
}
267273

268274
std::lock_guard<std::mutex> lock(u->user_state_mutex);
269-
/* generate our test tone on the fly */
275+
/* Generate the tone long enough for loopback capture streams whose first
276+
* buffer can arrive late; find_phase() searches wherever it lands. */
270277
for (int i = 0; i < nframes; i++) {
271278
double tone = 0.0;
272-
if (u->position + i < NUM_FRAMES_TO_OUTPUT) {
273-
/* generate sine wave */
279+
if (u->position + i < CONTINUOUS_TONE_FRAMES) {
274280
tone =
275281
sin(2 * M_PI * (i + u->position) * TONE_FREQUENCY / SAMPLE_FREQUENCY);
276282
tone *= OUTPUT_AMPLITUDE;
@@ -452,11 +458,26 @@ run_loopback_separate_streams_test(bool is_float)
452458
std::unique_ptr<cubeb_stream, decltype(&cubeb_stream_destroy)>
453459
cleanup_output_stream_at_exit(output_stream, cubeb_stream_destroy);
454460

455-
cubeb_stream_start(input_stream);
461+
// Start the render stream before the loopback capture stream, matching
462+
// the order cubeb_wasapi.cpp uses internally for a single duplex stream.
463+
// Some virtual audio drivers (e.g. VB-CABLE) only start relaying audio to
464+
// their loopback/capture side once a render client is active, and never
465+
// catch up if the capture side starts first.
456466
cubeb_stream_start(output_stream);
457-
delay(300);
467+
cubeb_stream_start(input_stream);
468+
// Give the capture side extra margin to receive its first buffer under
469+
// slow/instrumented builds (e.g. ASAN), on top of the continuous tone above.
470+
delay(LOOPBACK_PLAY_MS);
458471
cubeb_stream_stop(output_stream);
472+
// Keep capturing after render stops, so a virtual loopback device can
473+
// deliver any queued render data to this test instead of the next one.
474+
delay(LOOPBACK_DRAIN_MS);
459475
cubeb_stream_stop(input_stream);
476+
// Destroy the streams (and the context) right away instead of waiting
477+
// for the RAII cleanups below to do it when this function returns.
478+
cleanup_output_stream_at_exit.reset();
479+
cleanup_input_stream_at_exit.reset();
480+
cleanup_cubeb_at_exit.reset();
460481

461482
/* access after stop should not happen, but lock just in case and to appease
462483
* sanitization tools */
@@ -641,11 +662,26 @@ run_loopback_device_selection_test(bool is_float)
641662
std::unique_ptr<cubeb_stream, decltype(&cubeb_stream_destroy)>
642663
cleanup_output_stream_at_exit(output_stream, cubeb_stream_destroy);
643664

644-
cubeb_stream_start(input_stream);
665+
// Start the render stream before the loopback capture stream, matching
666+
// the order cubeb_wasapi.cpp uses internally for a single duplex stream.
667+
// Some virtual audio drivers (e.g. VB-CABLE) only start relaying audio to
668+
// their loopback/capture side once a render client is active, and never
669+
// catch up if the capture side starts first.
645670
cubeb_stream_start(output_stream);
646-
delay(300);
671+
cubeb_stream_start(input_stream);
672+
// Give the capture side extra margin to receive its first buffer under
673+
// slow/instrumented builds (e.g. ASAN), on top of the continuous tone above.
674+
delay(LOOPBACK_PLAY_MS);
647675
cubeb_stream_stop(output_stream);
676+
// Keep capturing after render stops, so a virtual loopback device can
677+
// deliver any queued render data to this test instead of the next one.
678+
delay(LOOPBACK_DRAIN_MS);
648679
cubeb_stream_stop(input_stream);
680+
// Destroy the streams (and the context) right away instead of waiting
681+
// for the RAII cleanups below to do it when this function returns.
682+
cleanup_output_stream_at_exit.reset();
683+
cleanup_input_stream_at_exit.reset();
684+
cleanup_cubeb_at_exit.reset();
649685

650686
/* access after stop should not happen, but lock just in case and to appease
651687
* sanitization tools */

0 commit comments

Comments
 (0)