blob: 37c7e3921bb12dbaf2652dfed4e4a7c66d590f72 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "intel-hda/utils/utils.h"
#include <lib/sync/completion.h>
#include <zircon/errors.h>
#include <string>
#include <thread>
#include <zxtest/zxtest.h>
namespace audio::intel_hda {
namespace {
class AutoAdvancingClock : public Clock {
public:
zx::time Now() { return now_; }
void SleepUntil(zx::time time) { now_ = std::max(now_, time); }
void AdvanceTime(zx::duration duration) { now_ = now_ + duration; }
private:
zx::time now_{};
};
TEST(WaitCondition, AlwaysTrue) {
EXPECT_OK(WaitCondition(ZX_USEC(0), ZX_USEC(0), []() { return true; }));
}
TEST(WaitCondition, AlwaysFalse) {
EXPECT_EQ(WaitCondition(ZX_USEC(0), ZX_USEC(0), []() { return false; }), ZX_ERR_TIMED_OUT);
}
TEST(WaitCondition, FrequentPolling) {
AutoAdvancingClock clock{};
int num_polls = 0;
// Poll every second for 10 seconds.
WaitCondition(
ZX_SEC(10), ZX_SEC(1),
[&num_polls]() {
num_polls++;
return false;
},
&clock);
// Ensure we polled 10 + 1 times.
EXPECT_EQ(num_polls, 11);
}
TEST(WaitCondition, LongPollPeriod) {
AutoAdvancingClock clock{};
int num_polls = 0;
// Have a polling period far greater than the deadline.
WaitCondition(
ZX_SEC(1), ZX_SEC(100),
[&num_polls]() {
num_polls++;
return false;
},
&clock);
// Ensure we poll twice, once at the beginning and once at the end.
EXPECT_EQ(num_polls, 2);
EXPECT_EQ(clock.Now(), zx::time(0) + zx::sec(1));
}
TEST(WaitCondition, LongRunningCondition) {
AutoAdvancingClock clock{};
int num_polls = 0;
// We want to poll every second for 10 seconds, but the condition takes
// 100 seconds to evaluate.
WaitCondition(
ZX_SEC(10), ZX_SEC(1),
[&num_polls, &clock]() {
num_polls++;
clock.AdvanceTime(zx::sec(100));
return false;
},
&clock);
// Ensure that we still polled twice.
EXPECT_EQ(num_polls, 2);
}
TEST(SampleCapabilities, MakeNewFromShortAudioDescriptorNoMatchFound) {
SampleCaps old_sample_caps = {};
old_sample_caps.pcm_size_rate_ = IHDA_PCM_SIZE_16BITS | IHDA_PCM_RATE_11025 |
IHDA_PCM_RATE_16000 | IHDA_PCM_RATE_22050 | IHDA_PCM_RATE_32000;
old_sample_caps.pcm_formats_ = IHDA_PCM_FORMAT_PCM;
SampleCaps new_sample_caps = {};
edid::ShortAudioDescriptor sad_list[1];
uint8_t num_channels_minus_1 = 1;
sad_list[0].format_and_channels = (edid::ShortAudioDescriptor::kLPcm << 3) | num_channels_minus_1;
sad_list[0].sampling_frequencies = edid::ShortAudioDescriptor::kHz48;
sad_list[0].bitrate = edid::ShortAudioDescriptor::kLpcm_20 | edid::ShortAudioDescriptor::kLpcm_24;
ASSERT_EQ(MakeNewSampleCaps(old_sample_caps, sad_list, countof(sad_list), new_sample_caps),
ZX_ERR_NOT_FOUND);
EXPECT_EQ(new_sample_caps.pcm_size_rate_, 0);
}
TEST(SampleCapabilities, MakeNewFromShortAudioDescriptorBadPcmFormat) {
SampleCaps old_sample_caps = {};
old_sample_caps.pcm_size_rate_ = IHDA_PCM_SIZE_16BITS | IHDA_PCM_RATE_48000;
old_sample_caps.pcm_formats_ =
IHDA_PCM_FORMAT_AC3 | IHDA_PCM_FORMAT_FLOAT32; // No PCM, error below.
SampleCaps new_sample_caps = {};
edid::ShortAudioDescriptor sad_list[1];
uint8_t num_channels_minus_1 = 1;
sad_list[0].format_and_channels = (edid::ShortAudioDescriptor::kLPcm << 3) | num_channels_minus_1;
sad_list[0].sampling_frequencies = edid::ShortAudioDescriptor::kHz48;
sad_list[0].bitrate = edid::ShortAudioDescriptor::kLpcm_20 | edid::ShortAudioDescriptor::kLpcm_24;
ASSERT_EQ(MakeNewSampleCaps(old_sample_caps, sad_list, countof(sad_list), new_sample_caps),
ZX_ERR_NOT_SUPPORTED);
EXPECT_EQ(new_sample_caps.pcm_size_rate_, 0);
}
TEST(SampleCapabilities, MakeNewFromShortAudioDescriptorFindSingle) {
SampleCaps old_sample_caps = {};
old_sample_caps.pcm_size_rate_ = IHDA_PCM_SIZE_16BITS | IHDA_PCM_RATE_11025 |
IHDA_PCM_RATE_16000 | IHDA_PCM_RATE_22050 | IHDA_PCM_RATE_32000;
old_sample_caps.pcm_formats_ = IHDA_PCM_FORMAT_PCM;
SampleCaps new_sample_caps = {};
edid::ShortAudioDescriptor sad_list[1];
sad_list[0].format_and_channels = 0x09; // format = 1, num channels minus 1 = 1.
sad_list[0].sampling_frequencies = edid::ShortAudioDescriptor::kHz32 |
edid::ShortAudioDescriptor::kHz44 |
edid::ShortAudioDescriptor::kHz48;
sad_list[0].bitrate = edid::ShortAudioDescriptor::kLpcm_16 |
edid::ShortAudioDescriptor::kLpcm_20 | edid::ShortAudioDescriptor::kLpcm_24;
ASSERT_OK(MakeNewSampleCaps(old_sample_caps, sad_list, countof(sad_list), new_sample_caps));
EXPECT_EQ(new_sample_caps.pcm_size_rate_, IHDA_PCM_SIZE_16BITS | IHDA_PCM_RATE_32000);
}
TEST(SampleCapabilities, MakeNewFromShortAudioDescriptorFindMultiple1) {
SampleCaps old_sample_caps = {};
old_sample_caps.pcm_size_rate_ = IHDA_PCM_SIZE_16BITS | IHDA_PCM_SIZE_20BITS |
IHDA_PCM_SIZE_24BITS | IHDA_PCM_RATE_32000 | IHDA_PCM_RATE_48000;
old_sample_caps.pcm_formats_ = IHDA_PCM_FORMAT_PCM;
SampleCaps new_sample_caps = {};
edid::ShortAudioDescriptor sad_list[1];
sad_list[0].format_and_channels = 0x09; // format = 1, num channels minus 1 = 1.
sad_list[0].sampling_frequencies = edid::ShortAudioDescriptor::kHz32 |
edid::ShortAudioDescriptor::kHz44 |
edid::ShortAudioDescriptor::kHz48;
sad_list[0].bitrate = edid::ShortAudioDescriptor::kLpcm_20;
ASSERT_OK(MakeNewSampleCaps(old_sample_caps, sad_list, countof(sad_list), new_sample_caps));
EXPECT_EQ(new_sample_caps.pcm_size_rate_,
IHDA_PCM_SIZE_20BITS | IHDA_PCM_RATE_32000 | IHDA_PCM_RATE_48000);
}
TEST(SampleCapabilities, MakeNewFromShortAudioDescriptorFindMultiple2) {
SampleCaps old_sample_caps = {};
old_sample_caps.pcm_size_rate_ = IHDA_PCM_SIZE_16BITS | IHDA_PCM_SIZE_20BITS |
IHDA_PCM_SIZE_24BITS | IHDA_PCM_RATE_32000 | IHDA_PCM_RATE_48000;
old_sample_caps.pcm_formats_ = IHDA_PCM_FORMAT_PCM;
SampleCaps new_sample_caps = {};
edid::ShortAudioDescriptor sad_list[1];
sad_list[0].format_and_channels = 0x09; // format = 1, num channels minus 1 = 1.
sad_list[0].sampling_frequencies = edid::ShortAudioDescriptor::kHz48;
sad_list[0].bitrate = edid::ShortAudioDescriptor::kLpcm_20 | edid::ShortAudioDescriptor::kLpcm_24;
ASSERT_OK(MakeNewSampleCaps(old_sample_caps, sad_list, countof(sad_list), new_sample_caps));
EXPECT_EQ(new_sample_caps.pcm_size_rate_,
IHDA_PCM_SIZE_20BITS | IHDA_PCM_SIZE_24BITS | IHDA_PCM_RATE_48000);
}
} // namespace
} // namespace audio::intel_hda