libASPL
Loading...
Searching...
No Matches
IORequestHandler.hpp
Go to the documentation of this file.
1// Copyright (c) libASPL authors
2// Licensed under MIT
3
4//! @file aspl/IORequestHandler.hpp
5//! @brief Handler for I/O requests to device.
6
7#pragma once
8
9#include <aspl/Client.hpp>
10#include <aspl/Stream.hpp>
11
12#include <CoreFoundation/CoreFoundation.h>
13
14#include <cstring>
15#include <memory>
16
17namespace aspl {
18
19//! Handler for I/O requests to device.
20//!
21//! Device invokes methods of this class when HAL requests it to perform I/O
22//! operations. All actual I/O happens here.
23//!
24//! What methods are invoked depends on whether the device has input and output
25//! streams and what is the value of DeviceParameters::EnableMixing.
26//!
27//! All methods of this class are invoked on realtime thread and thus they
28//! should not call blocking operations.
29//!
30//! It's safe to invoke any GetXXX() and ApplyProcessing() method. It's not
31//! safe to invoke any SetXXX() and AddXXX() method and any other method
32//! that is modifying object's state.
34{
35public:
36 IORequestHandler() = default;
37
38 IORequestHandler(const IORequestHandler&) = delete;
39 IORequestHandler& operator=(const IORequestHandler&) = delete;
40
41 virtual ~IORequestHandler() = default;
42
43 //! @name Reading per-client samples from device
44 //! @{
45
46 //! Read data from device to client.
47 //!
48 //! Invoked by Device::DoIOOperation() on realtime thread.
49 //!
50 //! Should fill the destination buffer with the requested number of bytes
51 //! with data from device's stream, at given offset (timestamp).
52 //!
53 //! The output data should be in device's stream native format.
54 //!
55 //! Provided with the current current zero timestamp (last value returned by
56 //! GetZeroTimestamp()), and requested timestamp (offset of the data).
57 //! Both timestamps are measured in number of frames.
58 //!
59 //! Default implementation fills buffer with zeros.
60 virtual void OnReadClientInput(const std::shared_ptr<Client>& client,
61 const std::shared_ptr<Stream>& stream,
64 void* bytes,
66 {
68 }
69
70 //! Process data returned by ReadClientInput() before passing it to client.
71 //!
72 //! Invoked by Device::DoIOOperation() on realtime thread.
73 //!
74 //! Should modify the passed frames according to per-client or per-stream
75 //! processing rules.
76 //!
77 //! The samples are in canonical format, i.e. native endian 32-bit
78 //! interleaved floats.
79 //!
80 //! The provided buffer contains exactly @p frameCount * @p channelCount samples.
81 //!
82 //! Default implementation just invokes Stream::ApplyProcessing().
83 virtual void OnProcessClientInput(const std::shared_ptr<Client>& client,
84 const std::shared_ptr<Stream>& stream,
90 {
91 stream->ApplyProcessing(frames, frameCount, channelCount);
92 }
93
94 //! @}
95
96 //! @name Writing per-client samples to device
97 //! @{
98
99 //! Process data from client before passing it to WriteClientOutput().
100 //!
101 //! Invoked by Device::DoIOOperation() on realtime thread.
102 //!
103 //! Should modify the passed samples according to per-client or per-stream
104 //! processing rules.
105 //!
106 //! The samples are in canonical format, i.e. native endian 32-bit
107 //! interleaved floats.
108 //!
109 //! The provided buffer contains exactly @p frameCount * @p channelCount samples.
110 //!
111 //! Default implementation just invokes Stream::ApplyProcessing().
112 virtual void OnProcessClientOutput(const std::shared_ptr<Client>& client,
113 const std::shared_ptr<Stream>& stream,
119 {
120 stream->ApplyProcessing(frames, frameCount, channelCount);
121 }
122
123 //! Write data from client to device.
124 //!
125 //! Invoked by Device::DoIOOperation() on realtime thread.
126 //! Used only if DeviceParameters::EnableMixing is false.
127 //!
128 //! Should read the requested number of bytes from the provided buffer and
129 //! mix them into device at given offset (timestamp).
130 //!
131 //! The input data is already in device's stream native format.
132 //!
133 //! Provided with the current current zero timestamp (last value returned by
134 //! GetZeroTimestamp()), and requested timestamp (offset of the data).
135 //! Both timestamps are measured in number of frames.
136 //!
137 //! Default implementation does nothing.
138 virtual void OnWriteClientOutput(const std::shared_ptr<Client>& client,
139 const std::shared_ptr<Stream>& stream,
142 const Float32* frames,
145 {
146 }
147
148 //! @}
149
150 //! @name Writing mixed samples to device
151 //! @{
152
153 //! Process data from client before passing it to WriteMixedOutput().
154 //!
155 //! Invoked by Device::DoIOOperation() on realtime thread.
156 //!
157 //! Should modify the passed samples according to per-client or per-stream
158 //! processing rules.
159 //!
160 //! The samples are in canonical format, i.e. native endian 32-bit
161 //! interleaved floats.
162 //!
163 //! The provided buffer contains exactly @p frameCount * @p channelCount samples.
164 //!
165 //! Default implementation just invokes Stream::ApplyProcessing().
166 virtual void OnProcessMixedOutput(const std::shared_ptr<Stream>& stream,
172 {
173 stream->ApplyProcessing(frames, frameCount, channelCount);
174 }
175
176 //! Write mixed data from all clients to device.
177 //!
178 //! Invoked by Device::DoIOOperation() on realtime thread.
179 //! Used only if DeviceParameters::EnableMixing is true.
180 //!
181 //! Should read the requested number of bytes from the provided buffer and
182 //! write them into device at given offset (timestamp).
183 //!
184 //! The input data is already in device's stream native format.
185 //!
186 //! Provided with the current current zero timestamp (last value returned by
187 //! GetZeroTimestamp()), and requested timestamp (offset of the data).
188 //! Both timestamps are measured in number of frames.
189 //!
190 //! Default implementation does nothing.
191 virtual void OnWriteMixedOutput(const std::shared_ptr<Stream>& stream,
194 const void* bytes,
196 {
197 }
198
199 //! @}
200};
201
202} // namespace aspl
Client.
Audio stream object.
Doubly-buffered value with non-blocking read and blocking write.
Handler for I/O requests to device.
virtual void OnProcessClientOutput(const std::shared_ptr< Client > &client, const std::shared_ptr< Stream > &stream, Float64 zeroTimestamp, Float64 timestamp, Float32 *frames, UInt32 frameCount, UInt32 channelCount)
Process data from client before passing it to WriteClientOutput().
virtual void OnProcessMixedOutput(const std::shared_ptr< Stream > &stream, Float64 zeroTimestamp, Float64 timestamp, Float32 *frames, UInt32 frameCount, UInt32 channelCount)
Process data from client before passing it to WriteMixedOutput().
virtual void OnProcessClientInput(const std::shared_ptr< Client > &client, const std::shared_ptr< Stream > &stream, Float64 zeroTimestamp, Float64 timestamp, Float32 *frames, UInt32 frameCount, UInt32 channelCount)
Process data returned by ReadClientInput() before passing it to client.
virtual void OnWriteClientOutput(const std::shared_ptr< Client > &client, const std::shared_ptr< Stream > &stream, Float64 zeroTimestamp, Float64 timestamp, const Float32 *frames, UInt32 frameCount, UInt32 channelCount)
Write data from client to device.
virtual void OnWriteMixedOutput(const std::shared_ptr< Stream > &stream, Float64 zeroTimestamp, Float64 timestamp, const void *bytes, UInt32 bytesCount)
Write mixed data from all clients to device.
virtual void OnReadClientInput(const std::shared_ptr< Client > &client, const std::shared_ptr< Stream > &stream, Float64 zeroTimestamp, Float64 timestamp, void *bytes, UInt32 bytesCount)
Read data from device to client.