OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
dummy_protocol.hpp
1#pragma once
2#include <ossia/audio/audio_engine.hpp>
3#include <ossia/detail/thread.hpp>
4
5#include <thread>
6
7namespace ossia
8{
9class dummy_engine final : public audio_engine
10{
11 int effective_sample_rate{}, effective_buffer_size{};
12 std::atomic_bool m_active;
13
14public:
15 dummy_engine(int rate, int bs)
16 {
17 effective_sample_rate = rate;
18 effective_buffer_size = bs;
19 effective_inputs = 0;
20 effective_outputs = 0;
21
22 setup_thread();
23 }
24
25 bool running() const override { return m_active; }
26
27 void setup_thread()
28 {
29 m_active = true;
30
31 int us_per_buffer
32 = 1e6 * double(effective_buffer_size) / double(effective_sample_rate);
33
34 m_runThread = std::thread{[this, us_per_buffer] {
35 ossia::set_thread_name("ossia audio 0");
36 ossia::set_thread_pinned(thread_type::Audio, 0);
37 ossia::set_thread_realtime(m_runThread, 99);
38
39 using clk = std::chrono::high_resolution_clock;
40
41 clk::time_point start = clk::now();
42 auto orig_start = start;
43 auto end = start;
44 uint64_t iter_total = 0;
45 int64_t ns_total = 0;
46 int64_t ns_delta = 0;
47 while(m_active)
48 {
49 iter_total++;
50 // TODO condition variables for the sleeping instead
51 // linux :
52 // https://stackoverflow.com/questions/24051863/how-to-implement-highly-accurate-timers-in-linux-userspace
53 // win : https://stackoverflow.com/a/13413019/1495627
54 // mac : https://stackoverflow.com/a/52905687/1495627
55 // other: naive way
56 // auto time_to_sleep = std::chrono::microseconds(us_per_buffer);
57 // auto actual_next = start + time_to_sleep;
58 auto now = start;
59 auto elapsed = (now - orig_start);
60 auto expected_next_elapsed = clk::duration(iter_total * us_per_buffer);
61 // auto delta = expected_next_elapsed - elapsed;
62 double delta_p = (expected_next_elapsed.count() - elapsed.count() / 1000.);
63 if(delta_p > 0)
64 {
65 std::this_thread::sleep_for(std::chrono::microseconds((int)delta_p));
66 }
67 end = clk::now();
68 tick_start();
69 if(stop_processing)
70 {
71 start = clk::now();
72 tick_clear();
73 continue;
74 }
75
76 auto ns
77 = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count();
78 ns += ns_delta;
79 ns_total += ns;
80
81 ns_delta = std::chrono::duration_cast<std::chrono::nanoseconds>(end - orig_start)
82 .count()
83 - ns_total;
84
85 int samples = std::ceil(double(effective_sample_rate) * ns / 1e9);
86 samples = std::min(samples, effective_buffer_size);
87 if(samples < 0)
88 samples = 0;
89
90 ossia::audio_tick_state ts{nullptr, nullptr, 0,
91 0, (uint64_t)samples, ns_total / 1e9};
92 audio_tick(ts);
93
94 start = clk::now();
95 tick_end();
96 }
97 }};
98 }
99
100 void stop() override
101 {
102 audio_engine::stop();
103 m_active = false;
104 if(m_runThread.joinable())
105 m_runThread.join();
106 }
107
108 ~dummy_engine() override { stop(); }
109
110private:
111 std::thread m_runThread;
112};
113}
Definition git_info.h:7