Skip to content

Commit

Permalink
Configurable device buffer size
Browse files Browse the repository at this point in the history
  • Loading branch information
gavv committed May 6, 2024
1 parent 83f215e commit 510c008
Show file tree
Hide file tree
Showing 12 changed files with 198 additions and 97 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ When you create sender virtual device using `roc-vad device add sender`, the fol
|--------------------------|------------------------|-----------------------------------------------------------------------------|-------------------------------|
| --device-rate | 44100 | virtual device sample rate | |
| --device-chans | stereo | virtual device channel layout (mono, stereo) | |
| --device-buffer | selected automatically | virtual device buffer size (number of samples per channel) | |
| --packet-encoding-id | 10 | encoding id for audio packets (any number, but same on sender and receiver) | for custom network encoding |
| --packet-encoding-rate | 44100 | sample rate for audio packets | for custom network encoding |
| --packet-encoding-format | s16 | sample format for audio packets (s16) | for custom network encoding |
Expand All @@ -349,6 +350,7 @@ When you create receiver virtual device using `roc-vad device add receiver`, the
|--------------------------|------------------------|-----------------------------------------------------------------------------|-----------------------------|
| --device-rate | 44100 | virtual device sample rate | |
| --device-chans | stereo | virtual device channel layout (mono, stereo) | |
| --device-buffer | selected automatically | virtual device buffer size (number of samples per channel) | |
| --packet-encoding-id | 10 | encoding id for audio packets (any number, but same on sender and receiver) | for custom network encoding |
| --packet-encoding-rate | 44100 | sample rate for audio packets | for custom network encoding |
| --packet-encoding-format | s16 | sample format for audio packets (s16) | for custom network encoding |
Expand Down
1 change: 1 addition & 0 deletions RPC.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ Defines how it is presented to apps.
| ----- | ---- | ----- | ----------- |
| sample_rate | [uint32](#uint32) | optional | Virtual device sample rate, in Hertz (e.g. 44100). Keep unset to use default. |
| channel_layout | [RvChannelLayout](#rvpb-RvChannelLayout) | optional | Virtual device channel layout (e.g. stereo). Keep unset to use default. |
| buffer_size | [uint32](#uint32) | optional | Virtual device buffer size, number of samples per channel. E.g. if sample rate is 44100 and channel layout is stereo, buffer size 44100 means 1 second. Keep unset to use default. |



Expand Down
50 changes: 29 additions & 21 deletions driver/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,6 @@ UInt32 compute_channel_count(const DeviceInfo& info)
}
}

size_t compute_buffer_size(const DeviceInfo& info)
{
if (info.device_encoding.buffer_size != 0) {
return info.device_encoding.buffer_size;
}

// one second by default (it doesn't affect latency)
return info.device_encoding.sample_rate * compute_channel_count(info);
}

aspl::DeviceParameters make_device_params(const DeviceInfo& info)
{
aspl::DeviceParameters device_params;
Expand Down Expand Up @@ -134,12 +124,12 @@ Device::Device(std::shared_ptr<aspl::Plugin> hal_plugin,
: index_allocator_(index_allocator)
, uid_generator_(uid_generator)
, hal_plugin_(hal_plugin)
, io_buf_(compute_buffer_size(device_info))
, ring_buf_(compute_buffer_size(device_info))
, info_(device_info)
{
assert(hal_plugin_);

// populate device info defaults
info_ = device_info;

if (info_.index == 0) {
info_.index = index_allocator_.allocate_and_acquire();
} else {
Expand All @@ -154,12 +144,27 @@ Device::Device(std::shared_ptr<aspl::Plugin> hal_plugin,
info_.name = fmt::format("Roc Virtual Device #{}", info_.index);
}

spdlog::info("creating device object, index={} uid={} type={} name=\"{}\"",
if (info_.device_encoding.buffer_size == 0) {
info_.device_encoding.buffer_size =
info_.device_encoding.sample_rate * compute_channel_count(info_);
}

spdlog::info(
"creating device object,"
" index={} uid={} type={} name=\"{}\" dev_rate={} dev_chans={} dev_buff={}",
info_.index,
info_.uid,
info_.type,
info_.name);
info_.name,
info_.device_encoding.sample_rate,
compute_channel_count(info_),
info_.device_encoding.buffer_size);

// create buffers
io_buf_.resize(info_.device_encoding.buffer_size);
ring_buf_ = std::make_unique<RingBuffer>(info_.device_encoding.buffer_size);

// create HAL device
hal_device_ = std::make_shared<aspl::Device>(
hal_plugin_->GetContext(), make_device_params(info_));

Expand All @@ -169,6 +174,7 @@ Device::Device(std::shared_ptr<aspl::Plugin> hal_plugin,
hal_device_->SetControlHandler(this);
hal_device_->SetIOHandler(this);

// create network sender or receiver
if (info_.type == DeviceType::Sender) {
net_transceiver_ = std::make_unique<Sender>(
info_.uid, info_.device_encoding, *info_.sender_config);
Expand All @@ -181,6 +187,7 @@ Device::Device(std::shared_ptr<aspl::Plugin> hal_plugin,
net_transceiver_->pause();
}

// bind or connect endpoints
sort_endpoints_();

for (auto& endpoint : info_.local_endpoints) {
Expand All @@ -191,6 +198,7 @@ Device::Device(std::shared_ptr<aspl::Plugin> hal_plugin,
connect_endpoint_(endpoint);
}

// enable or disable device
toggle(info_.enabled);
}

Expand Down Expand Up @@ -333,19 +341,19 @@ void Device::OnReadClientInput(const std::shared_ptr<aspl::Client>& client,
const auto sample_ptr = (float*)bytes;
const auto sample_cnt = bytes_count / sizeof(float);

const size_t wr_samples = ring_buf_.n_need_write(sample_ts + sample_cnt);
const size_t wr_samples = ring_buf_->n_need_write(sample_ts + sample_cnt);
if (wr_samples > 0) {
if (io_buf_.size() < wr_samples) {
io_buf_.resize(wr_samples);
}
// it's time to request more samples from receiver and
// append to ring buffer
net_transceiver_->read(io_buf_.data(), wr_samples);
ring_buf_.write(ring_buf_.tail_timestamp(), io_buf_.data(), wr_samples);
ring_buf_->write(ring_buf_->tail_timestamp(), io_buf_.data(), wr_samples);
}

// copy from ring buffer to client
ring_buf_.read(sample_ts, sample_ptr, sample_cnt);
ring_buf_->read(sample_ts, sample_ptr, sample_cnt);
}

// implements aspl::IORequestHandler
Expand All @@ -361,16 +369,16 @@ void Device::OnWriteMixedOutput(const std::shared_ptr<aspl::Stream>& stream,
const auto sample_cnt = bytes_count / sizeof(float);

// copy from clients to ring buffer
ring_buf_.write(sample_ts, sample_ptr, sample_cnt);
ring_buf_->write(sample_ts, sample_ptr, sample_cnt);

const size_t rd_samples = ring_buf_.n_can_read(ring_buf_pos_);
const size_t rd_samples = ring_buf_->n_can_read(ring_buf_pos_);
if (rd_samples > 0) {
if (io_buf_.size() < rd_samples) {
io_buf_.resize(rd_samples);
}
// it's time to read more samples from ring buffer and
// pass to sender
ring_buf_.read(ring_buf_pos_, io_buf_.data(), rd_samples);
ring_buf_->read(ring_buf_pos_, io_buf_.data(), rd_samples);
net_transceiver_->write(io_buf_.data(), rd_samples);
ring_buf_pos_ += rd_samples;
}
Expand Down
2 changes: 1 addition & 1 deletion driver/device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class Device : private aspl::ControlRequestHandler, private aspl::IORequestHandl

// buffers
std::vector<float> io_buf_;
RingBuffer ring_buf_;
std::unique_ptr<RingBuffer> ring_buf_;
uint64_t ring_buf_pos_ = 0;

// run-time device info
Expand Down
14 changes: 8 additions & 6 deletions driver/rpc_serdes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,9 @@ void device_info_from_rpc(DeviceInfo& out, const rvpb::RvDeviceInfo& in)
}

// device_encoding
if (in.device_encoding().has_sample_rate()) {
if (in.device_encoding().has_sample_rate() &&
in.device_encoding().sample_rate() != 0) {
out.device_encoding.sample_rate = in.device_encoding().sample_rate();

if (out.device_encoding.sample_rate == 0) {
throw std::invalid_argument(
"RvDeviceEncoding.sample_rate should be either unset or non-zero");
}
}

if (in.device_encoding().has_channel_layout()) {
Expand All @@ -148,6 +144,11 @@ void device_info_from_rpc(DeviceInfo& out, const rvpb::RvDeviceInfo& in)
in.device_encoding().channel_layout());
}

if (in.device_encoding().has_buffer_size() &&
in.device_encoding().buffer_size() != 0) {
out.device_encoding.buffer_size = in.device_encoding().buffer_size();
}

// sender_config
if (in.has_sender_config()) {
// packet_encoding
Expand Down Expand Up @@ -350,6 +351,7 @@ void device_info_to_rpc(rvpb::RvDeviceInfo& out, const DeviceInfo& in)
enum_to_rpc("RvDeviceInfo.channel_layout",
channel_layout_map,
in.device_encoding.channel_layout));
out.mutable_device_encoding()->set_buffer_size(in.device_encoding.buffer_size);

// sender_config
if (in.type == DeviceType::Sender) {
Expand Down
Loading

0 comments on commit 510c008

Please sign in to comment.