2 #include <Audio/Settings/Model.hpp>
4 #include <score/application/ApplicationContext.hpp>
6 #include <ossia/dataflow/audio_port.hpp>
7 #include <ossia/dataflow/graph_node.hpp>
8 #include <ossia/dataflow/token_request.hpp>
9 #include <ossia/dataflow/value_port.hpp>
10 #include <ossia/detail/flat_map.hpp>
11 #include <ossia/network/value/value.hpp>
13 #include <Analysis/Helpers.hpp>
17 namespace ossia::safe_nodes
20 using timed_vec = ossia::flat_map<int64_t, T>;
27 explicit GistState(
int bufferSize,
int rate)
28 : bufferSize{bufferSize}
32 gist.emplace_back(bufferSize, rate);
33 gist.emplace_back(bufferSize, rate);
37 :
GistState{settings.getBufferSize(), settings.getRate()}
48 static int channels(
auto& audio) noexcept {
return audio.channels; }
50 static auto data(
auto* channel) noexcept {
return channel; }
52 static auto frames(
auto& channel,
int d) noexcept
54 if constexpr(requires { channel.size(); })
55 return channel.size();
62 static auto write_value(
auto& out_port, V&& ret)
64 if constexpr(std::is_same_v<V, ossia::impulse>)
67 out_port.value = std::move(ret);
70 void preprocess(
const auto& audio)
72 const auto N = channels(audio);
78 while(gist.size() < N)
79 gist.emplace_back(bufferSize, rate);
85 void process_mono(
const auto& audio,
auto& out_port,
int d)
88 decltype(
auto) c0 = audio.get()[0];
91 const auto samples = frames(c0, d);
94 if(g0.getAudioFrameSize() != samples)
95 g0.setAudioFrameSize(samples);
97 g0.processAudioFrame(data(c0), samples);
102 write_value(out_port, ret);
106 void process_stereo(
const auto& audio,
auto& out_port,
int d)
108 ossia::vec2f ret = {0.f, 0.f};
109 decltype(
auto) c0 = audio.get()[0];
112 const auto samples = frames(c0, d);
115 if(g0.getAudioFrameSize() != samples)
116 g0.setAudioFrameSize(samples);
118 g0.processAudioFrame(data(c0), samples);
119 ret[0] = (g0.*Func)();
122 decltype(
auto) c1 = audio.get()[1];
125 const auto samples = frames(c1, d);
128 if(g1.getAudioFrameSize() != samples)
129 g1.setAudioFrameSize(samples);
131 g1.processAudioFrame(data(c0), samples);
132 ret[1] = (g1.*Func)();
136 write_value(out_port, ret);
140 void process_multi(
const auto& audio,
auto& out_port,
int d)
142 auto it = output.begin();
143 auto git = gist.begin();
144 for(
auto& channel : audio.get())
146 const auto samples = frames(channel, d);
149 if(git->getAudioFrameSize() != samples)
150 git->setAudioFrameSize(samples);
152 git->processAudioFrame(data(channel), samples);
153 *it = float(((*git).*Func)());
163 write_value(out_port, output);
168 void process_mono(
const auto& audio,
float gain,
float gate,
auto& out_port,
int d)
171 decltype(
auto) c0 = audio.get()[0];
174 const auto samples = frames(c0, d);
177 if(g0.getAudioFrameSize() != samples)
178 g0.setAudioFrameSize(samples);
180 g0.processAudioFrame(data(c0), samples, gain, gate);
185 write_value(out_port, ret);
189 void process_stereo(
const auto& audio,
float gain,
float gate,
auto& out_port,
int d)
191 ossia::vec2f ret = {0.f, 0.f};
192 decltype(
auto) c0 = audio.get()[0];
195 const auto samples = frames(c0, d);
198 if(g0.getAudioFrameSize() != samples)
199 g0.setAudioFrameSize(samples);
201 g0.processAudioFrame(data(c0), samples, gain, gate);
202 ret[0] = (g0.*Func)();
205 decltype(
auto) c1 = audio.get()[1];
208 const auto samples = frames(c1, d);
211 if(g1.getAudioFrameSize() != samples)
212 g1.setAudioFrameSize(samples);
214 g1.processAudioFrame(data(c0), samples, gain, gate);
215 ret[1] = (g1.*Func)();
219 write_value(out_port, ret);
223 void process_multi(
const auto& audio,
float gain,
float gate,
auto& out_port,
int d)
225 auto it = output.begin();
226 auto git = gist.begin();
227 for(
auto& channel : audio.get())
229 const auto samples = frames(channel, d);
232 if(git->getAudioFrameSize() != samples)
233 git->setAudioFrameSize(samples);
235 git->processAudioFrame(data(channel), samples, gain, gate);
237 *it = r = float(((*git).*Func)());
247 write_value(out_port, output);
253 const auto& audio,
float gain,
float gate,
auto& out_port,
auto& pulse_port,
int d)
256 decltype(
auto) c0 = audio.get()[0];
259 const auto samples = frames(c0, d);
262 if(g0.getAudioFrameSize() != samples)
263 g0.setAudioFrameSize(samples);
265 g0.processAudioFrame(data(c0), samples, gain, gate);
270 write_value(out_port, ret);
273 write_value(pulse_port, ossia::impulse{});
278 const auto& audio,
float gain,
float gate,
auto& out_port,
auto& pulse_port,
int d)
280 ossia::vec2f ret = {0.f, 0.f};
281 decltype(
auto) c0 = audio.get()[0];
284 const auto samples = frames(c0, d);
287 if(g0.getAudioFrameSize() != samples)
288 g0.setAudioFrameSize(samples);
290 g0.processAudioFrame(data(c0), samples, gain, gate);
291 ret[0] = (g0.*Func)();
294 decltype(
auto) c1 = audio.get()[1];
297 const auto samples = frames(c1, d);
300 if(g1.getAudioFrameSize() != samples)
301 g1.setAudioFrameSize(samples);
303 g1.processAudioFrame(data(c0), samples, gain, gate);
304 ret[1] = (g1.*Func)();
308 write_value(out_port, ret);
309 if(ret[0] >= 1.f || ret[1] >= 1.f)
310 write_value(pulse_port, ossia::impulse{});
315 const auto& audio,
float gain,
float gate,
auto& out_port,
auto& pulse_port,
int d)
318 auto it = output.begin();
319 auto git = gist.begin();
320 for(
auto& channel : audio.get())
322 const auto samples = frames(channel, d);
325 if(git->getAudioFrameSize() != samples)
326 git->setAudioFrameSize(samples);
328 git->processAudioFrame(data(channel), samples, gain, gate);
330 *it = r = float(((*git).*Func)());
341 write_value(out_port, output);
344 write_value(pulse_port, ossia::impulse{});
348 template <
auto Func,
typename... Args>
349 void process(
const auto& audio, Args&&... args)
353 switch(channels(audio))
356 return process_mono<Func>(audio, args...);
359 return process_stereo<Func>(audio, args...);
362 return process_multi<Func>(audio, args...);
368 void processVector(
const auto& audio, ossia::audio_port& mfcc,
int d)
370 while(gist.size() < channels(audio))
371 gist.emplace_back(bufferSize, rate);
373 mfcc.set_channels(channels(audio));
374 auto it = mfcc.get().begin();
375 auto git = gist.begin();
376 for(
auto& channel : audio.get())
378 const auto samples = frames(channel, d);
381 if(git->getAudioFrameSize() != samples)
382 git->setAudioFrameSize(samples);
384 git->processAudioFrame(data(channel), samples);
386 auto& res = ((*git).*Func)();
387 it->assign(res.begin(), res.end());
400 void processVector(
const auto& audio,
float gain,
float gate,
auto& mfcc,
int d)
402 while(gist.size() < channels(audio))
403 gist.emplace_back(bufferSize, rate);
404 auto git = gist.begin();
407 double** it = mfcc.get().begin();
409 for(
auto& channel : audio.get())
411 const auto samples = frames(channel, d);
412 std::fill_n(*it, d, 0.f);
415 if(git->getAudioFrameSize() != samples)
416 git->setAudioFrameSize(samples);
418 git->processAudioFrame(data(channel), samples, gain, gate);
420 decltype(
auto) res = ((*git).*Func)();
421 SCORE_ASSERT(std::ssize(res) <= d);
422 std::copy_n(res.begin(), res.size(), *it);
429 ossia::small_vector<Gist<double>, 2> gist;
430 Analysis::analysis_vector output;
Definition: score-plugin-audio/Audio/Settings/Model.hpp:22
Definition: GistState.hpp:26
T & settings() const
Access a specific Settings model instance.
Definition: ApplicationContext.hpp:40