Skip to content

Commit 8ddd1a9

Browse files
committed
new class RCAudioPlayerOSC
1 parent 937ead6 commit 8ddd1a9

File tree

1 file changed

+198
-0
lines changed

1 file changed

+198
-0
lines changed
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
2+
#include "AudioTools/CoreAudio/AudioPlayer.h"
3+
#include "OSCData.h"
4+
5+
namespace audio_tools {
6+
7+
/**
8+
* @brief Audio Player OSC Sender: Remote control for AudioPlayer class. Sends
9+
* OSC messages to the RCAudioPlayerOSCReceiver.
10+
* @ingroup player
11+
* @ingroup communication
12+
* @author Phil Schatzmann
13+
*/
14+
class RCAudioPlayerOSCSender {
15+
RCAudioPlayerOSCSender(Print &out) { p_out = &out; }
16+
17+
void play() {
18+
uint8_t data[20];
19+
OSCData msg{data, sizeof(data)};
20+
21+
msg.setAddress("/play");
22+
msg.setFormat("");
23+
p_out->write(msg.data(), msg.size());
24+
}
25+
26+
/// halts the playing: same as setActive(false)
27+
void stop() {
28+
uint8_t data[20];
29+
OSCData msg{data, sizeof(data)};
30+
31+
msg.setAddress("/stop");
32+
msg.setFormat("");
33+
p_out->write(msg.data(), msg.size());
34+
}
35+
36+
/// moves to next file or nth next file when indicating an offset. Negative
37+
/// values are supported to move back.
38+
bool next(int offset = 1) {
39+
uint8_t data[80];
40+
OSCData msg{data, sizeof(data)};
41+
42+
msg.setAddress("/next");
43+
msg.setFormat("i");
44+
msg.write((int32_t)offset);
45+
p_out->write(msg.data(), msg.size());
46+
return true;
47+
}
48+
49+
bool previous(int offset = 1) {
50+
uint8_t data[80];
51+
OSCData msg{data, sizeof(data)};
52+
53+
msg.setAddress("/previous");
54+
msg.setFormat("i");
55+
msg.write((int32_t)offset);
56+
p_out->write(msg.data(), msg.size());
57+
return true;
58+
}
59+
60+
/// moves to the selected file position
61+
bool setIndex(int idx) {
62+
uint8_t data[80];
63+
OSCData msg{data, sizeof(data)};
64+
65+
msg.setAddress("/index");
66+
msg.setFormat("i");
67+
msg.write((int32_t)idx);
68+
p_out->write(msg.data(), msg.size());
69+
return true;
70+
}
71+
72+
/// Moves to the selected file w/o updating the actual file position
73+
bool setPath(const char *path) {
74+
uint8_t data[strlen(path) + 20];
75+
OSCData msg{data, sizeof(data)};
76+
77+
msg.setAddress("/path");
78+
msg.setFormat("s");
79+
msg.write(path);
80+
p_out->write(msg.data(), msg.size());
81+
return true;
82+
}
83+
84+
bool setVolume(float volume) {
85+
uint8_t data[80];
86+
OSCData msg{data, sizeof(data)};
87+
88+
msg.setAddress("/volume");
89+
msg.setFormat("f");
90+
msg.write(volume);
91+
p_out->write(msg.data(), msg.size());
92+
return true;
93+
}
94+
95+
protected:
96+
Print *p_out = nullptr;
97+
};
98+
99+
/**
100+
* @brief Audio Player OSC Receiver: Receives OSC messages from the
101+
* AudioPlayerOSCSender and applies it to the AudioPlayer.
102+
* @ingroup player
103+
* @ingroup communication
104+
* @author Phil Schatzmann
105+
*/
106+
class RCAudioPlayerOSCReceiver {
107+
RCAudioPlayerOSCReceiver(AudioPlayer &player) {
108+
p_player = &player;
109+
registerCallbacks();
110+
}
111+
112+
/// Process the incoming OSC messages
113+
bool processInputMessage(Stream &in) {
114+
if (!is_active) return false;
115+
116+
uint8_t data[80];
117+
size_t len = in.readBytes(data, sizeof(data));
118+
if (len > 0) {
119+
if (osc.parse(data, len)) {
120+
return true;
121+
}
122+
}
123+
return false;
124+
}
125+
126+
/// Starts the processing of the incoming OSC messages
127+
bool begin() {
128+
if (p_player == nullptr) {
129+
LOGE("RCAudioPlayerOSCReceiver: player is null");
130+
return false;
131+
}
132+
osc.setReference(p_player);
133+
is_active = true;
134+
return true;
135+
}
136+
137+
/// stops the processing of the incoming OSC messages
138+
void end() {
139+
is_active = false;
140+
osc.clear();
141+
}
142+
143+
protected:
144+
AudioPlayer *p_player = nullptr;
145+
bool is_active = false;
146+
OSCData osc;
147+
148+
static bool play(OSCData &data, void *ref) {
149+
AudioPlayer *p_player = (AudioPlayer *)ref;
150+
p_player->play();
151+
return true;
152+
}
153+
154+
static bool stop(OSCData &data, void *ref) {
155+
AudioPlayer *p_player = (AudioPlayer *)ref;
156+
p_player->stop();
157+
return true;
158+
}
159+
160+
static bool next(OSCData &data, void *ref) {
161+
AudioPlayer *p_player = (AudioPlayer *)ref;
162+
int offset = data.readInt32();
163+
return p_player->next(offset);
164+
}
165+
166+
static bool previous(OSCData &data, void *ref) {
167+
AudioPlayer *p_player = (AudioPlayer *)ref;
168+
int offset = data.readInt32();
169+
return p_player->previous(offset);
170+
}
171+
static bool setIndex(OSCData &data, void *ref) {
172+
AudioPlayer *p_player = (AudioPlayer *)ref;
173+
int idx = data.readInt32();
174+
return p_player->setIndex(idx);
175+
}
176+
static bool setPath(OSCData &data, void *ref) {
177+
AudioPlayer *p_player = (AudioPlayer *)ref;
178+
const char *path = data.readString();
179+
return p_player->setPath(path);
180+
}
181+
static bool setVolume(OSCData &data, void *ref) {
182+
AudioPlayer *p_player = (AudioPlayer *)ref;
183+
float volume = data.readFloat();
184+
return p_player->setVolume(volume);
185+
}
186+
187+
void registerCallbacks() {
188+
osc.addCallback("/play", play, OSCCompare::StartsWith);
189+
osc.addCallback("/stop", stop, OSCCompare::StartsWith);
190+
osc.addCallback("/next", next, OSCCompare::StartsWith);
191+
osc.addCallback("/previous", previous, OSCCompare::StartsWith);
192+
osc.addCallback("/index", setIndex, OSCCompare::StartsWith);
193+
osc.addCallback("/path", setPath, OSCCompare::StartsWith);
194+
osc.addCallback("/volume", setVolume, OSCCompare::StartsWith);
195+
}
196+
};
197+
198+
} // namespace audio_tools

0 commit comments

Comments
 (0)