Pitch.hpp
1 #pragma once
2 #include <Engine/Node/SimpleApi.hpp>
3 
4 #include <ossia/detail/config.hpp>
5 
6 #include <Analysis/GistState.hpp>
7 
8 #if defined(OSSIA_ENABLE_KFR)
9 #include <kfr/base.hpp>
10 #include <kfr/dsp.hpp>
11 #endif
12 
13 #include <numeric>
14 namespace Analysis
15 {
16 struct Pitch
17 {
19  {
20  static const constexpr auto prettyName = "Pitch detector";
21  static const constexpr auto objectKey = "Pitch";
22  static const constexpr auto category = "Analysis/Pitch";
23  static const constexpr auto author = "ossia score, Gist library";
24  static const constexpr auto kind = Process::ProcessCategory::Analyzer;
25  static const constexpr auto description = "Get the pitch of a signal";
26  static const constexpr auto tags = std::array<const char*, 0>{};
27  static const uuid_constexpr auto uuid
28  = make_uuid("ed511605-8265-4b2c-8c4b-d3b189539b3b");
29 
30  static const constexpr audio_in audio_ins[]{"in"};
31  static const constexpr value_out value_outs[]{"out"};
32  };
33 
34 #if defined(OSSIA_ENABLE_KFR)
35  struct State : GistState
36  {
37  State()
38  : hipass{kfr::to_sos(
39  kfr::iir_highpass(kfr::butterworth<kfr::fbase>(12), 200, this->rate))}
40  {
41  }
42 
43  void filter(ossia::audio_port& in)
44  {
45  while(hipass.size() < in.channels())
46  {
47  hipass.emplace_back(kfr::to_sos(
48  kfr::iir_highpass(kfr::butterworth<kfr::fbase>(12), 200, this->rate)));
49  }
50 
51  int c = 0;
52  for(ossia::audio_channel& chan : in)
53  {
54  hipass[c++].apply(chan.data(), chan.size());
55  }
56  }
57 
58  using hipass_t = decltype(kfr::to_sos(
59  kfr::iir_highpass(kfr::zpk<kfr::fbase>{}, kfr::identity<kfr::fbase>{})));
60  std::vector<kfr::iir_filter<kfr::fbase>> hipass;
61  };
62 #else
63  using State = GistState;
64 #endif
65  using control_policy = ossia::safe_nodes::last_tick;
66 
67  static void
68  run(const ossia::audio_port& in, ossia::value_port& out, ossia::token_request tk,
69  ossia::exec_state_facade e, State& st)
70  {
71  if(in.channels() == 0)
72  return;
73 
74 #if defined(OSSIA_ENABLE_KFR)
75  st.filter(const_cast<ossia::audio_port&>(in));
76 #endif
77  st.process<&Gist<double>::pitch>(in, out, tk, e);
78  }
79 };
80 }
Utilities for OSSIA data structures.
Definition: DeviceInterface.hpp:33
Definition: GistState.hpp:24
Definition: Pitch.hpp:19
Definition: Pitch.hpp:17
Definition: SimpleApi.hpp:32