refactor Audio/Device
This commit is contained in:
parent
7b2f9c8d55
commit
4f13dd9456
@ -111,6 +111,7 @@ target_sources(nf7
|
||||
common/node_root_select_lambda.hh
|
||||
common/ptr_selector.hh
|
||||
common/queue.hh
|
||||
common/ring_buffer.hh
|
||||
common/sequencer.hh
|
||||
common/squashed_history.hh
|
||||
common/task.hh
|
||||
@ -119,7 +120,6 @@ target_sources(nf7
|
||||
common/util_algorithm.hh
|
||||
common/util_string.hh
|
||||
common/value.hh
|
||||
common/yas_audio.hh
|
||||
common/yas_enum.hh
|
||||
common/yas_imgui.hh
|
||||
common/yas_imnodes.hh
|
||||
|
102
common/ring_buffer.hh
Normal file
102
common/ring_buffer.hh
Normal file
@ -0,0 +1,102 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace nf7 {
|
||||
|
||||
class RingBuffer final {
|
||||
public:
|
||||
RingBuffer() = delete;
|
||||
RingBuffer(uint64_t unit, uint64_t bufn) noexcept :
|
||||
buf_(unit*bufn), unit_(unit), bufn_(bufn) {
|
||||
}
|
||||
RingBuffer(const RingBuffer&) = delete;
|
||||
RingBuffer(RingBuffer&&) = default;
|
||||
RingBuffer& operator=(const RingBuffer&) = delete;
|
||||
RingBuffer& operator=(RingBuffer&&) = default;
|
||||
|
||||
template <typename T>
|
||||
uint64_t Mix(uint64_t begin, const T* ptr, uint64_t n) noexcept {
|
||||
assert(unit_ == sizeof(T));
|
||||
|
||||
if (begin < cur_) {
|
||||
const auto drop = cur_ - begin;
|
||||
if (drop >= n) {
|
||||
return cur_;
|
||||
}
|
||||
ptr += drop;
|
||||
n -= drop;
|
||||
begin = cur_;
|
||||
}
|
||||
if (begin > cur_) {
|
||||
const auto skip = begin - cur_;
|
||||
n = std::min(bufn_ - skip, n);
|
||||
}
|
||||
auto buf = reinterpret_cast<T*>(buf_.data());
|
||||
|
||||
const auto [c, r, l] = CalcCursor(begin, n);
|
||||
for (uint64_t i = 0; i < r; ++i) {
|
||||
buf[c+i] += ptr[i];
|
||||
}
|
||||
for (uint64_t i = 0; i < l; ++i) {
|
||||
buf[i] += ptr[r+i];
|
||||
}
|
||||
return begin + n;
|
||||
}
|
||||
void Take(uint8_t* ptr, uint64_t n) noexcept {
|
||||
const auto [c, r, l] = CalcCursor(cur_, n);
|
||||
std::memcpy(&ptr[0*unit_], &buf_[c*unit_], r*unit_);
|
||||
std::memcpy(&ptr[r*unit_], &buf_[0*unit_], l*unit_);
|
||||
std::memset(&buf_[c*unit_], 0, r*unit_);
|
||||
std::memset(&buf_[0*unit_], 0, l*unit_);
|
||||
cur_ += n;
|
||||
}
|
||||
|
||||
uint64_t Peek(uint64_t begin, uint8_t* ptr, uint64_t n) noexcept {
|
||||
if (cur_ > bufn_) {
|
||||
const auto actual_begin = std::max(begin, cur_-bufn_);
|
||||
const auto pad = std::min(n, actual_begin - begin);
|
||||
std::memset(ptr, 0, pad*unit_);
|
||||
begin = actual_begin;
|
||||
ptr += pad*unit_;
|
||||
n -= pad;
|
||||
}
|
||||
n = std::min(n, bufn_);
|
||||
|
||||
const auto [c, r, l] = CalcCursor(begin, n);
|
||||
std::memcpy(&ptr[0*unit_], &buf_[c*unit_], r*unit_);
|
||||
std::memcpy(&ptr[r*unit_], &buf_[0*unit_], l*unit_);
|
||||
return begin + n;
|
||||
}
|
||||
void Write(const uint8_t* ptr, uint64_t n) noexcept {
|
||||
const auto [c, r, l] = CalcCursor(cur_, n);
|
||||
std::memcpy(&buf_[c*unit_], &ptr[0*unit_], r*unit_);
|
||||
std::memcpy(&buf_[0*unit_], &ptr[r*unit_], l*unit_);
|
||||
cur_ += n;
|
||||
}
|
||||
|
||||
uint64_t unit() const noexcept { return unit_; }
|
||||
uint64_t bufn() const noexcept { return bufn_; }
|
||||
uint64_t cur() const noexcept { return cur_; }
|
||||
|
||||
private:
|
||||
std::vector<uint8_t> buf_;
|
||||
uint64_t unit_;
|
||||
uint64_t bufn_;
|
||||
uint64_t cur_ = 0;
|
||||
|
||||
std::tuple<uint64_t, uint64_t, uint64_t> CalcCursor(
|
||||
uint64_t t, uint64_t n) noexcept {
|
||||
assert(n <= bufn_);
|
||||
const auto c = t % bufn_;
|
||||
const auto r = std::min(bufn_ - c, n);
|
||||
const auto l = n > r? n - r: 0;
|
||||
return {c, r, l};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace nf7
|
@ -1,86 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <miniaudio.h>
|
||||
#include <yas/serialize.hpp>
|
||||
|
||||
#include "nf7.hh"
|
||||
|
||||
|
||||
namespace yas::detail {
|
||||
|
||||
template <size_t F>
|
||||
struct serializer<
|
||||
type_prop::not_a_fundamental,
|
||||
ser_case::use_internal_serializer,
|
||||
F,
|
||||
ma_device_type> {
|
||||
public:
|
||||
template <typename Archive>
|
||||
static Archive& save(Archive& ar, const ma_device_type& t) {
|
||||
switch (t) {
|
||||
case ma_device_type_playback:
|
||||
ar("playback");
|
||||
break;
|
||||
case ma_device_type_capture:
|
||||
ar("capture");
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
return ar;
|
||||
}
|
||||
template <typename Archive>
|
||||
static Archive& load(Archive& ar, ma_device_type& t) {
|
||||
std::string v;
|
||||
ar(v);
|
||||
if (v == "playback") {
|
||||
t = ma_device_type_playback;
|
||||
} else if (v == "capture") {
|
||||
t = ma_device_type_capture;
|
||||
} else {
|
||||
throw nf7::DeserializeException("unknown device type");
|
||||
}
|
||||
return ar;
|
||||
}
|
||||
};
|
||||
|
||||
template <size_t F>
|
||||
struct serializer<
|
||||
type_prop::not_a_fundamental,
|
||||
ser_case::use_internal_serializer,
|
||||
F,
|
||||
ma_device_config> {
|
||||
public:
|
||||
template <typename Archive>
|
||||
static Archive& save(Archive& ar, const ma_device_config& v) {
|
||||
serialize(ar, v);
|
||||
return ar;
|
||||
}
|
||||
template <typename Archive>
|
||||
static Archive& load(Archive& ar, ma_device_config& v) {
|
||||
serialize(ar, v);
|
||||
if (v.sampleRate == 0) {
|
||||
throw nf7::DeserializeException("invalid sample rate");
|
||||
}
|
||||
return ar;
|
||||
}
|
||||
|
||||
private:
|
||||
static void serialize(auto& ar, auto& v) {
|
||||
ar(v.deviceType);
|
||||
ar(v.sampleRate);
|
||||
if (v.deviceType == ma_device_type_playback) {
|
||||
ar(v.playback.format);
|
||||
ar(v.playback.channels);
|
||||
} else if (v.deviceType == ma_device_type_capture) {
|
||||
ar(v.capture.format);
|
||||
ar(v.capture.channels);
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace yas::detail
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user