diff options
Diffstat (limited to 'cras/src/tests/audio_thread_unittest_obsolete.cc')
-rw-r--r-- | cras/src/tests/audio_thread_unittest_obsolete.cc | 2191 |
1 files changed, 0 insertions, 2191 deletions
diff --git a/cras/src/tests/audio_thread_unittest_obsolete.cc b/cras/src/tests/audio_thread_unittest_obsolete.cc deleted file mode 100644 index ae9f5ef3..00000000 --- a/cras/src/tests/audio_thread_unittest_obsolete.cc +++ /dev/null @@ -1,2191 +0,0 @@ -// Copyright (c) 2012 The Chromium OS Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -extern "C" { -#include "audio_thread.c" -} - -#include <gtest/gtest.h> -#include <stdio.h> -#include <sys/select.h> - -extern "C" { - -struct dev_stream_capture_call { - struct dev_stream* dev_stream; - const struct cras_audio_area* area; - unsigned int dev_index; - unsigned int num_called; -}; - -struct cap_sleep_frames_call { - struct dev_stream* dev_stream; - unsigned int written; - unsigned int num_called; -}; - -static int dev_stream_mix_dont_fill_next; -static unsigned int dev_stream_mix_count; -static unsigned int cras_mix_mute_count; -static unsigned int dev_stream_request_playback_samples_called; -static unsigned int cras_rstream_destroy_called; -static unsigned int cras_metrics_log_histogram_called; -static const char* cras_metrics_log_histogram_name; -static unsigned int cras_metrics_log_histogram_sample; -static unsigned int cras_metrics_log_event_called; - -static void (*cras_system_add_select_fd_callback)(void* data); -static void* cras_system_add_select_fd_callback_data; - -static int select_return_value; -static struct timeval select_timeval; -static int select_max_fd; -static fd_set select_in_fds; -static fd_set select_out_fds; -static uint32_t* select_write_ptr; -static uint32_t select_write_value; -static unsigned int cras_iodev_set_format_called; -static unsigned int dev_stream_set_delay_called; -static unsigned int cras_system_get_volume_return; -static unsigned int dev_stream_mix_called; - -static struct timespec time_now; -static int cras_fmt_conversion_needed_return_val; -static struct cras_audio_area* mock_audio_area1; -static struct cras_audio_area* mock_audio_area2; -static struct cras_audio_format cras_iodev_set_format_val; - -static struct dev_stream_capture_call dev_stream_capture_call; -static struct cap_sleep_frames_call cap_sleep_frames_call; -} - -// Number of frames past target that will be added to sleep times to insure that -// all frames are ready. -static const int CAP_EXTRA_SLEEP_FRAMES = 16; - -// Test the audio capture path. -class ReadStreamSuite : public testing::Test { - protected: - virtual void SetUp() { - memset(&cras_iodev_set_format_val, 0, sizeof(cras_iodev_set_format_val)); - cras_iodev_set_format_val.frame_rate = 44100; - cras_iodev_set_format_val.num_channels = 2; - cras_iodev_set_format_val.format = SND_PCM_FORMAT_S16_LE; - - memset(&iodev_, 0, sizeof(iodev_)); - iodev_.buffer_size = 16384; - cb_threshold_ = 480; - iodev_.direction = CRAS_STREAM_INPUT; - - iodev_.frames_queued = frames_queued; - iodev_.delay_frames = delay_frames; - iodev_.get_buffer = get_buffer; - iodev_.put_buffer = put_buffer; - iodev_.is_open = is_open; - iodev_.open_dev = open_dev; - iodev_.close_dev = close_dev; - iodev_.dev_running = dev_running; - - memcpy(&output_dev_, &iodev_, sizeof(output_dev_)); - output_dev_.direction = CRAS_STREAM_OUTPUT; - - SetupRstream(&rstream_, 1); - shm_ = cras_rstream_input_shm(rstream_); - SetupRstream(&rstream2_, 2); - shm2_ = cras_rstream_input_shm(rstream2_); - - mock_audio_area1 = (cras_audio_area*)calloc( - 1, sizeof(cras_audio_area) + 2 * sizeof(cras_channel_area)); - mock_audio_area1->num_channels = 2; - channel_area_set_channel(&mock_audio_area1->channels[0], CRAS_CH_FL); - channel_area_set_channel(&mock_audio_area1->channels[1], CRAS_CH_FR); - rstream_->input_audio_area = mock_audio_area1; - mock_audio_area2 = (cras_audio_area*)calloc( - 1, sizeof(cras_audio_area) + 2 * sizeof(cras_channel_area)); - mock_audio_area2->num_channels = 2; - channel_area_set_channel(&mock_audio_area2->channels[0], CRAS_CH_FL); - channel_area_set_channel(&mock_audio_area2->channels[1], CRAS_CH_FR); - rstream2_->input_audio_area = mock_audio_area2; - - dev_stream_mix_dont_fill_next = 0; - dev_stream_mix_count = 0; - dev_running_called_ = 0; - is_open_ = 0; - close_dev_called_ = 0; - - cras_iodev_set_format_called = 0; - dev_stream_set_delay_called = 0; - } - - virtual void TearDown() { - free(shm_->area); - free(rstream_); - free(shm2_->area); - free(rstream2_); - free(mock_audio_area1); - free(mock_audio_area2); - } - - void SetupRstream(struct cras_rstream** rstream, int fd) { - struct cras_audio_shm* shm; - - *rstream = (struct cras_rstream*)calloc(1, sizeof(**rstream)); - memcpy(&(*rstream)->format, &cras_iodev_set_format_val, - sizeof(cras_iodev_set_format_val)); - (*rstream)->direction = CRAS_STREAM_INPUT; - (*rstream)->cb_threshold = cb_threshold_; - (*rstream)->client = (struct cras_rclient*)this; - - shm = cras_rstream_input_shm(*rstream); - shm->header = (struct cras_audio_shm_header*)calloc( - 1, sizeof(*shm->header) + cb_threshold_ * 8); - cras_shm_set_frame_bytes(shm, 4); - cras_shm_set_used_size(shm, cb_threshold_ * cras_shm_frame_bytes(shm)); - } - - unsigned int GetCaptureSleepFrames() { - // Account for padding the sleep interval to ensure the wake up happens - // after the last desired frame is received. - return cb_threshold_ + 16; - } - - // Stub functions for the iodev structure. - static int frames_queued(const cras_iodev* iodev) { return frames_queued_; } - - static int delay_frames(const cras_iodev* iodev) { return delay_frames_; } - - static int get_buffer(cras_iodev* iodev, - struct cras_audio_area** area, - unsigned int* num) { - size_t sz = sizeof(*area_) + sizeof(struct cras_channel_area) * 2; - - if (audio_buffer_size_ < *num) - *num = audio_buffer_size_; - - area_ = (cras_audio_area*)calloc(1, sz); - area_->frames = *num; - area_->num_channels = 2; - area_->channels[0].buf = audio_buffer_; - channel_area_set_channel(&area_->channels[0], CRAS_CH_FL); - area_->channels[0].step_bytes = 4; - area_->channels[1].buf = audio_buffer_ + 2; - channel_area_set_channel(&area_->channels[1], CRAS_CH_FR); - area_->channels[1].step_bytes = 4; - - *area = area_; - return 0; - } - - static int put_buffer(cras_iodev* iodev, unsigned int num) { - free(area_); - return 0; - } - - static int is_open(const cras_iodev* iodev) { return is_open_; } - - static int open_dev(cras_iodev* iodev) { return 0; } - - static int close_dev(cras_iodev* iodev) { - close_dev_called_++; - return 0; - } - - static int dev_running(const cras_iodev* iodev) { - dev_running_called_++; - return 1; - } - - struct cras_iodev iodev_; - struct cras_iodev output_dev_; - static int is_open_; - static int frames_queued_; - static int delay_frames_; - static unsigned int cb_threshold_; - static uint8_t audio_buffer_[8192]; - static struct cras_audio_area* area_; - static unsigned int audio_buffer_size_; - static unsigned int dev_running_called_; - static unsigned int close_dev_called_; - struct cras_rstream* rstream_; - struct cras_rstream* rstream2_; - struct cras_audio_shm* shm_; - struct cras_audio_shm* shm2_; -}; - -int ReadStreamSuite::is_open_ = 0; -int ReadStreamSuite::frames_queued_ = 0; -int ReadStreamSuite::delay_frames_ = 0; -unsigned int ReadStreamSuite::close_dev_called_ = 0; -uint8_t ReadStreamSuite::audio_buffer_[8192]; -unsigned int ReadStreamSuite::audio_buffer_size_ = 0; -unsigned int ReadStreamSuite::dev_running_called_ = 0; -unsigned int ReadStreamSuite::cb_threshold_ = 0; -struct cras_audio_area* ReadStreamSuite::area_; - -TEST_F(ReadStreamSuite, PossiblyReadGetAvailError) { - struct timespec ts; - int rc; - struct audio_thread* thread; - - thread = audio_thread_create(); - ASSERT_TRUE(thread); - thread_set_active_dev(thread, &iodev_); - - thread_add_stream(thread, rstream_); - EXPECT_EQ(1, cras_iodev_set_format_called); - - frames_queued_ = -4; - is_open_ = 1; - rc = unified_io(thread, &ts); - EXPECT_EQ(-4, rc); - EXPECT_EQ(0, ts.tv_sec); - EXPECT_EQ(0, ts.tv_nsec); - EXPECT_EQ(0, dev_stream_set_delay_called); - EXPECT_EQ(1, close_dev_called_); - - audio_thread_destroy(thread); -} - -TEST_F(ReadStreamSuite, PossiblyReadEmpty) { - struct timespec ts; - int rc; - uint64_t nsec_expected; - struct audio_thread* thread; - - thread = audio_thread_create(); - ASSERT_TRUE(thread); - thread_set_active_dev(thread, &iodev_); - - thread_add_stream(thread, rstream_); - EXPECT_EQ(1, cras_iodev_set_format_called); - - // If no samples are present, it should sleep for cb_threshold frames. - frames_queued_ = 0; - is_open_ = 1; - nsec_expected = (GetCaptureSleepFrames()) * 1000000000ULL / - (uint64_t)cras_iodev_set_format_val.frame_rate; - rc = unified_io(thread, &ts); - EXPECT_EQ(0, rc); - EXPECT_EQ(0, ts.tv_sec); - EXPECT_EQ(0, shm_->area->write_offset[0]); - EXPECT_GE(ts.tv_nsec, nsec_expected - 1000); - EXPECT_LE(ts.tv_nsec, nsec_expected + 1000); - EXPECT_EQ(1, dev_running_called_); - EXPECT_EQ(1, dev_stream_set_delay_called); - - audio_thread_destroy(thread); -} - -TEST_F(ReadStreamSuite, PossiblyReadTooLittleData) { - struct timespec ts; - int rc; - uint64_t nsec_expected; - static const uint64_t num_frames_short = 40; - struct audio_thread* thread; - - thread = audio_thread_create(); - ASSERT_TRUE(thread); - thread_set_active_dev(thread, &iodev_); - - thread_add_stream(thread, rstream_); - - frames_queued_ = cb_threshold_ - num_frames_short; - is_open_ = 1; - audio_buffer_size_ = frames_queued_; - nsec_expected = ((uint64_t)num_frames_short + CAP_EXTRA_SLEEP_FRAMES) * - 1000000000ULL / - (uint64_t)cras_iodev_set_format_val.frame_rate; - - rc = unified_io(thread, &ts); - EXPECT_EQ(0, rc); - /* As much data as can be, should be read. */ - EXPECT_EQ(&audio_buffer_[0], dev_stream_capture_call.area->channels[0].buf); - EXPECT_EQ(rstream_, dev_stream_capture_call.dev_stream->stream); - EXPECT_EQ(cb_threshold_ - num_frames_short, cap_sleep_frames_call.written); - EXPECT_EQ(0, ts.tv_sec); - EXPECT_GE(ts.tv_nsec, nsec_expected - 1000); - EXPECT_LE(ts.tv_nsec, nsec_expected + 1000); - - audio_thread_destroy(thread); -} - -TEST_F(ReadStreamSuite, PossiblyReadHasDataWriteStream) { - struct timespec ts; - int rc; - uint64_t nsec_expected; - struct audio_thread* thread; - - thread = audio_thread_create(); - ASSERT_TRUE(thread); - thread_set_active_dev(thread, &iodev_); - - thread_add_stream(thread, rstream_); - - // A full block plus 4 frames. - frames_queued_ = cb_threshold_ + 4; - audio_buffer_size_ = frames_queued_; - - for (unsigned int i = 0; i < sizeof(audio_buffer_); i++) - audio_buffer_[i] = i; - - uint64_t sleep_frames = GetCaptureSleepFrames() - 4; - nsec_expected = (uint64_t)sleep_frames * 1000000000ULL / - (uint64_t)cras_iodev_set_format_val.frame_rate; - is_open_ = 1; - // Give it some samples to copy. - rc = unified_io(thread, &ts); - EXPECT_EQ(0, rc); - EXPECT_EQ(0, ts.tv_sec); - EXPECT_GE(ts.tv_nsec, nsec_expected - 1000); - EXPECT_LE(ts.tv_nsec, nsec_expected + 1000); - EXPECT_EQ(1, dev_stream_set_delay_called); - EXPECT_EQ(&audio_buffer_[0], dev_stream_capture_call.area->channels[0].buf); - EXPECT_EQ(rstream_, dev_stream_capture_call.dev_stream->stream); - EXPECT_EQ(cb_threshold_, cap_sleep_frames_call.written); - EXPECT_EQ(rstream_, cap_sleep_frames_call.dev_stream->stream); - - audio_thread_destroy(thread); -} - -TEST_F(ReadStreamSuite, PossiblyReadHasDataWriteTwoStreams) { - struct timespec ts; - int rc; - uint64_t nsec_expected; - struct audio_thread* thread; - - dev_stream_capture_call.num_called = 0; - cap_sleep_frames_call.num_called = 0; - - thread = audio_thread_create(); - ASSERT_TRUE(thread); - thread_set_active_dev(thread, &iodev_); - - rc = thread_add_stream(thread, rstream_); - EXPECT_EQ(0, rc); - rc = thread_add_stream(thread, rstream2_); - EXPECT_EQ(0, rc); - - // A full block plus 4 frames. - frames_queued_ = cb_threshold_ + 4; - audio_buffer_size_ = frames_queued_; - - for (unsigned int i = 0; i < sizeof(audio_buffer_); i++) - audio_buffer_[i] = i; - - uint64_t sleep_frames = GetCaptureSleepFrames() - 4; - nsec_expected = (uint64_t)sleep_frames * 1000000000ULL / - (uint64_t)cras_iodev_set_format_val.frame_rate; - is_open_ = 1; - // Give it some samples to copy. - rc = unified_io(thread, &ts); - EXPECT_EQ(0, rc); - EXPECT_EQ(0, ts.tv_sec); - EXPECT_GE(ts.tv_nsec, nsec_expected - 1000); - EXPECT_LE(ts.tv_nsec, nsec_expected + 1000); - EXPECT_EQ(2, dev_stream_capture_call.num_called); - EXPECT_EQ(2, cap_sleep_frames_call.num_called); - - audio_thread_destroy(thread); -} - -TEST_F(ReadStreamSuite, PossiblyReadHasDataWriteTwoDifferentStreams) { - struct timespec ts; - int rc; - uint64_t nsec_expected; - struct audio_thread* thread; - - thread = audio_thread_create(); - ASSERT_TRUE(thread); - thread_set_active_dev(thread, &iodev_); - - cb_threshold_ /= 2; - rstream_->cb_threshold = cb_threshold_; - - rc = thread_add_stream(thread, rstream_); - EXPECT_EQ(0, rc); - rc = thread_add_stream(thread, rstream2_); - EXPECT_EQ(0, rc); - - // A full block plus 4 frames. - frames_queued_ = cb_threshold_ + 4; - audio_buffer_size_ = frames_queued_; - - uint64_t sleep_frames = GetCaptureSleepFrames() - 4; - nsec_expected = (uint64_t)sleep_frames * 1000000000ULL / - (uint64_t)cras_iodev_set_format_val.frame_rate; - is_open_ = 1; - // Give it some samples to copy. - rc = unified_io(thread, &ts); - EXPECT_EQ(0, rc); - EXPECT_EQ(0, ts.tv_sec); - EXPECT_GE(ts.tv_nsec, nsec_expected - 1000); - EXPECT_LE(ts.tv_nsec, nsec_expected + 1000); - - frames_queued_ = cb_threshold_ + 5; - sleep_frames = GetCaptureSleepFrames() - 5; - nsec_expected = (uint64_t)sleep_frames * 1000000000ULL / - (uint64_t)cras_iodev_set_format_val.frame_rate; - audio_buffer_size_ = frames_queued_; - is_open_ = 1; - // Give it some samples to copy. - rc = unified_io(thread, &ts); - EXPECT_EQ(0, rc); - EXPECT_EQ(0, ts.tv_sec); - EXPECT_GE(ts.tv_nsec, nsec_expected - 1000); - EXPECT_LE(ts.tv_nsec, nsec_expected + 1000); - - audio_thread_destroy(thread); -} - -TEST_F(ReadStreamSuite, PossiblyReadWriteThreeBuffers) { - struct timespec ts; - int rc; - struct audio_thread* thread; - - thread = audio_thread_create(); - ASSERT_TRUE(thread); - thread_set_active_dev(thread, &iodev_); - - thread_add_stream(thread, rstream_); - - // A full block plus 4 frames. - frames_queued_ = cb_threshold_ + 4; - audio_buffer_size_ = frames_queued_; - is_open_ = 1; - - // Give it some samples to copy. - rc = unified_io(thread, &ts); - EXPECT_EQ(0, rc); - EXPECT_EQ(0, cras_shm_num_overruns(shm_)); - EXPECT_EQ(&audio_buffer_[0], dev_stream_capture_call.area->channels[0].buf); - EXPECT_EQ(rstream_, dev_stream_capture_call.dev_stream->stream); - EXPECT_EQ(cb_threshold_, cap_sleep_frames_call.written); - EXPECT_EQ(rstream_, cap_sleep_frames_call.dev_stream->stream); - - is_open_ = 1; - rc = unified_io(thread, &ts); - EXPECT_EQ(0, rc); - EXPECT_EQ(0, cras_shm_num_overruns(shm_)); - EXPECT_EQ(&audio_buffer_[0], dev_stream_capture_call.area->channels[0].buf); - EXPECT_EQ(rstream_, dev_stream_capture_call.dev_stream->stream); - EXPECT_EQ(cb_threshold_, cap_sleep_frames_call.written); - EXPECT_EQ(rstream_, cap_sleep_frames_call.dev_stream->stream); - - is_open_ = 1; - rc = unified_io(thread, &ts); - EXPECT_EQ(0, rc); - EXPECT_EQ(&audio_buffer_[0], dev_stream_capture_call.area->channels[0].buf); - EXPECT_EQ(rstream_, dev_stream_capture_call.dev_stream->stream); - EXPECT_EQ(cb_threshold_, cap_sleep_frames_call.written); - EXPECT_EQ(rstream_, cap_sleep_frames_call.dev_stream->stream); - - audio_thread_destroy(thread); -} - -// Test the audio playback path. -class WriteStreamSuite : public testing::Test { - protected: - virtual void SetUp() { - memset(&fmt_, 0, sizeof(fmt_)); - fmt_.frame_rate = 44100; - fmt_.num_channels = 2; - fmt_.format = SND_PCM_FORMAT_S16_LE; - - memset(&iodev_, 0, sizeof(iodev_)); - iodev_.format = &fmt_; - iodev_.buffer_size = 16384; - iodev_.direction = CRAS_STREAM_OUTPUT; - - iodev_.frames_queued = frames_queued; - iodev_.delay_frames = delay_frames; - iodev_.get_buffer = get_buffer; - iodev_.put_buffer = put_buffer; - iodev_.dev_running = dev_running; - iodev_.is_open = is_open; - iodev_.open_dev = open_dev; - iodev_.close_dev = close_dev; - iodev_.buffer_size = 480; - - buffer_frames_ = iodev_.buffer_size; - cb_threshold_ = 96; - SetupRstream(&rstream_, 1); - shm_ = cras_rstream_output_shm(rstream_); - SetupRstream(&rstream2_, 2); - shm2_ = cras_rstream_output_shm(rstream2_); - - thread_ = audio_thread_create(); - ASSERT_TRUE(thread_); - thread_set_active_dev(thread_, &iodev_); - - dev_stream_mix_dont_fill_next = 0; - dev_stream_mix_count = 0; - select_max_fd = -1; - select_write_ptr = NULL; - cras_metrics_log_event_called = 0; - dev_stream_request_playback_samples_called = 0; - cras_rstream_destroy_called = 0; - dev_stream_mix_called = 0; - is_open_ = 0; - close_dev_called_ = 0; - - dev_running_called_ = 0; - - audio_buffer_size_ = 8196; - thread_add_stream(thread_, rstream_); - frames_written_ = 0; - } - - virtual void TearDown() { - free(shm_->area); - free(rstream_); - free(shm2_->area); - free(rstream2_); - audio_thread_destroy(thread_); - } - - void SetupRstream(struct cras_rstream** rstream, int fd) { - struct cras_audio_shm* shm; - - *rstream = (struct cras_rstream*)calloc(1, sizeof(**rstream)); - memcpy(&(*rstream)->format, &fmt_, sizeof(fmt_)); - (*rstream)->fd = fd; - (*rstream)->buffer_frames = buffer_frames_; - (*rstream)->cb_threshold = cb_threshold_; - (*rstream)->client = (struct cras_rclient*)this; - - shm = cras_rstream_output_shm(*rstream); - shm->header = (struct cras_audio_shm_header*)calloc( - 1, sizeof(*shm->header) + cb_threshold_ * 8); - cras_shm_set_frame_bytes(shm, 4); - cras_shm_set_used_size(shm, buffer_frames_ * cras_shm_frame_bytes(shm)); - } - - uint64_t GetCaptureSleepFrames() { - // Account for padding the sleep interval to ensure the wake up happens - // after the last desired frame is received. - return cb_threshold_ + CAP_EXTRA_SLEEP_FRAMES; - } - - // Stub functions for the iodev structure. - static int frames_queued(const cras_iodev* iodev) { - return frames_queued_ + frames_written_; - } - - static int delay_frames(const cras_iodev* iodev) { return delay_frames_; } - - static int get_buffer(cras_iodev* iodev, - struct cras_audio_area** area, - unsigned int* num) { - size_t sz = sizeof(*area_) + sizeof(struct cras_channel_area) * 2; - - if (audio_buffer_size_ < *num) - *num = audio_buffer_size_; - - area_ = (cras_audio_area*)calloc(1, sz); - area_->frames = *num; - area_->num_channels = 2; - area_->channels[0].buf = audio_buffer_; - channel_area_set_channel(&area_->channels[0], CRAS_CH_FL); - area_->channels[0].step_bytes = 4; - area_->channels[1].buf = audio_buffer_ + 2; - channel_area_set_channel(&area_->channels[1], CRAS_CH_FR); - area_->channels[1].step_bytes = 4; - - *area = area_; - return 0; - } - - static int put_buffer(cras_iodev* iodev, unsigned int num) { - free(area_); - frames_written_ += num; - return 0; - } - - static int dev_running(const cras_iodev* iodev) { - dev_running_called_++; - return dev_running_; - } - - static int is_open(const cras_iodev* iodev) { return is_open_; } - - static int open_dev(cras_iodev* iodev) { - is_open_ = 1; - open_dev_called_++; - return 0; - } - - static int close_dev(cras_iodev* iodev) { - close_dev_called_++; - is_open_ = 0; - return 0; - } - - struct cras_iodev iodev_; - static int is_open_; - static int frames_queued_; - static int frames_written_; - static int delay_frames_; - static unsigned int cb_threshold_; - static unsigned int buffer_frames_; - static uint8_t audio_buffer_[8192]; - static unsigned int audio_buffer_size_; - static int dev_running_; - static unsigned int dev_running_called_; - static unsigned int close_dev_called_; - static unsigned int open_dev_called_; - static struct cras_audio_area* area_; - struct cras_audio_format fmt_; - struct cras_rstream* rstream_; - struct cras_rstream* rstream2_; - struct cras_audio_shm* shm_; - struct cras_audio_shm* shm2_; - struct audio_thread* thread_; -}; - -int WriteStreamSuite::is_open_ = 0; -int WriteStreamSuite::frames_queued_ = 0; -int WriteStreamSuite::frames_written_ = 0; -int WriteStreamSuite::delay_frames_ = 0; -unsigned int WriteStreamSuite::cb_threshold_ = 0; -unsigned int WriteStreamSuite::buffer_frames_ = 0; -uint8_t WriteStreamSuite::audio_buffer_[8192]; -unsigned int WriteStreamSuite::audio_buffer_size_ = 0; -int WriteStreamSuite::dev_running_ = 1; -unsigned int WriteStreamSuite::dev_running_called_ = 0; -unsigned int WriteStreamSuite::close_dev_called_ = 0; -unsigned int WriteStreamSuite::open_dev_called_ = 0; -struct cras_audio_area* WriteStreamSuite::area_; - -TEST_F(WriteStreamSuite, PossiblyFillGetAvailError) { - struct timespec ts; - int rc; - - frames_queued_ = -4; - is_open_ = 1; - rc = unified_io(thread_, &ts); - EXPECT_EQ(-4, rc); - EXPECT_EQ(0, ts.tv_sec); - EXPECT_EQ(0, ts.tv_nsec); - EXPECT_EQ(1, close_dev_called_); -} - -TEST_F(WriteStreamSuite, PossiblyFillEarlyWake) { - struct timespec ts; - int rc; - - // If woken and still have tons of data to play, go back to sleep. - frames_queued_ = cb_threshold_ * 2; - audio_buffer_size_ = buffer_frames_ - frames_queued_; - - iodev_.direction = CRAS_STREAM_OUTPUT; - is_open_ = 1; - - rc = unified_io(thread_, &ts); - EXPECT_EQ(0, rc); - EXPECT_EQ(0, ts.tv_sec); -} - -TEST_F(WriteStreamSuite, PossiblyFillGetFromStreamFull) { - struct timespec ts; - int rc; - uint64_t nsec_expected; - - // Have cb_threshold samples left. - frames_queued_ = cb_threshold_; - audio_buffer_size_ = buffer_frames_ - frames_queued_; - nsec_expected = - (uint64_t)cb_threshold_ * 1000000000ULL / (uint64_t)fmt_.frame_rate; - - // shm has plenty of data in it. - shm_->area->write_offset[0] = cb_threshold_ * 4; - - FD_ZERO(&select_out_fds); - FD_SET(rstream_->fd, &select_out_fds); - select_return_value = 1; - is_open_ = 1; - - rc = unified_io(thread_, &ts); - EXPECT_EQ(0, rc); - EXPECT_EQ(0, ts.tv_sec); - EXPECT_GE(ts.tv_nsec, nsec_expected - 1000); - EXPECT_LE(ts.tv_nsec, nsec_expected + 1000); - EXPECT_EQ(cb_threshold_, dev_stream_mix_count); - EXPECT_EQ(0, dev_stream_request_playback_samples_called); - EXPECT_EQ(-1, select_max_fd); -} - -TEST_F(WriteStreamSuite, PossiblyFillGetFromStreamMinSet) { - struct timespec ts; - int rc; - uint64_t nsec_expected; - - // Have cb_threshold samples left. - frames_queued_ = cb_threshold_ * 2; - audio_buffer_size_ = buffer_frames_ - frames_queued_; - // Setting the min_buffer_level should shorten the sleep time. - iodev_.min_buffer_level = cb_threshold_; - - // shm has is empty. - shm_->area->write_offset[0] = 0; - - FD_ZERO(&select_out_fds); - FD_SET(rstream_->fd, &select_out_fds); - select_return_value = 1; - is_open_ = 1; - // Set write offset after call to select. - select_write_ptr = &shm_->area->write_offset[0]; - select_write_value = cb_threshold_ * 4; - - // After the callback there will be cb_thresh of data in the buffer and - // cb_thresh x 2 data in the hardware (frames_queued_) = 3 cb_thresh total. - // It should sleep until there is a total of cb_threshold + min_buffer_level - // left, or 3 - 2 = 1 cb_thresh worth of delay. - nsec_expected = - (uint64_t)cb_threshold_ * 1000000000ULL / (uint64_t)fmt_.frame_rate; - - rc = unified_io(thread_, &ts); - EXPECT_EQ(0, rc); - EXPECT_EQ(0, ts.tv_sec); - EXPECT_GE(ts.tv_nsec, nsec_expected - 1000); - EXPECT_LE(ts.tv_nsec, nsec_expected + 1000); - EXPECT_EQ(cb_threshold_, dev_stream_mix_count); - EXPECT_EQ(1, dev_stream_request_playback_samples_called); -} - -TEST_F(WriteStreamSuite, PossiblyFillFramesQueued) { - struct timespec ts; - int rc; - - // Have cb_threshold samples left. - frames_queued_ = cb_threshold_; - audio_buffer_size_ = buffer_frames_ - frames_queued_; - - // shm has plenty of data in it. - shm_->area->write_offset[0] = cras_shm_used_size(shm_); - - is_open_ = 1; - rc = unified_io(thread_, &ts); - EXPECT_EQ(0, rc); - EXPECT_EQ(1, dev_running_called_); -} - -TEST_F(WriteStreamSuite, PossiblyFillGetFromStreamOneEmpty) { - struct timespec ts; - int rc; - - // Have cb_threshold samples left. - frames_queued_ = cb_threshold_; - audio_buffer_size_ = buffer_frames_ - frames_queued_; - - // shm has plenty of data in it. - shm_->area->write_offset[0] = cras_shm_used_size(shm_); - - // Test that nothing breaks if there is an empty stream. - dev_stream_mix_dont_fill_next = 1; - - FD_ZERO(&select_out_fds); - FD_SET(rstream_->fd, &select_out_fds); - select_return_value = 1; - - is_open_ = 1; - rc = unified_io(thread_, &ts); - EXPECT_EQ(0, rc); - EXPECT_EQ(0, dev_stream_request_playback_samples_called); - EXPECT_EQ(-1, select_max_fd); - EXPECT_EQ(0, shm_->area->read_offset[0]); - EXPECT_EQ(0, shm_->area->read_offset[1]); - EXPECT_EQ(cras_shm_used_size(shm_), shm_->area->write_offset[0]); - EXPECT_EQ(0, shm_->area->write_offset[1]); -} - -TEST_F(WriteStreamSuite, PossiblyFillGetFromStreamNeedFill) { - struct timespec ts; - uint64_t nsec_expected; - int rc; - - // Have cb_threshold samples left. - frames_queued_ = cb_threshold_; - audio_buffer_size_ = buffer_frames_ - frames_queued_; - - // shm is out of data. - shm_->area->write_offset[0] = 0; - - FD_ZERO(&select_out_fds); - FD_SET(rstream_->fd, &select_out_fds); - select_return_value = 1; - // Set write offset after call to select. - select_write_ptr = &shm_->area->write_offset[0]; - select_write_value = (buffer_frames_ - cb_threshold_) * 4; - - nsec_expected = (buffer_frames_ - cb_threshold_) * 1000000000ULL / - (uint64_t)fmt_.frame_rate; - - is_open_ = 1; - rc = unified_io(thread_, &ts); - EXPECT_EQ(0, rc); - EXPECT_EQ(0, ts.tv_sec); - EXPECT_GE(ts.tv_nsec, nsec_expected - 1000); - EXPECT_LE(ts.tv_nsec, nsec_expected + 1000); - EXPECT_EQ(buffer_frames_ - cb_threshold_, dev_stream_mix_count); - EXPECT_EQ(1, dev_stream_request_playback_samples_called); - EXPECT_NE(-1, select_max_fd); - EXPECT_EQ(0, memcmp(&select_out_fds, &select_in_fds, sizeof(select_in_fds))); - EXPECT_EQ(0, shm_->area->read_offset[0]); -} - -TEST_F(WriteStreamSuite, PossiblyFillGetFromTwoStreamsFull) { - struct timespec ts; - int rc; - uint64_t nsec_expected; - - // Have cb_threshold samples left. - frames_queued_ = cras_rstream_get_cb_threshold(rstream_); - audio_buffer_size_ = buffer_frames_ - frames_queued_; - nsec_expected = (uint64_t)cras_rstream_get_cb_threshold(rstream_) * - 1000000000ULL / (uint64_t)fmt_.frame_rate; - - // shm has plenty of data in it. - shm_->area->write_offset[0] = cras_rstream_get_cb_threshold(rstream_) * 4; - shm2_->area->write_offset[0] = cras_rstream_get_cb_threshold(rstream2_) * 4; - - thread_add_stream(thread_, rstream2_); - - is_open_ = 1; - rc = unified_io(thread_, &ts); - EXPECT_EQ(0, rc); - EXPECT_EQ(2, dev_stream_mix_called); - EXPECT_EQ(0, ts.tv_sec); - EXPECT_GE(ts.tv_nsec, nsec_expected - 1000); - EXPECT_LE(ts.tv_nsec, nsec_expected + 1000); - EXPECT_EQ(cras_rstream_get_cb_threshold(rstream_), dev_stream_mix_count); - EXPECT_EQ(0, dev_stream_request_playback_samples_called); - EXPECT_EQ(-1, select_max_fd); -} - -TEST_F(WriteStreamSuite, PossiblyFillGetFromTwoOneEmptySmallerCbThreshold) { - struct timespec ts; - int rc; - uint64_t nsec_expected; - - // Have cb_threshold samples left. - frames_queued_ = cb_threshold_; - audio_buffer_size_ = buffer_frames_ - frames_queued_; - - // First stream is empty and with a smaller cb_threshold. This is to test - // the case that when buffer level reaches the cb_threshold of one stream - // but not yet the other stream of smaller cb_threshold. - rstream_->cb_threshold -= 20; - nsec_expected = 20 * 1000000000ULL / (uint64_t)fmt_.frame_rate; - shm_->area->write_offset[0] = 0; - shm2_->area->write_offset[0] = cras_shm_used_size(shm2_); - - thread_add_stream(thread_, rstream2_); - is_open_ = 1; - rc = unified_io(thread_, &ts); - - // In this case, assert (1) we didn't request the empty stream since buffer - // level is larger then its cb_threshold, (2) still mix both streams so - // dev_stream_mix_count is zero, and (3) the resulting sleep frames - // equals the cb_threshold difference. - EXPECT_EQ(0, rc); - EXPECT_EQ(2, dev_stream_mix_called); - EXPECT_GE(ts.tv_nsec, nsec_expected - 1000); - EXPECT_LE(ts.tv_nsec, nsec_expected + 1000); - EXPECT_EQ(0, dev_stream_mix_count); - EXPECT_EQ(0, dev_stream_request_playback_samples_called); -} - -TEST_F(WriteStreamSuite, PossiblyFillGetFromTwoOneEmptyAfterFetch) { - struct timespec ts; - int rc; - - // Have cb_threshold samples left. - frames_queued_ = cb_threshold_; - audio_buffer_size_ = buffer_frames_ - frames_queued_; - - // First stream empty while the second stream full. - shm_->area->write_offset[0] = 0; - shm2_->area->write_offset[0] = cras_shm_used_size(shm2_); - - thread_add_stream(thread_, rstream2_); - - FD_ZERO(&select_out_fds); - FD_SET(rstream_->fd, &select_out_fds); - select_return_value = 1; - - is_open_ = 1; - rc = unified_io(thread_, &ts); - - // Assert that the empty stream is skipped, only one stream mixed. - EXPECT_EQ(0, rc); - EXPECT_EQ(1, dev_stream_mix_called); - EXPECT_EQ(buffer_frames_ - cb_threshold_, dev_stream_mix_count); - EXPECT_EQ(1, dev_stream_request_playback_samples_called); - EXPECT_NE(-1, select_max_fd); - EXPECT_EQ(0, memcmp(&select_out_fds, &select_in_fds, sizeof(select_in_fds))); -} - -TEST_F(WriteStreamSuite, PossiblyFillGetFromTwoStreamsFullOneMixes) { - struct timespec ts; - int rc; - size_t written_expected; - - // Have cb_threshold samples left. - frames_queued_ = cb_threshold_; - audio_buffer_size_ = buffer_frames_ - frames_queued_; - written_expected = buffer_frames_ - cb_threshold_; - - // shm has plenty of data in it. - shm_->area->write_offset[0] = cras_shm_used_size(shm_); - shm2_->area->write_offset[0] = cras_shm_used_size(shm2_); - - thread_add_stream(thread_, rstream2_); - - // Test that nothing breaks if one stream doesn't fill. - dev_stream_mix_dont_fill_next = 1; - - is_open_ = 1; - rc = unified_io(thread_, &ts); - EXPECT_EQ(0, rc); - EXPECT_EQ(0, dev_stream_request_playback_samples_called); - EXPECT_EQ(0, shm_->area->read_offset[0]); // No write from first stream. - EXPECT_EQ(written_expected * 4, shm2_->area->read_offset[0]); -} - -TEST_F(WriteStreamSuite, PossiblyFillGetFromTwoStreamsOneLimited) { - struct timespec ts; - int rc; - uint64_t nsec_expected; - static const unsigned int smaller_frames = 10; - - // Have cb_threshold samples left. - frames_queued_ = cb_threshold_; - audio_buffer_size_ = buffer_frames_ - frames_queued_; - nsec_expected = - (uint64_t)smaller_frames * (1000000000ULL / (uint64_t)fmt_.frame_rate); - - // One has too little the other is full. - shm_->area->write_offset[0] = smaller_frames * 4; - shm_->area->write_buf_idx = 1; - shm2_->area->write_offset[0] = cras_shm_used_size(shm2_); - shm2_->area->write_buf_idx = 1; - - thread_add_stream(thread_, rstream2_); - - FD_ZERO(&select_out_fds); - FD_SET(rstream_->fd, &select_out_fds); - select_return_value = 1; - - is_open_ = 1; - rc = unified_io(thread_, &ts); - EXPECT_EQ(0, rc); - EXPECT_EQ(0, ts.tv_sec); - EXPECT_GE(ts.tv_nsec, nsec_expected - 1000); - EXPECT_LE(ts.tv_nsec, nsec_expected + 1000); - EXPECT_EQ(smaller_frames, dev_stream_mix_count); - EXPECT_EQ(1, dev_stream_request_playback_samples_called); - EXPECT_NE(-1, select_max_fd); -} - -TEST_F(WriteStreamSuite, DrainOutputBufferCompelete) { - frames_queued_ = 3 * cb_threshold_; - close_dev_called_ = 0; - // All the audio in hw buffer are extra silent frames. - iodev_.extra_silent_frames = frames_queued_ + 1; - drain_output_buffer(thread_, &iodev_); - EXPECT_EQ(1, close_dev_called_); -} - -TEST_F(WriteStreamSuite, DrainOutputBufferWaitForPlayback) { - // Hardware buffer is full. - frames_queued_ = buffer_frames_; - iodev_.extra_silent_frames = 0; - close_dev_called_ = 0; - drain_output_buffer(thread_, &iodev_); - EXPECT_EQ(0, close_dev_called_); -} - -TEST_F(WriteStreamSuite, DrainOutputBufferWaitForAudio) { - // Hardware buffer is almost empty - frames_queued_ = 30; - iodev_.extra_silent_frames = 0; - close_dev_called_ = 0; - drain_output_buffer(thread_, &iodev_); - EXPECT_LT(cb_threshold_ - frames_queued_, frames_written_); - EXPECT_EQ(0, close_dev_called_); -} - -TEST_F(WriteStreamSuite, DrainOutputStream) { - struct timespec ts; - int rc; - - // Have 3 * cb_threshold samples in the hw buffer. - // Have 4 * cb_threshold samples in the first stream's shm - // Note: used_size = 5 * cb_threshold. - frames_queued_ = 3 * cb_threshold_; - audio_buffer_size_ = buffer_frames_ - frames_queued_; - shm_->area->write_offset[0] = 4 * cb_threshold_ * 4; - - is_open_ = 1; - close_dev_called_ = 0; - open_dev_called_ = 0; - - thread_disconnect_stream(thread_, rstream_); - - // We should be draining the audio. - EXPECT_EQ(0, close_dev_called_); - EXPECT_EQ(0, open_dev_called_); - - rc = unified_io(thread_, &ts); - - EXPECT_EQ(0, rc); - EXPECT_EQ(2 * cb_threshold_, frames_written_); - EXPECT_EQ(0, open_dev_called_); - EXPECT_EQ(0, close_dev_called_); - - // Clear the hardware buffer - frames_queued_ = 0; - frames_written_ = 0; - audio_buffer_size_ = buffer_frames_ - frames_queued_; - - rc = unified_io(thread_, &ts); - - // Verified that all data in stream1 is written. - // The device is not closed before we have played all the content. - EXPECT_EQ(0, rc); - EXPECT_EQ(2 * cb_threshold_, frames_written_); - EXPECT_EQ(0, close_dev_called_); - - // Clear the hardware buffer again. - frames_queued_ = 0; - frames_written_ = 0; - audio_buffer_size_ = buffer_frames_ - frames_queued_; - rc = unified_io(thread_, &ts); - - EXPECT_EQ(1, cras_rstream_destroy_called); - EXPECT_EQ(1, iodev_.is_draining); - EXPECT_EQ(0, rc); - EXPECT_EQ(480, thread_->buffer_frames[CRAS_STREAM_OUTPUT]); - EXPECT_EQ(96, thread_->cb_threshold[CRAS_STREAM_OUTPUT]); - - // Clear the hardware buffer again. - frames_queued_ = 0; - frames_written_ = 0; - audio_buffer_size_ = buffer_frames_ - frames_queued_; - rc = unified_io(thread_, &ts); - - EXPECT_EQ(1, close_dev_called_); - EXPECT_EQ(0, thread_->buffer_frames[CRAS_STREAM_OUTPUT]); - EXPECT_EQ(0, thread_->cb_threshold[CRAS_STREAM_OUTPUT]); -} - -// Test adding and removing streams. -class AddStreamSuite : public testing::Test { - protected: - virtual void SetUp() { - memset(&cras_iodev_set_format_val, 0, sizeof(cras_iodev_set_format_val)); - cras_iodev_set_format_val.frame_rate = 44100; - cras_iodev_set_format_val.num_channels = 2; - cras_iodev_set_format_val.format = SND_PCM_FORMAT_S16_LE; - - memset(&iodev_, 0, sizeof(iodev_)); - iodev_.buffer_size = 16384; - used_size_ = 480; - cb_threshold_ = 96; - iodev_.direction = CRAS_STREAM_OUTPUT; - - iodev_.is_open = is_open; - iodev_.open_dev = open_dev; - iodev_.close_dev = close_dev; - iodev_.get_buffer = get_buffer; - iodev_.put_buffer = put_buffer; - - is_open_ = 0; - is_open_called_ = 0; - open_dev_called_ = 0; - close_dev_called_ = 0; - open_dev_return_val_ = 0; - - cras_iodev_set_format_called = 0; - cras_rstream_destroy_called = 0; - cras_metrics_log_histogram_called = 0; - cras_metrics_log_histogram_name = NULL; - cras_metrics_log_histogram_sample = 0; - - audio_buffer_size_ = 8196; - } - - virtual void TearDown() {} - - unsigned int GetCaptureSleepFrames() { - // Account for padding the sleep interval to ensure the wake up happens - // after the last desired frame is received. - return cb_threshold_ + 16; - } - - // Stub functions for the iodev structure. - static int get_buffer(cras_iodev* iodev, - struct cras_audio_area** area, - unsigned int* num) { - size_t sz = sizeof(*area_) + sizeof(struct cras_channel_area) * 2; - - if (audio_buffer_size_ < *num) - *num = audio_buffer_size_; - - area_ = (cras_audio_area*)calloc(1, sz); - area_->frames = *num; - area_->num_channels = 2; - area_->channels[0].buf = audio_buffer_; - channel_area_set_channel(&area_->channels[0], CRAS_CH_FL); - area_->channels[0].step_bytes = 4; - area_->channels[1].buf = audio_buffer_ + 2; - channel_area_set_channel(&area_->channels[1], CRAS_CH_FR); - area_->channels[1].step_bytes = 4; - - *area = area_; - return 0; - } - - static int put_buffer(cras_iodev* iodev, unsigned int num) { - free(area_); - return 0; - } - - static int is_open(const cras_iodev* iodev) { - is_open_called_++; - return is_open_; - } - - static int open_dev(cras_iodev* iodev) { - open_dev_called_++; - is_open_ = true; - return open_dev_return_val_; - } - - static int close_dev(cras_iodev* iodev) { - close_dev_called_++; - is_open_ = false; - return 0; - } - - void add_rm_two_streams(CRAS_STREAM_DIRECTION direction) { - int rc; - struct cras_rstream *new_stream, *second_stream; - cras_audio_shm* shm; - struct cras_audio_format* fmt; - struct audio_thread* thread; - - thread = audio_thread_create(); - - fmt = (struct cras_audio_format*)malloc(sizeof(*fmt)); - memcpy(fmt, &cras_iodev_set_format_val, sizeof(*fmt)); - iodev_.direction = direction; - new_stream = (struct cras_rstream*)calloc(1, sizeof(*new_stream)); - new_stream->fd = 55; - new_stream->buffer_frames = 65; - new_stream->cb_threshold = 80; - new_stream->direction = direction; - memcpy(&new_stream->format, fmt, sizeof(*fmt)); - shm = cras_rstream_output_shm(new_stream); - shm->header = - (struct cras_audio_shm_header*)calloc(1, sizeof(*shm->header)); - - if (direction == CRAS_STREAM_INPUT) - thread_set_active_dev(thread, &iodev_); - else - thread_set_active_dev(thread, &iodev_); - - thread_add_stream(thread, new_stream); - EXPECT_EQ(1, thread->devs_open[direction]); - EXPECT_EQ(1, open_dev_called_); - EXPECT_EQ(65, thread->buffer_frames[direction]); - if (direction == CRAS_STREAM_OUTPUT) - EXPECT_EQ(32, thread->cb_threshold[direction]); - else - EXPECT_EQ(80, thread->cb_threshold[direction]); - - is_open_ = 1; - - second_stream = (struct cras_rstream*)calloc(1, sizeof(*second_stream)); - second_stream->fd = 56; - second_stream->buffer_frames = 25; - second_stream->cb_threshold = 12; - second_stream->direction = direction; - memcpy(&second_stream->format, fmt, sizeof(*fmt)); - shm = cras_rstream_output_shm(second_stream); - shm->header = - (struct cras_audio_shm_header*)calloc(1, sizeof(*shm->header)); - - is_open_called_ = 0; - thread_add_stream(thread, second_stream); - EXPECT_EQ(1, thread->devs_open[direction]); - EXPECT_EQ(1, open_dev_called_); - EXPECT_EQ(25, thread->buffer_frames[direction]); - EXPECT_EQ(12, thread->cb_threshold[direction]); - - // Remove the streams. - rc = thread_remove_stream(thread, second_stream); - EXPECT_EQ(1, rc); - EXPECT_EQ(0, close_dev_called_); - if (direction == CRAS_STREAM_OUTPUT) - EXPECT_EQ(32, thread->cb_threshold[direction]); - else - EXPECT_EQ(80, thread->cb_threshold[direction]); - - rc = thread_remove_stream(thread, new_stream); - EXPECT_EQ(0, rc); - - // For output stream, we enter the draining mode; - // for input stream, we close the device directly. - if (direction == CRAS_STREAM_INPUT) { - EXPECT_EQ(0, thread->devs_open[direction]); - EXPECT_EQ(0, thread->buffer_frames[direction]); - EXPECT_EQ(0, thread->cb_threshold[direction]); - } else { - EXPECT_EQ(1, iodev_.is_draining); - } - - free(fmt); - shm = cras_rstream_output_shm(new_stream); - audio_thread_destroy(thread); - free(shm->header); - free(new_stream); - shm = cras_rstream_output_shm(second_stream); - free(shm->header); - free(second_stream); - } - - struct cras_iodev iodev_; - static int is_open_; - static int is_open_called_; - static int open_dev_called_; - static int open_dev_return_val_; - static int close_dev_called_; - static int used_size_; - static int cb_threshold_; - struct cras_audio_format fmt_; - static struct cras_audio_area* area_; - static uint8_t audio_buffer_[8192]; - static unsigned int audio_buffer_size_; -}; - -int AddStreamSuite::is_open_ = 0; -int AddStreamSuite::is_open_called_ = 0; -int AddStreamSuite::open_dev_called_ = 0; -int AddStreamSuite::open_dev_return_val_ = 0; -int AddStreamSuite::close_dev_called_ = 0; -int AddStreamSuite::used_size_ = 0; -int AddStreamSuite::cb_threshold_ = 0; -struct cras_audio_area* AddStreamSuite::area_; -uint8_t AddStreamSuite::audio_buffer_[8192]; -unsigned int AddStreamSuite::audio_buffer_size_ = 0; - -TEST_F(AddStreamSuite, SimpleAddOutputStream) { - int rc; - cras_rstream* new_stream; - cras_audio_shm* shm; - struct audio_thread* thread; - - thread = audio_thread_create(); - - new_stream = (struct cras_rstream*)calloc(1, sizeof(*new_stream)); - new_stream->client = (struct cras_rclient*)this; - new_stream->fd = 55; - new_stream->buffer_frames = 65; - new_stream->cb_threshold = 80; - memcpy(&new_stream->format, &cras_iodev_set_format_val, - sizeof(cras_iodev_set_format_val)); - - shm = cras_rstream_output_shm(new_stream); - shm->header = (struct cras_audio_shm_header*)calloc(1, sizeof(*shm->header)); - - thread_set_active_dev(thread, &iodev_); - - rc = thread_add_stream(thread, new_stream); - ASSERT_EQ(0, rc); - EXPECT_EQ(1, thread->devs_open[CRAS_STREAM_OUTPUT]); - EXPECT_EQ(1, open_dev_called_); - EXPECT_EQ(65, thread->buffer_frames[CRAS_STREAM_OUTPUT]); - EXPECT_EQ(32, thread->cb_threshold[CRAS_STREAM_OUTPUT]); - - is_open_ = 1; - - // remove the stream. - rc = thread_remove_stream(thread, new_stream); - EXPECT_EQ(0, rc); - EXPECT_EQ(1, iodev_.is_draining); - EXPECT_EQ(0, cras_metrics_log_histogram_called); - EXPECT_EQ(0, cras_rstream_destroy_called); - - rc = thread_disconnect_stream(thread, new_stream); - EXPECT_EQ(1, cras_rstream_destroy_called); - - free(shm->header); - audio_thread_destroy(thread); - free(new_stream); -} - -TEST_F(AddStreamSuite, AddStreamOpenFail) { - struct audio_thread* thread; - cras_rstream new_stream; - cras_audio_shm* shm; - - thread = audio_thread_create(); - ASSERT_TRUE(thread); - thread_set_active_dev(thread, &iodev_); - printf("1\n"); - - shm = cras_rstream_output_shm(&new_stream); - shm->header = (struct cras_audio_shm_header*)calloc(1, sizeof(*shm->header)); - - open_dev_return_val_ = -1; - new_stream.direction = CRAS_STREAM_OUTPUT; - EXPECT_EQ(AUDIO_THREAD_OUTPUT_DEV_ERROR, - thread_add_stream(thread, &new_stream)); - printf("2\n"); - EXPECT_EQ(1, open_dev_called_); - EXPECT_EQ(1, cras_iodev_set_format_called); - audio_thread_destroy(thread); - printf("3\n"); - free(shm->header); -} - -TEST_F(AddStreamSuite, AddRmTwoOutputStreams) { - add_rm_two_streams(CRAS_STREAM_OUTPUT); -} - -TEST_F(AddStreamSuite, AddRmTwoInputStreams) { - add_rm_two_streams(CRAS_STREAM_INPUT); -} - -TEST_F(AddStreamSuite, RmStreamLogLongestTimeout) { - int rc; - cras_rstream* new_stream; - cras_audio_shm* shm; - struct audio_thread* thread; - - thread = audio_thread_create(); - - new_stream = (struct cras_rstream*)calloc(1, sizeof(*new_stream)); - new_stream->fd = 55; - new_stream->buffer_frames = 65; - new_stream->cb_threshold = 80; - memcpy(&new_stream->format, &cras_iodev_set_format_val, - sizeof(cras_iodev_set_format_val)); - - shm = cras_rstream_output_shm(new_stream); - shm->header = (struct cras_audio_shm_header*)calloc(1, sizeof(*shm->header)); - - thread_set_active_dev(thread, &iodev_); - rc = thread_add_stream(thread, new_stream); - ASSERT_EQ(0, rc); - EXPECT_EQ(1, thread->devs_open[CRAS_STREAM_OUTPUT]); - EXPECT_EQ(1, open_dev_called_); - EXPECT_EQ(65, thread->buffer_frames[CRAS_STREAM_OUTPUT]); - EXPECT_EQ(32, thread->cb_threshold[CRAS_STREAM_OUTPUT]); - - is_open_ = 1; - cras_shm_set_longest_timeout(shm, 90); - - // remove the stream. - rc = thread_remove_stream(thread, new_stream); - EXPECT_EQ(0, rc); - EXPECT_EQ(1, iodev_.is_draining); - - cras_system_add_select_fd_callback(cras_system_add_select_fd_callback_data); - - EXPECT_EQ(1, cras_metrics_log_histogram_called); - EXPECT_STREQ(kStreamTimeoutMilliSeconds, cras_metrics_log_histogram_name); - EXPECT_EQ(90, cras_metrics_log_histogram_sample); - - free(shm->header); - free(new_stream); - audio_thread_destroy(thread); -} - -class ActiveDevicesSuite : public testing::Test { - protected: - virtual void SetUp() { - memset(&cras_iodev_set_format_val, 0, sizeof(cras_iodev_set_format_val)); - cras_iodev_set_format_val.frame_rate = 44100; - cras_iodev_set_format_val.num_channels = 2; - cras_iodev_set_format_val.format = SND_PCM_FORMAT_S16_LE; - - memset(&iodev_, 0, sizeof(iodev_)); - memset(&iodev2_, 0, sizeof(iodev2_)); - iodev_.close_dev = close_dev; - iodev_.is_open = is_open; - iodev_.open_dev = open_dev; - iodev_.delay_frames = delay_frames; - iodev_.get_buffer = get_buffer; - iodev_.put_buffer = put_buffer; - iodev_.frames_queued = frames_queued; - iodev_.delay_frames = delay_frames; - iodev_.dev_running = dev_running; - iodev_.buffer_size = 2048; - iodev2_.close_dev = close_dev; - iodev2_.is_open = is_open; - iodev2_.open_dev = open_dev; - iodev2_.delay_frames = delay_frames; - iodev2_.get_buffer = get_buffer; - iodev2_.put_buffer = put_buffer; - iodev2_.frames_queued = frames_queued; - iodev2_.delay_frames = delay_frames; - iodev2_.dev_running = dev_running; - iodev2_.buffer_size = 2048; - thread_ = audio_thread_create(); - ASSERT_TRUE(thread_); - - buffer_frames_ = 500; - cb_threshold_ = 250; - SetupRstream(&rstream_); - SetupRstream(&rstream2_); - rstream2_->buffer_frames -= 50; - rstream2_->cb_threshold -= 50; - - mock_audio_area1 = (cras_audio_area*)calloc( - 1, sizeof(cras_audio_area) + 2 * sizeof(cras_channel_area)); - mock_audio_area1->num_channels = 2; - channel_area_set_channel(&mock_audio_area1->channels[0], CRAS_CH_FL); - channel_area_set_channel(&mock_audio_area1->channels[1], CRAS_CH_FR); - rstream_->input_audio_area = mock_audio_area1; - mock_audio_area2 = (cras_audio_area*)calloc( - 1, sizeof(cras_audio_area) + 2 * sizeof(cras_channel_area)); - mock_audio_area2->num_channels = 2; - channel_area_set_channel(&mock_audio_area2->channels[0], CRAS_CH_FL); - channel_area_set_channel(&mock_audio_area2->channels[1], CRAS_CH_FR); - rstream2_->input_audio_area = mock_audio_area2; - - cras_iodev_set_format_called = 0; - close_dev_called_ = 0; - is_open_ = 0; - cras_fmt_conversion_needed_return_val = 0; - open_dev_val_idx_ = 0; - delay_frames_val_idx_ = 0; - frames_queued_val_idx_ = 0; - frames_queued_[0] = 250; - frames_queued_[1] = 250; - get_buffer_val_idx_ = 0; - put_buffer_val_idx_ = 0; - for (int i = 0; i < 8; i++) { - open_dev_val_[i] = 0; - delay_frames_[i] = 0; - audio_buffer_size_[i] = 250; - get_buffer_rc_[i] = 0; - put_buffer_rc_[i] = 0; - } - } - - virtual void TearDown() { - struct cras_audio_shm* shm; - audio_thread_destroy(thread_); - shm = cras_rstream_output_shm(rstream_); - free(shm->header); - free(rstream_); - free(mock_audio_area1); - free(mock_audio_area2); - } - - void SetupRstream(struct cras_rstream** rstream) { - struct cras_audio_shm* shm; - *rstream = (struct cras_rstream*)calloc(1, sizeof(**rstream)); - memcpy(&(*rstream)->format, &cras_iodev_set_format_val, - sizeof(cras_iodev_set_format_val)); - (*rstream)->direction = CRAS_STREAM_OUTPUT; - (*rstream)->buffer_frames = buffer_frames_; - (*rstream)->cb_threshold = cb_threshold_; - shm = cras_rstream_output_shm(*rstream); - shm->header = (struct cras_audio_shm_header*)calloc( - 1, sizeof(*shm->header) + cb_threshold_ * 8); - cras_shm_set_frame_bytes(shm, 4); - cras_shm_set_used_size(shm, buffer_frames_ * cras_shm_frame_bytes(shm)); - shm = cras_rstream_input_shm(*rstream); - shm->header = (struct cras_audio_shm_header*)calloc( - 1, sizeof(*shm->header) + buffer_frames_ * 8); - cras_shm_set_frame_bytes(shm, 4); - cras_shm_set_used_size(shm, cb_threshold_ * cras_shm_frame_bytes(shm)); - } - - static int close_dev(struct cras_iodev* iodev) { - close_dev_called_++; - return 0; - } - - static int is_open(const cras_iodev* iodev) { return is_open_; } - - static int open_dev(struct cras_iodev* iodev) { - open_dev_val_idx_ %= 8; - is_open_ = 1; - return open_dev_val_[open_dev_val_idx_++]; - } - - static int delay_frames(const cras_iodev* iodev) { - delay_frames_val_idx_ %= 8; - return delay_frames_[delay_frames_val_idx_++]; - } - - static int dev_running(const cras_iodev* iodev) { return 1; } - - static int frames_queued(const cras_iodev* iodev) { - frames_queued_val_idx_ %= 2; - return frames_queued_[frames_queued_val_idx_++]; - } - - static int get_buffer(cras_iodev* iodev, - struct cras_audio_area** area, - unsigned int* num) { - size_t sz = sizeof(*area_) + sizeof(struct cras_channel_area) * 2; - - get_buffer_val_idx_ %= 8; - if (audio_buffer_size_[get_buffer_val_idx_] < *num) - *num = audio_buffer_size_[get_buffer_val_idx_]; - - area_ = (cras_audio_area*)calloc(1, sz); - area_->frames = *num; - area_->num_channels = 2; - area_->channels[0].buf = audio_buffer_[get_buffer_val_idx_]; - channel_area_set_channel(&area_->channels[0], CRAS_CH_FL); - area_->channels[0].step_bytes = 4; - area_->channels[1].buf = audio_buffer_[get_buffer_val_idx_] + 2; - channel_area_set_channel(&area_->channels[1], CRAS_CH_FR); - area_->channels[1].step_bytes = 4; - - *area = area_; - - get_buffer_val_idx_++; - return 0; - } - - static int put_buffer(cras_iodev* iodev, unsigned int num) { - free(area_); - put_buffer_val_idx_ %= 8; - return put_buffer_rc_[put_buffer_val_idx_++]; - } - - static int is_open_; - static int open_dev_val_[8]; - static int open_dev_val_idx_; - static int close_dev_called_; - static int buffer_frames_; - static int cb_threshold_; - static int frames_queued_[2]; - static int frames_queued_val_idx_; - static uint8_t audio_buffer_[8][8192]; - static unsigned int audio_buffer_size_[8]; - static int get_buffer_rc_[8]; - static int put_buffer_rc_[8]; - static int get_buffer_val_idx_; - static int put_buffer_val_idx_; - struct cras_iodev iodev_; - struct cras_iodev iodev2_; - struct cras_rstream* rstream_; - struct cras_rstream* rstream2_; - struct audio_thread* thread_; - static struct cras_audio_area* area_; - static int delay_frames_val_idx_; - static int delay_frames_[8]; -}; - -int ActiveDevicesSuite::is_open_ = 0; -int ActiveDevicesSuite::buffer_frames_ = 0; -int ActiveDevicesSuite::cb_threshold_ = 0; -int ActiveDevicesSuite::frames_queued_[2]; -int ActiveDevicesSuite::frames_queued_val_idx_; -int ActiveDevicesSuite::close_dev_called_ = 0; -int ActiveDevicesSuite::open_dev_val_[8]; -int ActiveDevicesSuite::open_dev_val_idx_ = 0; -int ActiveDevicesSuite::delay_frames_val_idx_ = 0; -int ActiveDevicesSuite::delay_frames_[8]; -uint8_t ActiveDevicesSuite::audio_buffer_[8][8192]; -unsigned int ActiveDevicesSuite::audio_buffer_size_[8]; -int ActiveDevicesSuite::get_buffer_val_idx_ = 0; -int ActiveDevicesSuite::put_buffer_val_idx_ = 0; -int ActiveDevicesSuite::get_buffer_rc_[8]; -int ActiveDevicesSuite::put_buffer_rc_[8]; -struct cras_audio_area* ActiveDevicesSuite::area_; - -TEST_F(ActiveDevicesSuite, SetActiveDevRemoveOld) { - struct active_dev* adevs; - struct cras_iodev iodev3_; - - iodev_.direction = CRAS_STREAM_INPUT; - iodev2_.direction = CRAS_STREAM_INPUT; - iodev3_.direction = CRAS_STREAM_INPUT; - - thread_set_active_dev(thread_, &iodev_); - adevs = thread_->active_devs[CRAS_STREAM_INPUT]; - EXPECT_NE((void*)NULL, adevs); - EXPECT_EQ(adevs->dev, &iodev_); - EXPECT_EQ(1, iodev_.is_active); - - /* Assert the first active dev is still iodev. */ - thread_add_active_dev(thread_, &iodev2_); - adevs = thread_->active_devs[CRAS_STREAM_INPUT]; - EXPECT_EQ(adevs->dev, &iodev_); - - thread_set_active_dev(thread_, &iodev3_); - adevs = thread_->active_devs[CRAS_STREAM_INPUT]; - EXPECT_EQ(adevs->dev, &iodev3_); - EXPECT_EQ(iodev3_.is_active, 1); - EXPECT_EQ(iodev_.is_active, 0); -} - -TEST_F(ActiveDevicesSuite, SetActiveDevAlreadyInList) { - struct active_dev* adevs; - iodev_.direction = CRAS_STREAM_INPUT; - iodev2_.direction = CRAS_STREAM_INPUT; - - thread_set_active_dev(thread_, &iodev_); - thread_add_active_dev(thread_, &iodev2_); - - adevs = thread_->active_devs[CRAS_STREAM_INPUT]; - EXPECT_EQ(adevs->dev, &iodev_); - EXPECT_EQ(iodev_.is_active, 1); - - thread_set_active_dev(thread_, &iodev2_); - adevs = thread_->active_devs[CRAS_STREAM_INPUT]; - EXPECT_EQ(adevs->dev, &iodev2_); - EXPECT_EQ(iodev2_.is_active, 1); - EXPECT_EQ(iodev_.is_active, 0); -} - -TEST_F(ActiveDevicesSuite, AddRemoveActiveDevice) { - struct active_dev* adevs; - iodev_.direction = CRAS_STREAM_INPUT; - iodev2_.direction = CRAS_STREAM_INPUT; - - thread_set_active_dev(thread_, &iodev_); - adevs = thread_->active_devs[CRAS_STREAM_INPUT]; - EXPECT_NE((void*)NULL, adevs); - EXPECT_EQ(adevs->dev, &iodev_); - EXPECT_EQ(1, iodev_.is_active); - - thread_add_active_dev(thread_, &iodev2_); - EXPECT_NE((void*)NULL, adevs->next); - EXPECT_EQ(adevs->next->dev, &iodev2_); - EXPECT_EQ(1, iodev2_.is_active); - - thread_rm_active_dev(thread_, &iodev_); - adevs = thread_->active_devs[CRAS_STREAM_INPUT]; - EXPECT_EQ((void*)NULL, adevs->next); - EXPECT_EQ(adevs->dev, &iodev2_); - EXPECT_EQ(0, iodev_.is_active); - - iodev_.direction = CRAS_STREAM_POST_MIX_PRE_DSP; - thread_add_active_dev(thread_, &iodev_); - EXPECT_NE((void*)NULL, thread_->active_devs[CRAS_STREAM_POST_MIX_PRE_DSP]); - EXPECT_EQ(1, iodev_.is_active); -} - -TEST_F(ActiveDevicesSuite, ClearActiveDevices) { - iodev_.direction = CRAS_STREAM_OUTPUT; - iodev2_.direction = CRAS_STREAM_OUTPUT; - - thread_set_active_dev(thread_, &iodev_); - thread_add_active_dev(thread_, &iodev2_); - EXPECT_NE((void*)NULL, thread_->active_devs[CRAS_STREAM_OUTPUT]); - EXPECT_EQ(1, iodev_.is_active); - EXPECT_EQ(1, iodev2_.is_active); - - thread_clear_active_devs(thread_, CRAS_STREAM_OUTPUT); - EXPECT_EQ((void*)NULL, thread_->active_devs[CRAS_STREAM_OUTPUT]); - EXPECT_EQ(0, iodev_.is_active); - EXPECT_EQ(0, iodev2_.is_active); -} - -TEST_F(ActiveDevicesSuite, OpenActiveDevices) { - iodev_.direction = CRAS_STREAM_OUTPUT; - iodev2_.direction = CRAS_STREAM_OUTPUT; - - thread_set_active_dev(thread_, &iodev_); - thread_add_active_dev(thread_, &iodev2_); - thread_add_stream(thread_, rstream_); - - EXPECT_EQ(2, cras_iodev_set_format_called); - EXPECT_EQ(500, thread_->buffer_frames[CRAS_STREAM_OUTPUT]); - EXPECT_EQ(250, thread_->cb_threshold[CRAS_STREAM_OUTPUT]); -} - -TEST_F(ActiveDevicesSuite, OpenFirstActiveDeviceFail) { - int rc; - iodev_.direction = CRAS_STREAM_OUTPUT; - iodev2_.direction = CRAS_STREAM_OUTPUT; - - thread_set_active_dev(thread_, &iodev_); - thread_add_active_dev(thread_, &iodev2_); - - open_dev_val_[0] = -1; - rc = thread_add_stream(thread_, rstream_); - EXPECT_EQ(rc, AUDIO_THREAD_OUTPUT_DEV_ERROR); - EXPECT_EQ(2, cras_iodev_set_format_called); - EXPECT_EQ(0, thread_->buffer_frames[CRAS_STREAM_OUTPUT]); - EXPECT_EQ(0, thread_->cb_threshold[CRAS_STREAM_OUTPUT]); -} - -TEST_F(ActiveDevicesSuite, OpenSecondActiveDeviceFail) { - int rc; - iodev_.direction = CRAS_STREAM_OUTPUT; - iodev2_.direction = CRAS_STREAM_OUTPUT; - - thread_set_active_dev(thread_, &iodev_); - thread_add_active_dev(thread_, &iodev2_); - - open_dev_val_[1] = -1; - rc = thread_add_stream(thread_, rstream_); - EXPECT_EQ(0, rc); - EXPECT_EQ(2, cras_iodev_set_format_called); - EXPECT_EQ(500, thread_->buffer_frames[CRAS_STREAM_OUTPUT]); - EXPECT_EQ(250, thread_->cb_threshold[CRAS_STREAM_OUTPUT]); - EXPECT_EQ(0, close_dev_called_); - EXPECT_EQ((void*)NULL, thread_->active_devs[CRAS_STREAM_OUTPUT]->next); -} - -TEST_F(ActiveDevicesSuite, OpenSecondActiveDeviceFormatIncompatible) { - int rc; - iodev_.direction = CRAS_STREAM_OUTPUT; - iodev2_.direction = CRAS_STREAM_OUTPUT; - - thread_set_active_dev(thread_, &iodev_); - thread_add_active_dev(thread_, &iodev2_); - - cras_fmt_conversion_needed_return_val = 1; - rc = thread_add_stream(thread_, rstream_); - EXPECT_EQ(0, rc); - EXPECT_EQ(2, cras_iodev_set_format_called); - EXPECT_EQ(500, thread_->buffer_frames[CRAS_STREAM_OUTPUT]); - EXPECT_EQ(250, thread_->cb_threshold[CRAS_STREAM_OUTPUT]); - EXPECT_EQ(1, close_dev_called_); - EXPECT_EQ((void*)NULL, thread_->active_devs[CRAS_STREAM_OUTPUT]->next); -} - -TEST_F(ActiveDevicesSuite, CloseActiveDevices) { - iodev_.direction = CRAS_STREAM_OUTPUT; - iodev2_.direction = CRAS_STREAM_OUTPUT; - - thread_set_active_dev(thread_, &iodev_); - thread_add_active_dev(thread_, &iodev2_); - - thread_add_stream(thread_, rstream_); - EXPECT_EQ(1, thread_->devs_open[CRAS_STREAM_OUTPUT]); - EXPECT_EQ(2, cras_iodev_set_format_called); - - thread_add_stream(thread_, rstream2_); - EXPECT_EQ(4, cras_iodev_set_format_called); - - thread_remove_stream(thread_, rstream2_); - - thread_remove_stream(thread_, rstream_); - EXPECT_EQ(1, iodev_.is_draining); - EXPECT_EQ(1, iodev2_.is_draining); -} - -TEST_F(ActiveDevicesSuite, InputDelayFrames) { - int fr; - iodev_.direction = CRAS_STREAM_INPUT; - iodev2_.direction = CRAS_STREAM_INPUT; - rstream_->direction = CRAS_STREAM_INPUT; - - thread_set_active_dev(thread_, &iodev_); - thread_add_active_dev(thread_, &iodev2_); - - thread_add_stream(thread_, rstream_); - delay_frames_[0] = 3; - delay_frames_[1] = 33; - fr = input_delay_frames(thread_->active_devs[CRAS_STREAM_INPUT]); - EXPECT_EQ(33, fr); - - delay_frames_val_idx_ = 0; - delay_frames_[1] = -1; - fr = input_delay_frames(thread_->active_devs[CRAS_STREAM_INPUT]); - EXPECT_EQ(-1, fr); -} - -TEST_F(ActiveDevicesSuite, InputFramesQueued) { - int fr; - iodev_.direction = CRAS_STREAM_INPUT; - iodev2_.direction = CRAS_STREAM_INPUT; - thread_set_active_dev(thread_, &iodev_); - thread_add_active_dev(thread_, &iodev2_); - frames_queued_val_idx_ = 0; - frames_queued_[0] = 195; - frames_queued_[1] = 190; - fr = input_min_frames_queued(thread_->active_devs[CRAS_STREAM_INPUT]); - EXPECT_EQ(190, fr); - - /* Test error path. */ - frames_queued_val_idx_ = 0; - frames_queued_[0] = -1; - frames_queued_[1] = 190; - fr = input_min_frames_queued(thread_->active_devs[CRAS_STREAM_INPUT]); - EXPECT_EQ(-1, fr); -} - -TEST_F(ActiveDevicesSuite, MixMultipleInputs) { - struct timespec ts; - - iodev_.direction = CRAS_STREAM_INPUT; - iodev2_.direction = CRAS_STREAM_INPUT; - rstream_->direction = CRAS_STREAM_INPUT; - rstream2_->direction = CRAS_STREAM_INPUT; - - for (unsigned int dev = 0; dev < 8; dev++) { - int16_t* buff = (int16_t*)audio_buffer_[dev]; - for (unsigned int i = 0; i < 250; i++) - buff[i] = i; - } - thread_set_active_dev(thread_, &iodev_); - thread_add_active_dev(thread_, &iodev2_); - - /* Assert shm from rstream_ is used. */ - thread_add_stream(thread_, rstream_); - unified_io(thread_, &ts); - EXPECT_EQ(rstream_, cap_sleep_frames_call.dev_stream->stream); - - thread_add_stream(thread_, rstream2_); - unified_io(thread_, &ts); - EXPECT_EQ(rstream2_, cap_sleep_frames_call.dev_stream->stream); -} - -extern "C" { - -const char kNoCodecsFoundMetric[] = "Cras.NoCodecsFoundAtBoot"; -const char kStreamTimeoutMilliSeconds[] = "Cras.StreamTimeoutMilliSeconds"; - -int cras_iodev_get_thread_poll_fd(const struct cras_iodev* iodev) { - return 0; -} - -int cras_iodev_read_thread_command(struct cras_iodev* iodev, - uint8_t* buf, - size_t max_len) { - return 0; -} - -int cras_iodev_send_command_response(struct cras_iodev* iodev, int rc) { - return 0; -} - -void cras_iodev_fill_time_from_frames(size_t frames, - size_t frame_rate, - struct timespec* ts) { - uint64_t to_play_usec; - - ts->tv_sec = 0; - /* adjust sleep time to target our callback threshold */ - to_play_usec = (uint64_t)frames * 1000000L / (uint64_t)frame_rate; - - while (to_play_usec > 1000000) { - ts->tv_sec++; - to_play_usec -= 1000000; - } - ts->tv_nsec = to_play_usec * 1000; -} - -void dev_stream_set_delay(const struct dev_stream* dev_stream, - unsigned int delay_frames) { - dev_stream_set_delay_called++; -} - -void cras_set_capture_timestamp(size_t frame_rate, - size_t frames, - struct cras_timespec* ts) {} - -int cras_iodev_set_format(struct cras_iodev* iodev, - struct cras_audio_format* fmt) { - cras_iodev_set_format_called++; - iodev->format = &cras_iodev_set_format_val; - return 0; -} - -// From mixer. -unsigned int dev_stream_mix(struct dev_stream* dev_stream, - size_t num_channels, - uint8_t* dst, - size_t* count, - size_t* index) { - int16_t* src; - int16_t* target = (int16_t*)dst; - size_t fr_written, fr_in_buf; - size_t num_samples; - size_t frames = 0; - struct cras_audio_shm* shm; - - if (dev_stream->stream->direction == CRAS_STREAM_OUTPUT) { - shm = &dev_stream->stream->output_shm; - } else { - shm = &dev_stream->stream->input_shm; - } - - dev_stream_mix_called++; - - if (dev_stream_mix_dont_fill_next) { - dev_stream_mix_dont_fill_next = 0; - return 0; - } - dev_stream_mix_count = *count; - - /* We only copy the data from shm to dst, not actually mix them. */ - fr_in_buf = cras_shm_get_frames(shm); - if (fr_in_buf == 0) - return 0; - if (fr_in_buf < *count) - *count = fr_in_buf; - - fr_written = 0; - while (fr_written < *count) { - src = cras_shm_get_readable_frames(shm, fr_written, &frames); - if (frames > *count - fr_written) - frames = *count - fr_written; - num_samples = frames * num_channels; - memcpy(target, src, num_samples * 2); - fr_written += frames; - target += num_samples; - } - - *index = *index + 1; - cras_shm_buffer_read(shm, fr_written); - return *count; -} - -void cras_scale_buffer(int16_t* buffer, unsigned int count, float scaler) {} - -size_t cras_mix_mute_buffer(uint8_t* dst, size_t frame_bytes, size_t count) { - cras_mix_mute_count = count; - return count; -} - -void cras_mix_add_clip(int16_t* dst, const int16_t* src, size_t count) { - int32_t sum; - unsigned int i; - - for (i = 0; i < count; i++) { - sum = dst[i] + src[i]; - if (sum > 0x7fff) - sum = 0x7fff; - else if (sum < -0x8000) - sum = -0x8000; - dst[i] = sum; - } -} - -// From cras_metrics.c -void cras_metrics_log_event(const char* event) { - cras_metrics_log_event_called++; -} - -void cras_metrics_log_histogram(const char* name, - int sample, - int min, - int max, - int nbuckets) { - cras_metrics_log_histogram_called++; - cras_metrics_log_histogram_name = name; - cras_metrics_log_histogram_sample = sample; -} - -// From util. -int cras_set_rt_scheduling(int rt_lim) { - return 0; -} - -int cras_set_thread_priority(int priority) { - return 0; -} - -// From rstream. -int cras_rstream_get_audio_request_reply(const struct cras_rstream* stream) { - return 0; -} - -void cras_rstream_log_overrun(const struct cras_rstream* stream) {} - -int cras_system_add_select_fd(int fd, - void (*callback)(void* data), - void* callback_data) { - cras_system_add_select_fd_callback = callback; - cras_system_add_select_fd_callback_data = callback_data; - return 0; -} - -void cras_system_rm_select_fd(int fd) {} - -size_t cras_system_get_volume() { - return cras_system_get_volume_return; -} - -int cras_system_get_mute() { - return 0; -} - -int cras_system_get_capture_mute() { - return 0; -} - -void cras_rstream_destroy(struct cras_rstream* stream) { - cras_rstream_destroy_called++; -} - -void loopback_iodev_set_format(struct cras_iodev* loopback_dev, - const struct cras_audio_format* fmt) {} - -int loopback_iodev_add_audio(struct cras_iodev* loopback_dev, - const uint8_t* audio, - unsigned int count) { - return 0; -} - -int loopback_iodev_add_zeros(struct cras_iodev* dev, unsigned int count) { - return 0; -} - -int cras_fmt_conversion_needed(const struct cras_audio_format* a, - const struct cras_audio_format* b) { - return cras_fmt_conversion_needed_return_val; -} - -void cras_audio_area_config_buf_pointers(struct cras_audio_area* area, - const struct cras_audio_format* fmt, - uint8_t* base_buffer) { - unsigned int i; - const int sample_size = snd_pcm_format_physical_width(fmt->format) / 8; - - /* TODO(dgreid) - assuming interleaved audio here for now. */ - for (i = 0; i < area->num_channels; i++) { - area->channels[i].step_bytes = cras_get_format_bytes(fmt); - area->channels[i].buf = base_buffer + i * sample_size; - } -} - -void cras_audio_area_copy(const struct cras_audio_area* dst, - unsigned int dst_offset, - unsigned int dst_format_bytes, - const struct cras_audio_area* src, - unsigned int src_index) { - unsigned count, i; - int16_t *dchan, *schan; - - if (src_index == 0) - memset(dst->channels[0].buf, 0, src->frames * dst_format_bytes); - - dchan = (int16_t*)(dst->channels[0].buf + - dst_offset * dst->channels[0].step_bytes); - schan = (int16_t*)src->channels[0].buf; - count = src->frames * src->num_channels; - for (i = 0; i < count; i++) { - int32_t sum; - sum = *dchan + *schan; - if (sum > 0x7fff) - sum = 0x7fff; - else if (sum < -0x8000) - sum = -0x8000; - *dchan = sum; - dchan++; - schan++; - } -} - -// Override select so it can be stubbed. -int select(int nfds, - fd_set* readfds, - fd_set* writefds, - fd_set* exceptfds, - struct timeval* timeout) { - select_max_fd = nfds; - select_timeval.tv_sec = timeout->tv_sec; - select_timeval.tv_usec = timeout->tv_usec; - select_in_fds = *readfds; - *readfds = select_out_fds; - if (select_write_ptr) - *select_write_ptr = select_write_value; - return select_return_value; -} - -int clock_gettime(clockid_t clk_id, struct timespec* tp) { - *tp = time_now; - return 0; -} - -struct dev_stream* dev_stream_create(struct cras_rstream* stream, - const struct cras_audio_format* fmt) { - struct dev_stream* out = static_cast<dev_stream*>(calloc(1, sizeof(*out))); - out->stream = stream; - - return out; -} - -void dev_stream_destroy(struct dev_stream* dev_stream) { - free(dev_stream); -} - -void dev_stream_capture(struct dev_stream* dev_stream, - const struct cras_audio_area* area, - unsigned int dev_index) { - dev_stream_capture_call.dev_stream = dev_stream; - dev_stream_capture_call.area = area; - dev_stream_capture_call.dev_index = dev_index; - dev_stream_capture_call.num_called++; -} - -int dev_stream_playback_frames(const struct dev_stream* dev_stream) { - struct cras_audio_shm* shm; - int frames; - - shm = cras_rstream_output_shm(dev_stream->stream); - - frames = cras_shm_get_frames(shm); - if (frames < 0) - return frames; - - if (!dev_stream->conv) - return frames; - - return cras_fmt_conv_in_frames_to_out(dev_stream->conv, frames); -} - -unsigned int dev_stream_capture_avail(const struct dev_stream* dev_stream) { - struct cras_audio_shm* shm; - struct cras_rstream* rstream = dev_stream->stream; - unsigned int cb_threshold = cras_rstream_get_cb_threshold(rstream); - unsigned int frames_avail; - - shm = cras_rstream_input_shm(rstream); - - cras_shm_get_writeable_frames(shm, cb_threshold, &frames_avail); - - return frames_avail; -} - -int dev_stream_capture_sleep_frames(struct dev_stream* dev_stream, - unsigned int written) { - cap_sleep_frames_call.dev_stream = dev_stream; - cap_sleep_frames_call.written = written; - cap_sleep_frames_call.num_called++; - return 0; -} - -int dev_stream_request_playback_samples(struct dev_stream* dev_stream) { - struct cras_rstream* rstream = dev_stream->stream; - - dev_stream_request_playback_samples_called++; - - cras_shm_set_callback_pending(cras_rstream_output_shm(rstream), 1); - return 0; -} - -size_t cras_fmt_conv_in_frames_to_out(struct cras_fmt_conv* conv, - size_t in_frames) { - return in_frames; -} - -size_t cras_fmt_conv_out_frames_to_in(struct cras_fmt_conv* conv, - size_t out_frames) { - return out_frames; -} - -} // extern "C" - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} |