blob: 2e84faacc25b6154ced11bead0f3a60157106cd0 [file] [log] [blame]
/* Copyright 2017 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.
*/
#include <time.h>
#include <unordered_map>
extern "C" {
#include "cras_iodev.h"
#include "dev_stream.h"
#include "utlist.h"
}
namespace {
struct cb_data {
int frames_queued_ret;
timespec frames_queued_ts;
};
std::unordered_map<cras_iodev*, cb_data> frames_queued_map;
std::unordered_map<cras_iodev*, cb_data> valid_frames_map;
std::unordered_map<cras_iodev*, timespec> drop_time_map;
std::unordered_map<const cras_iodev*, double> est_rate_ratio_map;
std::unordered_map<const cras_iodev*, int> update_rate_map;
std::unordered_map<const cras_ionode*, int> on_internal_card_map;
} // namespace
void iodev_stub_reset() {
frames_queued_map.clear();
valid_frames_map.clear();
drop_time_map.clear();
est_rate_ratio_map.clear();
update_rate_map.clear();
on_internal_card_map.clear();
}
void iodev_stub_est_rate_ratio(cras_iodev* iodev, double ratio) {
est_rate_ratio_map.insert({iodev, ratio});
}
void iodev_stub_update_rate(cras_iodev* iodev, int data) {
update_rate_map.insert({iodev, data});
}
void iodev_stub_on_internal_card(cras_ionode* node, int data) {
on_internal_card_map.insert({node, data});
}
void iodev_stub_frames_queued(cras_iodev* iodev, int ret, timespec ts) {
cb_data data = {ret, ts};
frames_queued_map.insert({iodev, data});
}
void iodev_stub_valid_frames(cras_iodev* iodev, int ret, timespec ts) {
cb_data data = {ret, ts};
valid_frames_map.insert({iodev, data});
}
bool iodev_stub_get_drop_time(cras_iodev* iodev, timespec* ts) {
auto elem = drop_time_map.find(iodev);
if (elem != drop_time_map.end()) {
*ts = elem->second;
return true;
}
return false;
}
extern "C" {
int cras_iodev_add_stream(struct cras_iodev* iodev, struct dev_stream* stream) {
DL_APPEND(iodev->streams, stream);
return 0;
}
int cras_iodev_get_valid_frames(struct cras_iodev* iodev,
struct timespec* tstamp) {
auto elem = valid_frames_map.find(iodev);
if (elem != valid_frames_map.end()) {
*tstamp = elem->second.frames_queued_ts;
return elem->second.frames_queued_ret;
}
clock_gettime(CLOCK_MONOTONIC_RAW, tstamp);
return 0;
}
double cras_iodev_get_est_rate_ratio(const struct cras_iodev* iodev) {
auto elem = est_rate_ratio_map.find(iodev);
if (elem != est_rate_ratio_map.end()) {
return elem->second;
}
return 1.0f;
}
int cras_iodev_get_dsp_delay(const struct cras_iodev* iodev) {
return 0;
}
int cras_iodev_frames_queued(struct cras_iodev* iodev,
struct timespec* tstamp) {
auto elem = frames_queued_map.find(iodev);
if (elem != frames_queued_map.end()) {
*tstamp = elem->second.frames_queued_ts;
return elem->second.frames_queued_ret;
}
clock_gettime(CLOCK_MONOTONIC_RAW, tstamp);
return 0;
}
struct dev_stream* cras_iodev_rm_stream(struct cras_iodev* iodev,
const struct cras_rstream* stream) {
return NULL;
}
int cras_iodev_update_rate(struct cras_iodev* iodev,
unsigned int level,
struct timespec* level_tstamp) {
auto elem = update_rate_map.find(iodev);
if (elem != update_rate_map.end()) {
return elem->second;
}
return 0;
}
enum CRAS_IODEV_STATE cras_iodev_state(const struct cras_iodev* iodev) {
return iodev->state;
}
unsigned int cras_iodev_all_streams_written(struct cras_iodev* iodev) {
return 0;
}
int cras_iodev_put_input_buffer(struct cras_iodev* iodev) {
return 0;
}
int cras_iodev_put_output_buffer(struct cras_iodev* iodev,
uint8_t* frames,
unsigned int nframes,
int* non_empty,
struct cras_fmt_conv* output_converter) {
return 0;
}
int cras_iodev_get_input_buffer(struct cras_iodev* iodev, unsigned* frames) {
return 0;
}
int cras_iodev_get_output_buffer(struct cras_iodev* iodev,
struct cras_audio_area** area,
unsigned* frames) {
return 0;
}
float cras_iodev_get_software_gain_scaler(const struct cras_iodev* iodev) {
return 0.0;
}
void cras_iodev_stream_written(struct cras_iodev* iodev,
struct dev_stream* stream,
unsigned int nwritten) {}
int cras_iodev_prepare_output_before_write_samples(struct cras_iodev* odev) {
return 0;
}
int cras_iodev_buffer_avail(struct cras_iodev* iodev, unsigned hw_level) {
return 0;
}
unsigned int cras_iodev_max_stream_offset(const struct cras_iodev* iodev) {
return 0;
}
int cras_iodev_odev_should_wake(const struct cras_iodev* odev) {
return 1;
}
int cras_iodev_output_underrun(struct cras_iodev* odev,
unsigned int hw_level,
unsigned int frames_written) {
return 0;
}
int cras_iodev_reset_request(struct cras_iodev* iodev) {
return 0;
}
unsigned int cras_iodev_stream_offset(struct cras_iodev* iodev,
struct dev_stream* stream) {
return 0;
}
unsigned int cras_iodev_get_num_underruns(const struct cras_iodev* iodev) {
return 0;
}
unsigned int cras_iodev_frames_to_play_in_sleep(struct cras_iodev* odev,
unsigned int* hw_level,
struct timespec* hw_tstamp) {
clock_gettime(CLOCK_MONOTONIC_RAW, hw_tstamp);
*hw_level = 0;
return 0;
}
void cras_iodev_update_highest_hw_level(struct cras_iodev* iodev,
unsigned int hw_level) {}
void cras_iodev_start_stream(struct cras_iodev* iodev,
struct dev_stream* stream) {}
int cras_iodev_drop_frames_by_time(struct cras_iodev* iodev,
struct timespec ts) {
drop_time_map.insert({iodev, ts});
return 0;
}
bool cras_iodev_is_on_internal_card(const struct cras_ionode* node) {
auto elem = on_internal_card_map.find(node);
if (elem != on_internal_card_map.end()) {
return elem->second;
}
return 1;
}
} // extern "C"