34 ossia::audio_engine::fun_type tick;
35 int64_t bufferSize{512};
36 double sampleRate{44100.};
38 std::vector<std::vector<float>> inputs;
39 std::vector<std::vector<float>> outputs;
40 std::vector<float*> inputPointers;
41 std::vector<float*> outputPointers;
43 std::atomic<int64_t> requested{};
44 std::atomic<int64_t> done{};
47 ossia::audio_engine::fun_type t, int64_t bs,
double rate,
int ins,
int outs)
49 , bufferSize{std::max<int64_t>(bs, 1)}
50 , sampleRate{rate > 0. ? rate : 44100.}
51 , inputs(std::max(ins, 0), std::vector<float>(bufferSize))
52 , outputs(std::max(outs, 0), std::vector<float>(bufferSize))
55 inputPointers.push_back(c.data());
56 for(
auto& c : outputs)
57 outputPointers.push_back(c.data());
60 int64_t samplesAt(
double seconds)
const noexcept
62 return int64_t(std::floor(seconds * sampleRate + 1e-6));
65 void run(
const ossia::audio_tick_state& t)
67 for(
int chan = 0; chan < t.n_out; chan++)
68 std::fill_n(t.outputs[chan], t.frames, 0.f);
70 using clk = std::chrono::steady_clock;
71 constexpr auto linger = std::chrono::milliseconds(5);
72 auto deadline = clk::now() + linger;
75 const int64_t target = requested.load(std::memory_order_acquire);
76 int64_t cur = done.load(std::memory_order_relaxed);
81 const int64_t n = std::min(target - cur, bufferSize);
82 ossia::audio_tick_state st{
84 outputPointers.data(),
85 int32_t(inputPointers.size()),
86 int32_t(outputPointers.size()),
88 double(cur) / sampleRate};
92 done.store(cur, std::memory_order_release);
93 deadline = clk::now() + linger;
96 if(clk::now() >= deadline)
98 std::this_thread::yield();
102 bool waitFor(int64_t target,
const ossia::audio_engine& engine)
104 int64_t prev = requested.load(std::memory_order_relaxed);
106 requested.store(target, std::memory_order_release);
108 using clk = std::chrono::steady_clock;
109 const auto t0 = clk::now();
111 while(done.load(std::memory_order_acquire) < target)
113 if(!engine.running())
115 if(clk::now() - t0 > std::chrono::seconds(60))
118 std::this_thread::yield();
120 std::this_thread::sleep_for(std::chrono::microseconds(50));
151 ~Clock()
override {
delete m_widg.data(); }
154 void play_impl(
const TimeVal& t)
override
156 Dataflow::Clock::play_impl(t);
158 if(
auto win = context.doc.app.mainWindow)
161 win->addToolBar(Qt::ToolBarArea::BottomToolBarArea, m_widg);
162 QObject::connect(m_widg, &TimeWidget::advance, m_widg, [
this](
int ms) {
163 stepTo(steppedSeconds() + ms / 1000.);
169 void stop_impl()
override
171 delete m_widg.data();
172 Dataflow::Clock::stop_impl();
175 QPointer<TimeWidget> m_widg;
Definition ExecutionContext.hpp:208
Definition DocumentContext.hpp:18