ape  0.5.0
Audio Programming Environment
processor.h
Go to the documentation of this file.
1 
3 #ifndef CPPAPE_PROCESSOR_H
4 #define CPPAPE_PROCESSOR_H
5 
6 #include "baselib.h"
8 #include "misc.h"
9 
10 namespace ape
11 {
15  struct IOConfig
16  {
17  std::size_t
25  outputs,
34 
38  double sampleRate;
39  };
40 
41  class Processor : public UIObject
42  {
43  public:
44 
48  void init() {}
52  void close() {}
53 
59  void processFrames(umatrix<const float> inputs, umatrix<float> outputs, size_t frames)
60  {
61  assert(configuration.sampleRate != 0);
62 
64  process(inputs, outputs, frames);
65  }
66 
77  virtual Status onEvent(Event * e)
78  {
79  switch (e->eventType)
80  {
81  case IOChanged:
82  {
83  const auto old = config();
84  const auto newC = *e->event.eIOChanged;
85  configuration.inputs = newC.inputs;
86  configuration.outputs = newC.outputs;
87  configuration.maxBlockSize = newC.blockSize;
88  configuration.sampleRate = newC.sampleRate;
89  return StatusCode::Handled;
90  }
91 
92  case PlayStateChanged:
93  {
94  e->event.ePlayStateChanged->isPlaying ? start(config()) : stop();
95  return StatusCode::Handled;
96  }
97 
98  default:
100  }
101  }
102 
106  virtual ~Processor()
107  {
108 
109  }
110 
114  const IOConfig& config() const
115  {
116  return configuration;
117  }
118 
122  std::size_t sharedChannels() const noexcept
123  {
124  return config().inputs > config().outputs ? config().outputs : config().inputs;
125  }
126 
127  protected:
128 
130  {
131 
132  }
133 
137  virtual void processingHook() {}
138 
146  void setTriggeringChannel(int channel)
147  {
148  getInterface().setTriggeringChannel(&getInterface(), channel);
149  }
150 
157  void defaultProcess(umatrix<const float> inputs, umatrix<float> outputs, size_t frames)
158  {
159  const auto shared = sharedChannels();
160 
161  for (std::size_t c = 0; c < shared; ++c)
162  {
163  for (std::size_t n = 0; n < frames; ++n)
164  outputs[c][n] = inputs[c][n];
165  }
166 
167  clear(outputs, shared);
168  }
169 
174  virtual void start(const IOConfig& config) { }
179  virtual void stop() { }
180 
193  virtual void process(umatrix<const float> inputs, umatrix<float> outputs, size_t frames)
194  {
195  defaultProcess(inputs, outputs, frames);
196  }
197 
198  private:
199  detail::PluginResource resource;
200  IOConfig configuration;
201  };
202 
207  {
208  public:
209 
210  Status onEvent(Event * e) override
211  {
212  if (e->eventType == PlayStateChanged && !e->event.ePlayStateChanged->isPlaying)
213  {
214  if (position.isPlaying)
215  {
216  pause();
217  position.isPlaying = false;
218  }
219  }
220 
221  return Processor::onEvent(e);
222  }
223 
224  protected:
225 
233  virtual void play() {}
241  virtual void pause() {}
242 
250  {
251  return position;
252  }
253 
254  private:
255 
256  void processingHook() override
257  {
258  bool wasTransportPlaying = position.isPlaying;
259  if (getInterface().getPlayHeadPosition(&getInterface(), &position) != 0)
260  {
261  if (wasTransportPlaying && !position.isPlaying)
262  {
263  pause();
264  }
265  else if (!wasTransportPlaying && position.isPlaying)
266  {
267  play();
268  }
269  }
270  }
271 
272  APE_PlayHeadPosition position{};
273  };
274 
279  template<class TProcessor>
281  {
282  public:
283 
284  static_assert(std::is_base_of<Processor, TProcessor>::value, "Embedded processors must derive from Processor");
285 
291  {
292  processor.init();
293  }
294 
300  {
301  processor.close();
302  }
303 
308  void start(const IOConfig& cfg)
309  {
310  APE_Event_IOChanged ioEvent;
311  ioEvent.inputs = cfg.inputs;
312  ioEvent.outputs = cfg.outputs;
313  ioEvent.blockSize = cfg.maxBlockSize;
314  ioEvent.sampleRate = cfg.sampleRate;
315 
316  APE_Event e;
317  e.eventType = IOChanged;
318  e.event.eIOChanged = &ioEvent;
319 
320  processor.onEvent(&e);
321 
322  APE_Event_PlayStateChanged playState;
323  playState.isPlaying = true;
324 
326  e.event.ePlayStateChanged = &playState;
327 
328  processor.onEvent(&e);
329  }
330 
335  void stop()
336  {
337  APE_Event e;
338 
339  APE_Event_PlayStateChanged playState;
340  playState.isPlaying = false;
341 
343  e.event.ePlayStateChanged = &playState;
344 
345  processor.onEvent(&e);
346  }
347 
351  TProcessor* operator ->()
352  {
353  return &processor;
354  }
355 
356  protected:
357 
358  TProcessor processor;
359  };
360 
361  namespace detail
362  {
363  class FactoryBase
364  {
365  public:
366  typedef Processor * (*ProcessorCreater)();
367  static void SetCreater(ProcessorCreater factory);
368 
369  };
370 
371  template<class ProcessorType>
372  class ProcessorFactory
373  {
374  public:
375 
376  static Processor * create()
377  {
378  return new ProcessorType();
379  }
380  };
381 
382 
383  template<class ProcessorType>
384  static int registerClass(ProcessorType* formal_null);
385  }
386 
387 
388 }
389 
395 #define GlobalData(type, str) \
396  class type; \
397  int __ ## type ## __unneeded = ape::detail::registerClass((type*)0);
398 
399 #endif
ape::Processor::start
virtual void start(const IOConfig &config)
Start processing with a certain configuration. Resources can be allocated here.
Definition: processor.h:174
ape::getInterface
APE_SharedInterface & getInterface()
Acquire the low-level C API.
ape::IOConfig
Configuration structure with information needed for running a plugin.
Definition: processor.h:15
APE_Event::eventType
APE_EventType eventType
Definition: Events.h:71
APE_Event::event
union APE_Event::@0 event
ape::Processor::stop
virtual void stop()
Stop processing. Here's a good place to release any large resources.
Definition: processor.h:179
ape::IOConfig::inputs
std::size_t inputs
How many inputs this plugin is initialized with
Definition: processor.h:21
ape::EmbeddedProcessor::processor
TProcessor processor
Definition: processor.h:358
IOChanged
Definition: Events.h:65
APE_Event_IOChanged::blockSize
size_t blockSize
Definition: Events.h:50
APE_Event_PlayStateChanged
Guaranteed to be mutually exclusive to any concurrent processing.
Definition: Events.h:57
ape::Processor::setTriggeringChannel
void setTriggeringChannel(int channel)
Request the oscilloscope to trigger on a specific channel (default is the first output channel from t...
Definition: processor.h:146
ape::umatrix< const float >
ape::UIObject
Base traits class for all classes that are displayed in the GUI.
Definition: baselib.h:62
ape::EmbeddedProcessor::EmbeddedProcessor
EmbeddedProcessor()
Initializes the processor. Processor::init()
Definition: processor.h:290
ape::EmbeddedProcessor::operator->
TProcessor * operator->()
Access the wrapped TProcessor instance.
Definition: processor.h:351
Events.h
ape::Processor::processFrames
void processFrames(umatrix< const float > inputs, umatrix< float > outputs, size_t frames)
Trigger processing of the inputs into the outputs . EmbeddedEffect::process, EmbeddedGenerator::proc...
Definition: processor.h:59
ape::Processor::close
void close()
Called just before any destructor is run.
Definition: processor.h:52
ape::Processor::processingHook
virtual void processingHook()
Internal use only
Definition: processor.h:137
ape::TransportProcessor::onEvent
Status onEvent(Event *e) override
Send an event to this processor.
Definition: processor.h:210
ape::StatusCode::NotImplemented
static constexpr APE_Status NotImplemented
No support for operation.
Definition: baselib.h:106
misc.h
ape::Processor::onEvent
virtual Status onEvent(Event *e)
Send an event to this processor.
Definition: processor.h:77
ape::StatusCode::Handled
static constexpr APE_Status Handled
Operation handled.
Definition: baselib.h:102
ape::EmbeddedProcessor::~EmbeddedProcessor
~EmbeddedProcessor()
Initializes the processor. Processor::init()
Definition: processor.h:299
ape::Processor::process
virtual void process(umatrix< const float > inputs, umatrix< float > outputs, size_t frames)
Callback for processing a buffer switch in real-time.
Definition: processor.h:193
ape::IOConfig::sampleRate
double sampleRate
The sample rate this plugin is running at.
Definition: processor.h:38
ape::TransportProcessor::play
virtual void play()
Callback when the projects starts to "play". stop()
Definition: processor.h:233
ape
Definition: audiofile.h:7
APE_PlayHeadPosition
juce::AudioPlayHead::CurrentPositionInfo
Definition: SharedInterface.h:100
ape::Processor::~Processor
virtual ~Processor()
Polymorphically destruct this processor
Definition: processor.h:106
APE_Event_IOChanged::inputs
size_t inputs
Definition: Events.h:48
APE_Event_PlayStateChanged::isPlaying
bool isPlaying
Definition: Events.h:59
ape::Processor::init
void init()
Called after every constructor in the inheritance chain has run
Definition: processor.h:48
ape::Processor::sharedChannels
std::size_t sharedChannels() const noexcept
Returns the minimum number of shared channels between inputs and outputs.
Definition: processor.h:122
APE_Event::eIOChanged
APE_Event_IOChanged * eIOChanged
Definition: Events.h:75
ape::TransportProcessor::pause
virtual void pause()
Callback when the project stops playback. play()
Definition: processor.h:241
APE_Event::ePlayStateChanged
APE_Event_PlayStateChanged * ePlayStateChanged
Definition: Events.h:76
baselib.h
ape::TransportProcessor::getPlayHeadPosition
const APE_PlayHeadPosition & getPlayHeadPosition()
Returns current position info about the playhead.
Definition: processor.h:249
ape::TransportProcessor
A Processor with additional access to the transport / playhead of the host.
Definition: processor.h:206
ape::Processor::defaultProcess
void defaultProcess(umatrix< const float > inputs, umatrix< float > outputs, size_t frames)
Copy the number of shared channels from inputs to outputs , clearing any extra outputs in outputs ....
Definition: processor.h:157
ape::EmbeddedProcessor::stop
void stop()
Stops the processor. Processor::stop()
Definition: processor.h:335
ape::IOConfig::maxBlockSize
std::size_t maxBlockSize
The maximum amount of sample frames that can be requested at any given time.
Definition: processor.h:21
APE_Event_IOChanged
Guaranteed to be mutually exclusive to any concurrent processing.
Definition: Events.h:46
ape::Processor
Definition: processor.h:41
APE_PlayHeadPosition::isPlaying
bool isPlaying
Definition: SharedInterface.h:135
ape::clear
void clear(std::vector< T > &arr) noexcept
Clear a uarray of non-const qualified T elements to a default-initialized value.
Definition: misc.h:652
APE_Event
Definition: Events.h:69
ape::Processor::config
const IOConfig & config() const
Return the configuration this processor is initialized with.
Definition: processor.h:114
APE_Event_IOChanged::outputs
size_t outputs
Definition: Events.h:49
ape::IOConfig::outputs
std::size_t outputs
How many outputs this plugin is initialized with
Definition: processor.h:21
PlayStateChanged
Definition: Events.h:66
ape::EmbeddedProcessor
Class for easily embedding processors within your processor. Base functionality for EmbeddedEffect an...
Definition: processor.h:280
ape::EmbeddedProcessor::start
void start(const IOConfig &cfg)
Starts the processor with a specific configuration. Processor::start()
Definition: processor.h:308
APE_Event_IOChanged::sampleRate
double sampleRate
Definition: Events.h:51
ape::Processor::Processor
Processor()
Definition: processor.h:129