aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/src/pcm_loopback_test.cc118
1 files changed, 81 insertions, 37 deletions
diff --git a/tests/src/pcm_loopback_test.cc b/tests/src/pcm_loopback_test.cc
index 6a3ffb8..5c6ff4d 100644
--- a/tests/src/pcm_loopback_test.cc
+++ b/tests/src/pcm_loopback_test.cc
@@ -64,6 +64,7 @@ public:
template<pcm_format F>
struct PcmFormat {
using Type = void;
+ static constexpr pcm_format kFormat = F;
static constexpr int32_t kMax = 0;
static constexpr int32_t kMin = 0;
};
@@ -71,10 +72,19 @@ struct PcmFormat {
template<>
struct PcmFormat<PCM_FORMAT_S16_LE> {
using Type = int16_t;
+ static constexpr pcm_format kFormat = PCM_FORMAT_S16_LE;
static constexpr Type kMax = std::numeric_limits<Type>::max();
static constexpr Type kMin = std::numeric_limits<Type>::min();
};
+template<>
+struct PcmFormat<PCM_FORMAT_FLOAT_LE> {
+ using Type = float;
+ static constexpr pcm_format kFormat = PCM_FORMAT_FLOAT_LE;
+ static constexpr Type kMax = 1.0;
+ static constexpr Type kMin = -1.0;
+};
+
// CH: channels
// SR: sampling rate
// FQ: sine wave frequency
@@ -139,43 +149,77 @@ static double Energy(T *buffer, size_t samples) {
return sum;
}
-TEST(PcmLoopbackTest, LoopbackS16le) {
+template<typename F>
+class PcmLoopbackTest : public ::testing::Test {
+ protected:
+ PcmLoopbackTest() = default;
+ virtual ~PcmLoopbackTest() = default;
+
+ void SetUp() override {
+ static constexpr pcm_config kInConfig = {
+ .channels = kDefaultChannels,
+ .rate = kDefaultSamplingRate,
+ .period_size = kDefaultPeriodSize,
+ .period_count = kDefaultPeriodCount,
+ .format = kPcmForamt,
+ .start_threshold = 0,
+ .stop_threshold = 0,
+ .silence_threshold = 0,
+ .silence_size = 0,
+ };
+ pcm_in = pcm_open(kLoopbackCard, kLoopbackCaptureDevice, PCM_IN, &kInConfig);
+ ASSERT_TRUE(pcm_is_ready(pcm_in));
+
+ static constexpr pcm_config kOutConfig = {
+ .channels = kDefaultChannels,
+ .rate = kDefaultSamplingRate,
+ .period_size = kDefaultPeriodSize,
+ .period_count = kDefaultPeriodCount,
+ .format = kPcmForamt,
+ .start_threshold = kDefaultPeriodSize,
+ .stop_threshold = kDefaultPeriodSize * kDefaultPeriodCount,
+ .silence_threshold = 0,
+ .silence_size = 0,
+ };
+ pcm_out = pcm_open(kLoopbackCard, kLoopbackPlaybackDevice, PCM_OUT, &kOutConfig);
+ ASSERT_TRUE(pcm_is_ready(pcm_out));
+ ASSERT_EQ(pcm_link(pcm_in, pcm_out), 0);
+ }
+
+ void TearDown() override {
+ ASSERT_EQ(pcm_unlink(pcm_in), 0);
+ pcm_close(pcm_in);
+ pcm_close(pcm_out);
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ }
+
static constexpr unsigned int kDefaultChannels = 2;
static constexpr unsigned int kDefaultSamplingRate = 48000;
static constexpr unsigned int kDefaultPeriodSize = 1024;
static constexpr unsigned int kDefaultPeriodCount = 3;
static constexpr unsigned int kDefaultPeriodTimeInMs =
kDefaultPeriodSize * 1000 / kDefaultSamplingRate;
+ static constexpr pcm_format kPcmForamt = F::Format;
+ pcm *pcm_in;
+ pcm *pcm_out;
+};
- static constexpr pcm_config kInConfig = {
- .channels = kDefaultChannels,
- .rate = kDefaultSamplingRate,
- .period_size = kDefaultPeriodSize,
- .period_count = kDefaultPeriodCount,
- .format = PCM_FORMAT_S16_LE,
- .start_threshold = 0,
- .stop_threshold = 0,
- .silence_threshold = 0,
- .silence_size = 0,
- };
- pcm *pcm_in = pcm_open(kLoopbackCard, kLoopbackCaptureDevice, PCM_IN, &kInConfig);
- ASSERT_TRUE(pcm_is_ready(pcm_in));
-
- static constexpr pcm_config kOutConfig = {
- .channels = kDefaultChannels,
- .rate = kDefaultSamplingRate,
- .period_size = kDefaultPeriodSize,
- .period_count = kDefaultPeriodCount,
- .format = PCM_FORMAT_S16_LE,
- .start_threshold = kDefaultPeriodSize,
- .stop_threshold = kDefaultPeriodSize * kDefaultPeriodCount,
- .silence_threshold = 0,
- .silence_size = 0,
- };
- pcm *pcm_out = pcm_open(kLoopbackCard, kLoopbackPlaybackDevice, PCM_OUT, &kOutConfig);
- ASSERT_TRUE(pcm_is_ready(pcm_out));
+using S16bitlePcmFormat = PcmFormat<PCM_FORMAT_S16_LE>;
+using FloatPcmFormat = PcmFormat<PCM_FORMAT_FLOAT_LE>;
- ASSERT_EQ(pcm_link(pcm_in, pcm_out), 0);
+using Formats = ::testing::Types<S16bitlePcmFormat, FloatPcmFormat>;
+
+TYPED_TEST_SUITE(PcmLoopbackTest, Formats);
+
+TYPED_TEST(PcmLoopbackTest, Loopback) {
+ static constexpr unsigned int kDefaultChannels = this->kDefaultChannels;
+ static constexpr unsigned int kDefaultSamplingRate = this->kDefaultSamplingRate;
+ static constexpr unsigned int kDefaultPeriodSize = this->kDefaultPeriodSize;
+ // static constexpr unsigned int kDefaultPeriodCount = this->kDefaultPeriodCount;
+ static constexpr unsigned int kDefaultPeriodTimeInMs = this->kDefaultPeriodTimeInMs;
+ static constexpr pcm_format kPcmForamt = this->kPcmForamt;
+ pcm *pcm_in = this->pcm_in;
+ pcm *pcm_out = this->pcm_out;
bool stopping = false;
ASSERT_EQ(pcm_get_subdevice(pcm_in), pcm_get_subdevice(pcm_out));
@@ -190,23 +234,26 @@ TEST(PcmLoopbackTest, LoopbackS16le) {
if (res == -1) {
std::cout << pcm_get_error(pcm_in) << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(kDefaultPeriodTimeInMs));
+ counter++;
continue;
}
- EXPECT_EQ(pcm_readi(pcm_in, buffer.get(), frames), frames) << counter;
+
// Test the energy of the buffer after the sine tone samples fill in the buffer.
// Therefore, check the buffer 5 times later.
if (counter >= 5) {
- double e = Energy(buffer.get(), frames * kInConfig.channels);
+ double e = Energy(buffer.get(), frames * kDefaultChannels);
EXPECT_GT(e, 0.0) << counter;
}
counter++;
}
+ std::cout << "read count = " << counter << std::endl;
});
std::thread playback([pcm_out, &stopping] {
- SineToneGenerator<2, 48000, 1000, 0, PCM_FORMAT_S16_LE> generator;
+ SineToneGenerator<kDefaultChannels, kDefaultSamplingRate, 1000, 0, kPcmForamt> generator;
size_t buffer_size = pcm_frames_to_bytes(pcm_out, kDefaultPeriodSize);
unsigned int frames = pcm_bytes_to_frames(pcm_out, buffer_size);
+ std::cout << buffer_size << std::endl;
auto buffer = std::make_unique<unsigned char[]>(buffer_size);
int32_t counter = 0;
while (!stopping) {
@@ -214,16 +261,13 @@ TEST(PcmLoopbackTest, LoopbackS16le) {
EXPECT_EQ(pcm_writei(pcm_out, buffer.get(), frames), frames) << counter;
counter++;
}
+ std::cout << "write count = " << counter << std::endl;
});
- std::this_thread::sleep_for(std::chrono::seconds(1));
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
stopping = true;
capture.join();
playback.join();
-
- ASSERT_EQ(pcm_unlink(pcm_in), 0);
- pcm_close(pcm_in);
- pcm_close(pcm_out);
}
} // namespace testing