oveRTOS C++ API
C++20 RAII wrappers for the oveRTOS C API
Loading...
Searching...
No Matches
audio.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2026 Kamil Lulko <kamil.lulko@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-3.0-or-later
5 *
6 * This file is part of oveRTOS.
7 */
8
14#pragma once
15
16#include <ove/audio.h>
17#include <ove/audio_device.h>
18#include <ove/types.hpp>
19#include <ove/error.hpp>
20
21#ifdef CONFIG_OVE_AUDIO
22
23namespace ove::audio
24{
25
53inline struct ove_audio_device_cfg device_cfg_i2s(uint32_t sample_rate, uint32_t channels,
54 uint32_t input_device)
55{
56 struct ove_audio_device_cfg cfg {
57 };
58 cfg.transport = OVE_AUDIO_TRANSPORT_I2S;
59 cfg.fmt.sample_rate = sample_rate;
60 cfg.fmt.channels = channels;
61 cfg.fmt.sample_fmt = OVE_AUDIO_FMT_S16;
62 cfg.i2s.input_device = input_device;
63 return cfg;
64}
65
71class Graph
72{
73 public:
74 Graph() : g_{}, initialized_(false)
75 {
76 }
77
78 ~Graph() noexcept
79 {
80 if (initialized_)
81 ove_audio_graph_deinit(&g_);
82 }
83
85 [[nodiscard]] Result<void> init(unsigned int frames_per_period) noexcept
86 {
87 const int rc = ove_audio_graph_init(&g_, frames_per_period);
88 if (rc == OVE_OK)
89 initialized_ = true;
90 return from_rc(rc);
91 }
92
102 template <unsigned Nodes, unsigned Frames, unsigned Channels = 1, unsigned SampleBytes = 2>
103 [[nodiscard]] Result<void> create() noexcept
104 {
105 int rc = ove_audio_graph_init(&g_, Frames);
106 if (rc != OVE_OK)
107 return from_rc(rc);
108 initialized_ = true;
109#ifdef CONFIG_OVE_ZERO_HEAP
110 alignas(4) static unsigned char storage[OVE_AUDIO_GRAPH_STORAGE_BYTES(
111 Nodes, Frames, Channels, SampleBytes)];
112 rc = ove_audio_graph_set_buf_storage(&g_, storage, sizeof(storage));
113#endif
114 return from_rc(rc);
115 }
116
120 [[nodiscard]] Result<int> add_node(const struct ove_audio_node_ops *ops, void *ctx,
121 const char *name, enum ove_audio_node_type type) noexcept
122 {
123 const int rc = ove_audio_graph_add_node(&g_, ops, ctx, name, type);
124 if (rc >= 0)
125 return rc;
126 return std::unexpected{static_cast<Error>(rc)};
127 }
128
130 [[nodiscard]] Result<void> connect(unsigned int from, unsigned int to) noexcept
131 {
132 return from_rc(ove_audio_graph_connect(&g_, from, to));
133 }
134
136 [[nodiscard]] Result<void> build() noexcept
137 {
138 return from_rc(ove_audio_graph_build(&g_));
139 }
140
142 [[nodiscard]] Result<void> start() noexcept
143 {
144 return from_rc(ove_audio_graph_start(&g_));
145 }
146
148 [[nodiscard]] Result<void> stop() noexcept
149 {
150 return from_rc(ove_audio_graph_stop(&g_));
151 }
152
154 [[nodiscard]] Result<void> process() noexcept
155 {
156 return from_rc(ove_audio_graph_process(&g_));
157 }
158
161 [[nodiscard]] Result<struct ove_audio_graph_stats> get_stats() const noexcept
162 {
163 struct ove_audio_graph_stats stats {
164 };
165 const int rc = ove_audio_graph_get_stats(&g_, &stats);
166 return from_rc(rc, stats);
167 }
168
171 [[nodiscard]] Result<int> device_source(const struct ove_audio_device_cfg *cfg,
172 const char *name) noexcept
173 {
174 const int rc = ove_audio_device_source(&g_, cfg, name);
175 if (rc >= 0)
176 return rc;
177 return std::unexpected{static_cast<Error>(rc)};
178 }
179
182 [[nodiscard]] Result<int> device_sink(const struct ove_audio_device_cfg *cfg,
183 const char *name) noexcept
184 {
185 const int rc = ove_audio_device_sink(&g_, cfg, name);
186 if (rc >= 0)
187 return rc;
188 return std::unexpected{static_cast<Error>(rc)};
189 }
190
192 struct ove_audio_graph *raw()
193 {
194 return &g_;
195 }
196
203 template <typename T> [[nodiscard]] Result<int> add_processor(T &node, const char *name)
204 {
205 static const struct ove_audio_node_ops ops = {
206 /* configure */
207 [](void *, const struct ove_audio_fmt *in_f,
208 struct ove_audio_fmt *out_f) -> int {
209 if (in_f && out_f)
210 *out_f = *in_f;
211 return OVE_OK;
212 },
213 /* start */ nullptr,
214 /* stop */ nullptr,
215 /* process */
216 [](void *ctx, const struct ove_audio_buf *in, struct ove_audio_buf *out)
217 -> int { return static_cast<T *>(ctx)->process(in, out); },
218 /* destroy */ nullptr,
219 };
220 const int rc =
221 ove_audio_graph_add_node(&g_, &ops, &node, name, OVE_AUDIO_NODE_PROCESSOR);
222 if (rc >= 0)
223 return rc;
224 return std::unexpected{static_cast<Error>(rc)};
225 }
226
227 private:
228 struct ove_audio_graph g_;
229 bool initialized_;
230};
231
232} /* namespace ove::audio */
233
234#endif /* CONFIG_OVE_AUDIO */
C++ wrapper around ove_audio_graph.
Definition audio.hpp:72
Result< void > init(unsigned int frames_per_period) noexcept
Initialise the audio graph with the given period size.
Definition audio.hpp:85
Result< void > create() noexcept
Definition audio.hpp:103
Result< void > build() noexcept
Finalize the graph topology.
Definition audio.hpp:136
Result< struct ove_audio_graph_stats > get_stats() const noexcept
Definition audio.hpp:161
struct ove_audio_graph * raw()
Access the underlying C graph struct.
Definition audio.hpp:192
Result< void > connect(unsigned int from, unsigned int to) noexcept
Connect two nodes (output of from to input of to).
Definition audio.hpp:130
Result< int > device_sink(const struct ove_audio_device_cfg *cfg, const char *name) noexcept
Definition audio.hpp:182
Result< void > process() noexcept
Run one processing period through the graph.
Definition audio.hpp:154
Result< int > add_node(const struct ove_audio_node_ops *ops, void *ctx, const char *name, enum ove_audio_node_type type) noexcept
Definition audio.hpp:120
Result< int > add_processor(T &node, const char *name)
Definition audio.hpp:203
Result< void > start() noexcept
Start audio processing.
Definition audio.hpp:142
Result< int > device_source(const struct ove_audio_device_cfg *cfg, const char *name) noexcept
Definition audio.hpp:171
Result< void > stop() noexcept
Stop audio processing.
Definition audio.hpp:148
Strong ove::Error type, Result<T> alias, and std::error_code interop for the oveRTOS C++ binding.
Audio graph engine — typed node factories, device configuration helpers, and graph lifecycle (init/bu...
Definition audio.hpp:24
struct ove_audio_device_cfg device_cfg_i2s(uint32_t sample_rate, uint32_t channels, uint32_t input_device)
Build an audio device config for the I2S transport.
Definition audio.hpp:53
Result< void > from_rc(int rc) noexcept
Lifts a substrate rc-code into a Result<void>.
Definition error.hpp:254
Error
Strong-typed mirror of substrate OVE_ERR_* codes.
Definition error.hpp:64
std::expected< T, Error > Result
std::expected-based result alias.
Definition error.hpp:139
Common type definitions and concepts for the C++ wrapper layer.