@@ -48,23 +48,23 @@ class OSCContainerEncoder : public AudioEncoder {
48
48
// target.begin();
49
49
is_active = p_codec->begin ();
50
50
p_codec->setAudioInfo (audioInfo ());
51
- writeAudioInfo ();
51
+ writeAudioInfo (audioInfo (), p_codec-> mime () );
52
52
return is_active;
53
53
}
54
54
55
55
void setAudioInfo (AudioInfo info) override {
56
56
TRACED ();
57
- writeAudioInfo ();
57
+ if (is_active) writeAudioInfo (audioInfo (), p_codec-> mime () );
58
58
AudioWriter::setAudioInfo (info);
59
59
}
60
60
61
61
// / Add data segment. On first write we also add a AudioInfo header
62
62
size_t write (const uint8_t *data, size_t len) {
63
63
LOGD (" OSCContainerEncoder::write: %d" , (int )len);
64
64
if ((repeat_info > 0 ) && (packet_count % repeat_info == 0 )) {
65
- writeAudioInfo ();
65
+ writeAudioInfo (audioInfo (), p_codec-> mime () );
66
66
}
67
- writeAudio (data, len);
67
+ writeAudio (data, len, packet_count );
68
68
packet_count++;
69
69
return len;
70
70
}
@@ -82,36 +82,39 @@ class OSCContainerEncoder : public AudioEncoder {
82
82
this ->repeat_info = packet_count;
83
83
}
84
84
85
+ // / Returns the sequence number of the next packet
86
+ uint64_t getSequenceNumber () { return packet_count; }
87
+
85
88
protected:
86
89
uint64_t packet_count = 0 ;
87
90
int repeat_info = 0 ;
88
91
bool is_active = false ;
89
92
AudioEncoder *p_codec = nullptr ;
90
93
Print *p_out = nullptr ;
91
94
92
- void writeAudio (const uint8_t *data, size_t len) {
95
+ void writeAudio (const uint8_t *data, size_t len, uint64_t packet ) {
93
96
LOGD (" writeAudio: %d" , (int )len);
94
97
uint8_t osc_data[len + 20 ]; // 20 is guess to cover address & fmt
95
98
OSCData osc{osc_data, sizeof (osc_data)};
96
99
osc.setAddress (" /audio/data" );
97
100
osc.setFormat (" ttb" );
98
101
osc.write ((uint64_t )millis ());
99
102
// we use a uint64_t for a sequence number
100
- osc.write (packet_count );
103
+ osc.write (packet );
101
104
osc.write (data, len);
102
105
p_out->write (osc_data, osc.size ());
103
106
}
104
107
105
- void writeAudioInfo () {
108
+ void writeAudioInfo (AudioInfo info, const char *mime ) {
106
109
LOGD (" writeAudioInfo" );
107
110
uint8_t osc_data[100 ];
108
111
OSCData osc{osc_data, sizeof (osc_data)};
109
112
osc.setAddress (" /audio/info" );
110
113
osc.setFormat (" iiis" );
111
- osc.write ((int32_t )audioInfo () .sample_rate );
112
- osc.write ((int32_t )audioInfo () .channels );
113
- osc.write ((int32_t )audioInfo () .bits_per_sample );
114
- osc.write (p_codec-> mime () );
114
+ osc.write ((int32_t )info .sample_rate );
115
+ osc.write ((int32_t )info .channels );
116
+ osc.write ((int32_t )info .bits_per_sample );
117
+ osc.write (mime);
115
118
p_out->write (osc_data, osc.size ());
116
119
}
117
120
};
@@ -167,16 +170,19 @@ class OSCContainerDecoder : public ContainerDecoder {
167
170
// / Provides the mime type from the encoder
168
171
const char *mime () { return mime_str.c_str (); };
169
172
170
- // / Replace the write to the decoder with a callback
171
- void setWriteCallback (
172
- bool (*write_callback)( uint64_t time, uint64_t seq, uint8_t *data,
173
- size_t len, void *ref)) {
173
+ // / Replace the write to the decoder with a callback:
174
+ void setWriteCallback (bool (*write_callback)( uint64_t time, uint64_t seq,
175
+ uint8_t *data, size_t len ,
176
+ void *ref)) {
174
177
this ->write_callback = write_callback;
175
178
}
176
179
177
180
// / Provide a reference object to the callback
178
181
void setReference (void *ref) { this ->ref = ref; }
179
182
183
+ // / Provides the sequence number of the last packet
184
+ uint64_t getSequenceNumber () { return seq_no; }
185
+
180
186
protected:
181
187
bool is_active = false ;
182
188
AudioDecoder *p_codec = nullptr ;
@@ -185,17 +191,23 @@ class OSCContainerDecoder : public ContainerDecoder {
185
191
Print *p_out = nullptr ;
186
192
OSCData osc;
187
193
Str mime_str;
188
- bool (*write_callback)(uint64_t time, uint64_t seq, uint8_t *data, size_t len, void * ref) = nullptr;
194
+ uint64_t seq_no = 0 ;
195
+ // / Return false to complete the processing w/o writing to the decoder
196
+ bool (*write_callback)(uint64_t time, uint64_t seq, uint8_t *data, size_t len,
197
+ void *ref) = nullptr ;
189
198
void *ref = nullptr ;
190
199
191
200
static bool parseData (OSCData &osc, void *ref) {
192
201
uint64_t time = osc.readTime ();
193
202
uint64_t seq = osc.readTime ();
194
203
OSCBinaryData data = osc.readData ();
195
204
OSCContainerDecoder *self = static_cast <OSCContainerDecoder *>(ref);
205
+ // store the actual sequence number
206
+ self->seq_no = seq;
196
207
// call write callbak if defined
197
208
if (self->write_callback != nullptr ) {
198
- return self->write_callback (time, seq, data.data , data.len , ref);
209
+ bool ok = self->write_callback (time, seq, data.data , data.len , ref);
210
+ if (!ok) return true ;
199
211
}
200
212
// output to decoder
201
213
if (self->p_codec != nullptr ) {
0 commit comments