-
Notifications
You must be signed in to change notification settings - Fork 36
Expand file tree
/
Copy pathOscInput.h
More file actions
182 lines (141 loc) · 5.17 KB
/
OscInput.h
File metadata and controls
182 lines (141 loc) · 5.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
// OscInput.h
// ofxPDSP
// Nicola Pisanti, MIT License, 2016
#ifndef OFXPDSPMIDI_PDSPOSCINPUT_H_INCLUDED
#define OFXPDSPMIDI_PDSPOSCINPUT_H_INCLUDED
#include "ofMain.h"
#include <chrono>
#include <algorithm>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <atomic>
#include "../DSP/pdspCore.h"
#include "../sequencer/SequencerSection.h"
#include "ofxOsc.h"
#include "helper/OscParser.h"
/*!
@brief utility class manage OSC input to the DSP
*/
/*!
@cond HIDDEN_SYMBOLS
*/
typedef osc::ReceivedMessage _PDSPOscReceivedMessage_t;
typedef osc::IpEndpointName _PDSPIpEndpointName_t;
typedef osc::osc_bundle_element_size_t _PDSPosc_bundle_element_size_t;
/*!
@endcond
*/
namespace pdsp {
class Engine;
}
namespace pdsp{ namespace osc {
class Input : public pdsp::Preparable {
friend class pdsp::Engine;
private:
class _PositionedOscMessage {
public:
_PositionedOscMessage(){ sample = -1; };
_PositionedOscMessage(ofxOscMessage message, int sample) : message(message), sample(sample){};
std::chrono::time_point<std::chrono::high_resolution_clock> timepoint;
ofxOscMessage message;
int sample;
};
class CustomOscReceiver : public ofxOscReceiver {
public:
std::vector<_PositionedOscMessage> * circularBuffer;
std::atomic<int> * index;
protected:
void ProcessMessage(const _PDSPOscReceivedMessage_t &m, const _PDSPIpEndpointName_t &remoteEndpoint) override;
};
public:
Input();
~Input();
/*!
@brief open the port with the given index
@param[in] port OSC port
*/
void openPort( int port );
/*!
@brief shuts down the output
*/
void close();
/*!
@brief return true if the port has been sucessfully opened
*/
bool isConnected() { return connected; }
/*!
@brief enable or disable diagnostic messages
@param[in] verbose true for enabling, false for disabling
*/
void setVerbose( bool verbose );
/*!
@brief control the clock of the units and sequencer with an OSC message
@param[in] oscAddress address for OSC input
@param[in] argument index of argument from message, 0 if not gived (first argument)
*/
void linkTempo( string oscAddress, int argument=0 );
/*!
@brief get a trigger output for the given OSC address. Only the first value of those address will be taken, as float value. When you have used an address as trig output you can't use it as value
@param[in] oscAddress address for OSC input
@param[in] argument index of argument from message, 0 if not gived (first argument)
*/
pdsp::SequencerGateOutput& out_trig( string oscAddress, int argument=0 );
/*!
@brief get a value output for the given OSC address. Only the first value of those address will be taken, as float value. When you have used an address as value output you can't use it as trigger
@param[in] oscAddress address for OSC input
@param[in] argument index of argument from message, 0 if not gived (first argument)
*/
pdsp::SequencerValueOutput& out_value( string oscAddress, int argument=0 );
/*!
@brief get a reference to the parser for the selected address and argument. You can assign a lambda function to this value to elaborate the signal.
@param[in] oscAddress address for OSC input
@param[in] argument index of argument from message, 0 if not gived (first argument)
*/
std::function<float(float)> & parser( string oscAddress, int argument=0 );
/*!
@brief sets an initial value for the selected addres and argument, valid until any other OSC message is received
@param[in] oscAddress address for OSC input
@param[in] argument index of argument from message, 0 if not gived (first argument)
@param[in] value initial value for the selected address and argument
*/
void initTo( string oscAddress, int argument, float value );
/*!
@brief sends 0.0f as message to all the connected trigger and value outputs.
*/
void clearAll();
/*!
@cond HIDDEN_SYMBOLS
*/
void processOsc( int bufferSize ) noexcept;
bool hasTempoChange();
double getTempo();
/*!
@endcond
*/
protected:
void prepareToPlay( int expectedBufferSize, double sampleRate ) override;
void releaseResources() override;
private:
CustomOscReceiver receiver;
std::vector<OscParser*> parsers;
bool connected;
bool verbose;
bool sendClearMessages;
std::atomic<int> index;
int lastread;
std::vector<_PositionedOscMessage> circularBuffer;
std::vector<_PositionedOscMessage> readVector;
double oneSlashMicrosecForSample;
std::chrono::time_point<std::chrono::high_resolution_clock> bufferChrono;
bool tempoLinked;
std::string tempoAddress;
int tempoArgument;
double tempo;
bool tempoChanged;
void pushToReadVector( _PositionedOscMessage & message );
int checkParser( std::string oscAddress );
static std::vector<Input*> instances;
};
}}
#endif // OFXPDSPMIDI_PDSPOSCINPUT_H_INCLUDED