diff --git a/_communication_8h_source.html b/_communication_8h_source.html
index 31fc290937..27bb8ce43c 100644
--- a/_communication_8h_source.html
+++ b/_communication_8h_source.html
@@ -719,7 +719,7 @@
- 743 int correction_ms = 0;
+ 743 int correction_us = 0;
@@ -740,32 +740,38 @@
-
-
-
- 773 void startDelay() { start_time =
millis(); }
-
-
- 776 void delayBytes(
size_t bytes) { delaySamples(bytes / bytesPerSample); }
-
-
- 779 void delaySamples(
size_t samples) {
- 780 int durationMsEff =
millis() - start_time;
- 781 int durationToBe = (samples * 1000) / info.
sample_rate;
- 782 int waitMs = durationToBe - durationMsEff + info.correction_ms;
- 783 LOGI(
"wait: %d", waitMs);
-
-
-
-
-
-
- 790 unsigned long start_time;
-
-
-
-
-
+
+
+
+
+
+ 775 start_time = micros();
+
+
+
+
+ 780 void delayBytes(
size_t bytes) { delaySamples(bytes / bytesPerSample); }
+
+
+ 783 void delaySamples(
size_t samples) {
+ 784 sum_samples += samples;
+ 785 int64_t durationUsEff = micros() - start_time;
+ 786 int64_t durationUsToBe = (sum_samples * 1000000) / info.
sample_rate;
+ 787 int64_t waitUs = durationUsToBe - durationUsEff + info.correction_us;
+ 788 LOGI(
"wait: %d", waitUs);
+
+ 790 delayMicroseconds(waitUs);
+
+
+
+
+ 795 unsigned long start_time;
+ 796 uint64_t sum_samples = 0;
+
+
+
+
+
@@ -811,7 +817,6 @@
-
diff --git a/_v_b_a_n_stream_8h_source.html b/_v_b_a_n_stream_8h_source.html
index 966f13fca9..8bfe653bb8 100644
--- a/_v_b_a_n_stream_8h_source.html
+++ b/_v_b_a_n_stream_8h_source.html
@@ -95,7 +95,7 @@
30 bool throttle_active =
false;
- 32 int throttle_correction_ms = -2;
+ 32 int throttle_correction_us = 0;
34 int max_write_size = DEFAULT_BUFFER_SIZE * 2;
@@ -113,7 +113,7 @@
57 AudioStream::setAudioInfo(info);
58 auto thc = throttle.defaultConfig();
- 60 thc.correction_ms = cfg.throttle_correction_ms;;
+ 60 thc.correction_us = cfg.throttle_correction_us;;
62 if (cfg.mode==TX_MODE){
@@ -167,230 +167,229 @@
- 114 throttle.startDelay();
-
-
-
- 118 int availableForWrite() {
- 119 return cfg.max_write_size;
-
-
- 122 size_t readBytes(uint8_t* data,
size_t byteCount)
override {
- 123 return rx_buffer.
readArray(data, byteCount);
-
-
-
-
-
-
-
- 131 const IPAddress broadcast_address{0,0,0,0};
-
-
-
-
-
- 137 bool udp_connected =
false;
- 138 uint32_t packet_counter = 0;
-
+
+
+
+ 117 int availableForWrite() {
+ 118 return cfg.max_write_size;
+
+
+ 121 size_t readBytes(uint8_t* data,
size_t byteCount)
override {
+ 122 return rx_buffer.
readArray(data, byteCount);
+
+
+
+
+
+
+
+ 130 const IPAddress broadcast_address{0,0,0,0};
+
+
+
+
+
+ 136 bool udp_connected =
false;
+ 137 uint32_t packet_counter = 0;
+
+
-
-
- 143 if (!configure_tx()){
-
-
-
- 147 if (WiFi.status() != WL_CONNECTED){
- 148 LOGE(
"Wifi not connected");
-
-
- 151 WiFi.setSleep(
false);
- 152 IPAddress myIP = WiFi.localIP();
- 153 udp_connected = udp.connect(myIP, cfg.
udp_port);
- 154 return udp_connected;
-
-
-
-
- 159 if (WiFi.status() != WL_CONNECTED){
- 160 LOGE(
"Wifi not connected");
-
-
- 163 WiFi.setSleep(
false);
- 164 udp.onPacket([
this](AsyncUDPPacket packet) {
-
-
-
-
-
-
-
- 172 int rate = vban_sample_rate();
-
-
-
-
- 177 configure_vban((VBanSampleRates)rate);
-
-
-
-
- 182 if(cfg.
ssid==
nullptr)
return;
-
- 184 LOGI(
"ssid %s", cfg.
ssid);
-
-
- 187 while (WiFi.status() != WL_CONNECTED) {
-
-
-
-
-
- 193 LOGI(
"Wifi connected to IP (%d.%d.%d.%d)",WiFi.localIP()[0],WiFi.localIP()[1],WiFi.localIP()[2],WiFi.localIP()[3]);
-
+
+ 142 if (!configure_tx()){
+
+
+
+ 146 if (WiFi.status() != WL_CONNECTED){
+ 147 LOGE(
"Wifi not connected");
+
+
+ 150 WiFi.setSleep(
false);
+ 151 IPAddress myIP = WiFi.localIP();
+ 152 udp_connected = udp.connect(myIP, cfg.
udp_port);
+ 153 return udp_connected;
+
+
+
+
+ 158 if (WiFi.status() != WL_CONNECTED){
+ 159 LOGE(
"Wifi not connected");
+
+
+ 162 WiFi.setSleep(
false);
+ 163 udp.onPacket([
this](AsyncUDPPacket packet) {
+
+
+
+
+
+
+
+ 171 int rate = vban_sample_rate();
+
+
+
+
+ 176 configure_vban((VBanSampleRates)rate);
+
+
+
+
+ 181 if(cfg.
ssid==
nullptr)
return;
+
+ 183 LOGI(
"ssid %s", cfg.
ssid);
+
+
+ 186 while (WiFi.status() != WL_CONNECTED) {
+
+
+
+
+
+ 192 LOGI(
"Wifi connected to IP (%d.%d.%d.%d)",WiFi.localIP()[0],WiFi.localIP()[1],WiFi.localIP()[2],WiFi.localIP()[3]);
+
+
-
- 197 void configure_vban(VBanSampleRates rate) {
-
-
- 200 vban.packet_counter = (uint32_t*) &vban.packet[VBAN_PACKET_HEADER_BYTES];
- 201 vban.data_frame = (uint8_t*) &vban.packet[VBAN_PACKET_HEADER_BYTES + VBAN_PACKET_COUNTER_BYTES];
-
-
- 204 strncpy(vban.hdr->preamble,
"VBAN", 4);
- 205 vban.hdr->sample_rate = VBAN_PROTOCOL_AUDIO | rate;
- 206 vban.hdr->num_samples = (VBAN_PACKET_NUM_SAMPLES / cfg.
channels)-1;
- 207 vban.hdr->num_channels = cfg.
channels - 1;
- 208 vban.hdr->sample_format = VBAN_BITFMT_16_INT | VBAN_CODEC_PCM;
-
-
- 211 vban.packet_data_bytes = (vban.hdr->num_samples+1) * (vban.hdr->num_channels+1) * ((vban.hdr->sample_format & VBAN_BIT_RESOLUTION_MASK)+1);
- 212 vban.packet_total_bytes = vban.packet_data_bytes + VBAN_PACKET_HEADER_BYTES + VBAN_PACKET_COUNTER_BYTES;
-
+ 196 void configure_vban(VBanSampleRates rate) {
+
+
+ 199 vban.packet_counter = (uint32_t*) &vban.packet[VBAN_PACKET_HEADER_BYTES];
+ 200 vban.data_frame = (uint8_t*) &vban.packet[VBAN_PACKET_HEADER_BYTES + VBAN_PACKET_COUNTER_BYTES];
+
+
+ 203 strncpy(vban.hdr->preamble,
"VBAN", 4);
+ 204 vban.hdr->sample_rate = VBAN_PROTOCOL_AUDIO | rate;
+ 205 vban.hdr->num_samples = (VBAN_PACKET_NUM_SAMPLES / cfg.
channels)-1;
+ 206 vban.hdr->num_channels = cfg.
channels - 1;
+ 207 vban.hdr->sample_format = VBAN_BITFMT_16_INT | VBAN_CODEC_PCM;
+
+
+ 210 vban.packet_data_bytes = (vban.hdr->num_samples+1) * (vban.hdr->num_channels+1) * ((vban.hdr->sample_format & VBAN_BIT_RESOLUTION_MASK)+1);
+ 211 vban.packet_total_bytes = vban.packet_data_bytes + VBAN_PACKET_HEADER_BYTES + VBAN_PACKET_COUNTER_BYTES;
+
+
-
- 216 int vban_sample_rate(){
-
-
-
- 220 result = SAMPLE_RATE_6000_HZ;
-
-
- 223 result = SAMPLE_RATE_12000_HZ;
-
-
- 226 result = SAMPLE_RATE_24000_HZ;
-
-
- 229 result = SAMPLE_RATE_48000_HZ;
-
-
- 232 result = SAMPLE_RATE_96000_HZ;
-
-
- 235 result = SAMPLE_RATE_192000_HZ;
-
-
- 238 result = SAMPLE_RATE_384000_HZ;
-
-
- 241 result = SAMPLE_RATE_8000_HZ;
-
-
- 244 result = SAMPLE_RATE_16000_HZ;
-
-
- 247 result = SAMPLE_RATE_32000_HZ;
-
-
- 250 result = SAMPLE_RATE_64000_HZ;
-
-
- 253 result = SAMPLE_RATE_128000_HZ;
-
-
- 256 result = SAMPLE_RATE_256000_HZ;
-
-
- 259 result = SAMPLE_RATE_512000_HZ;
-
-
- 262 result = SAMPLE_RATE_11025_HZ;
-
-
- 265 result = SAMPLE_RATE_22050_HZ;
-
-
- 268 result = SAMPLE_RATE_44100_HZ;
-
-
- 271 result = SAMPLE_RATE_88200_HZ;
-
-
- 274 result = SAMPLE_RATE_176400_HZ;
-
-
- 277 result = SAMPLE_RATE_352800_HZ;
-
-
- 280 result = SAMPLE_RATE_705600_HZ;
-
-
-
-
-
-
- 302 uint16_t vban_rx_data_bytes, vban_rx_sample_count;
- 303 int16_t* vban_rx_data;
- 304 uint32_t* vban_rx_pkt_nbr;
- 305 uint16_t outBuf[VBAN_PACKET_MAX_SAMPLES+1];
-
-
- 308 int len = packet.length();
-
- 310 uint8_t* udpIncomingPacket = packet.data();
-
-
-
- 314 if (len<=(VBAN_PACKET_HEADER_BYTES+VBAN_PACKET_COUNTER_BYTES) || len>VBAN_PACKET_MAX_LEN_BYTES) {
- 315 LOGE(
"Error: packet length %u bytes\n", len);
-
-
-
-
- 320 if(strncmp(
"VBAN",(
const char*)udpIncomingPacket,4)!=0){
- 321 LOGE(
"Unrecognized preamble %.4s\n", udpIncomingPacket);
-
-
-
- 325 vban_rx_data_bytes = len - (VBAN_PACKET_HEADER_BYTES+VBAN_PACKET_COUNTER_BYTES);
- 326 vban_rx_pkt_nbr = (uint32_t*)&udpIncomingPacket[VBAN_PACKET_HEADER_BYTES];
- 327 vban_rx_data = (int16_t*)&udpIncomingPacket[VBAN_PACKET_HEADER_BYTES+VBAN_PACKET_COUNTER_BYTES];
- 328 vban_rx_sample_count = vban_rx_data_bytes/2;
- 329 uint8_t vbanSampleRateIdx = udpIncomingPacket[4] & VBAN_SR_MASK;
- 330 uint8_t vbchannels = udpIncomingPacket[6]+1;
- 331 uint32_t vbanSampleRate = VBanSRList[vbanSampleRateIdx];
-
-
- 334 if(vban_rx_sample_count > VBAN_PACKET_MAX_SAMPLES){
- 335 LOGE(
"error: unexpected packet size: %u\n",vban_rx_sample_count);
-
-
-
-
-
-
-
-
-
-
-
- 347 rx_buffer.
writeArray((uint8_t*)&vban_rx_data, vban_rx_sample_count*
sizeof(uint16_t));
-
-
-
-
-
+ 215 int vban_sample_rate(){
+
+
+
+ 219 result = SAMPLE_RATE_6000_HZ;
+
+
+ 222 result = SAMPLE_RATE_12000_HZ;
+
+
+ 225 result = SAMPLE_RATE_24000_HZ;
+
+
+ 228 result = SAMPLE_RATE_48000_HZ;
+
+
+ 231 result = SAMPLE_RATE_96000_HZ;
+
+
+ 234 result = SAMPLE_RATE_192000_HZ;
+
+
+ 237 result = SAMPLE_RATE_384000_HZ;
+
+
+ 240 result = SAMPLE_RATE_8000_HZ;
+
+
+ 243 result = SAMPLE_RATE_16000_HZ;
+
+
+ 246 result = SAMPLE_RATE_32000_HZ;
+
+
+ 249 result = SAMPLE_RATE_64000_HZ;
+
+
+ 252 result = SAMPLE_RATE_128000_HZ;
+
+
+ 255 result = SAMPLE_RATE_256000_HZ;
+
+
+ 258 result = SAMPLE_RATE_512000_HZ;
+
+
+ 261 result = SAMPLE_RATE_11025_HZ;
+
+
+ 264 result = SAMPLE_RATE_22050_HZ;
+
+
+ 267 result = SAMPLE_RATE_44100_HZ;
+
+
+ 270 result = SAMPLE_RATE_88200_HZ;
+
+
+ 273 result = SAMPLE_RATE_176400_HZ;
+
+
+ 276 result = SAMPLE_RATE_352800_HZ;
+
+
+ 279 result = SAMPLE_RATE_705600_HZ;
+
+
+
+
+
+
+ 301 uint16_t vban_rx_data_bytes, vban_rx_sample_count;
+ 302 int16_t* vban_rx_data;
+ 303 uint32_t* vban_rx_pkt_nbr;
+ 304 uint16_t outBuf[VBAN_PACKET_MAX_SAMPLES+1];
+
+
+ 307 int len = packet.length();
+
+ 309 uint8_t* udpIncomingPacket = packet.data();
+
+
+
+ 313 if (len<=(VBAN_PACKET_HEADER_BYTES+VBAN_PACKET_COUNTER_BYTES) || len>VBAN_PACKET_MAX_LEN_BYTES) {
+ 314 LOGE(
"Error: packet length %u bytes\n", len);
+
+
+
+
+ 319 if(strncmp(
"VBAN",(
const char*)udpIncomingPacket,4)!=0){
+ 320 LOGE(
"Unrecognized preamble %.4s\n", udpIncomingPacket);
+
+
+
+ 324 vban_rx_data_bytes = len - (VBAN_PACKET_HEADER_BYTES+VBAN_PACKET_COUNTER_BYTES);
+ 325 vban_rx_pkt_nbr = (uint32_t*)&udpIncomingPacket[VBAN_PACKET_HEADER_BYTES];
+ 326 vban_rx_data = (int16_t*)&udpIncomingPacket[VBAN_PACKET_HEADER_BYTES+VBAN_PACKET_COUNTER_BYTES];
+ 327 vban_rx_sample_count = vban_rx_data_bytes/2;
+ 328 uint8_t vbanSampleRateIdx = udpIncomingPacket[4] & VBAN_SR_MASK;
+ 329 uint8_t vbchannels = udpIncomingPacket[6]+1;
+ 330 uint32_t vbanSampleRate = VBanSRList[vbanSampleRateIdx];
+
+
+ 333 if(vban_rx_sample_count > VBAN_PACKET_MAX_SAMPLES){
+ 334 LOGE(
"error: unexpected packet size: %u\n",vban_rx_sample_count);
+
+
+
+
+
+
+
+
+
+
+
+ 346 rx_buffer.
writeArray((uint8_t*)&vban_rx_data, vban_rx_sample_count*
sizeof(uint16_t));
+
+
+
+
+
@@ -409,7 +408,7 @@
-
+
RxTxMode
Audio Source (TX_MODE) or Audio Sink (RX_MODE). RXTX_MODE is Source and Sink at the same time!
Definition: AudioTypes.h:24
diff --git a/classaudio__tools_1_1_throttle-members.html b/classaudio__tools_1_1_throttle-members.html
index bce0f9d8f8..ce5fe28b2f 100644
--- a/classaudio__tools_1_1_throttle-members.html
+++ b/classaudio__tools_1_1_throttle-members.html
@@ -81,7 +81,8 @@
info (defined in Throttle) | Throttle | protected |
start_time (defined in Throttle) | Throttle | protected |
startDelay() (defined in Throttle) | Throttle | inline |
- Throttle()=default (defined in Throttle) | Throttle | |
+ sum_samples (defined in Throttle) | Throttle | protected |
+ Throttle()=default (defined in Throttle) | Throttle | |