29 int sample_rate{48000};
33 static constexpr std::size_t ring_size = 65536;
38 static constexpr std::size_t max_block = 1 << 15;
39 std::vector<std::vector<float>> ring;
40 std::atomic<std::size_t> write_pos{0};
41 std::atomic<std::size_t> read_pos{0};
44 std::vector<ossia::float_vector>* output_data{};
46 void init(
int nchannels)
48 num_channels = nchannels;
49 ring.resize(nchannels);
51 ch.resize(ring_size, 0.f);
55 void write(
const float* interleaved,
int num_samples,
int channels)
57 int nch = std::min(channels, num_channels);
58 auto wp = write_pos.load(std::memory_order_relaxed);
59 for(
int s = 0; s < num_samples; s++)
61 for(
int ch = 0; ch < nch; ch++)
62 ring[ch][(wp + s) % ring_size] = interleaved[s * channels + ch];
64 write_pos.store(wp + num_samples, std::memory_order_release);
70 ossia::small_vector<std::span<float>, 8>* output_spans{};
73 void read_into_output(
int block_size)
81 if(block_size > (
int)max_block)
82 block_size = max_block;
84 for(
auto& v : *output_data)
86 if(std::ssize(v) != block_size)
92 if(resized && output_spans && output_data)
94 const std::size_t n = std::min(output_spans->size(), output_data->size());
95 for(std::size_t i = 0; i < n; i++)
96 (*output_spans)[i] = (*output_data)[i];
99 auto rp = read_pos.load(std::memory_order_relaxed);
100 auto wp = write_pos.load(std::memory_order_acquire);
102 std::size_t available = (wp >= rp) ? (wp - rp) : 0;
104 int nch = std::min((
int)output_data->size(), num_channels);
105 if(available >= (std::size_t)block_size)
107 for(
int ch = 0; ch < nch; ch++)
109 auto& dst = (*output_data)[ch];
110 auto& src = ring[ch];
111 for(
int s = 0; s < block_size; s++)
112 dst[s] = src[(rp + s) % ring_size];
114 read_pos.store(rp + block_size, std::memory_order_release);
119 for(
int ch = 0; ch < nch; ch++)
120 std::fill_n((*output_data)[ch].data(), block_size, 0.f);