I noticed this while working on the multi-client PiHPSDR with native xdma data client1 and
network data client2. It's not a show stopper and I was able to work around it by shifting
DDC offsets used by client1 and client2.
-scenario-
Local sound is enabled on both PiHPSDR clients.
PiHPSDR client1 uses (up to) DDCs 0-3, client2 uses (up to) DDCs 4-9
If I had PiHPSDR client 1 running with 1 receiver @ 192K, then started a 2nd PiHPSDR client1 running with 1 receiver @ 192K, both clients start stuttering audio.
client1 here is using DDC2 and client2 DDC6.
If any other sample rate is used besides 192K, this anomaly goes away.
If I instrument the OutDDCIQ.c with timestamps I see that the amount of DDC2
data being sent gets cut in half, hence causing the stuttering.
I thought I'd try this on the latest unchanged p2app code to see if it was a new issue I created or
and existing one.
To stage it I modified IncomingDDCSpecific.c to enable DDC6 @ 192K
and instrumented OutDDCIQ.c for timestamps, I was able to recreate the
anomaly.
See below for specifics:
IncomingDDCSpecific.c
176 SetP2SampleRate(i, Enabled, Word2, Interleaved);
177 Word = Word >> 1; // move onto next DDC enabled bit
178 }
179 SetP2SampleRate(6, true, 192, false);
180
181 // now set register, and see if any changes made; reuse Dither again
182 Dither = WriteP2DDCRateRegister();
183 if (Dither)
184 HandlerCheckDDCSettings();
OutDDCIQ.c
384 #include <sys/time.h>
385 struct timeval tv;
386 struct timezone tz;
387
388 while(!InitError && SDRActive)
389 {
390
391 //
392 // loop through all DDC I/Q buffers.
393 // while there is enough I/Q data for this DDC in local (ARM) memory, make DDC Packets
394 // then put any residues at the heads of the buffer, ready for new data to come in
395 //
396 gettimeofday(&tv,&tz);
397 printf("Microseconds: %d ##################################\n",tv.tv_usec);
398 for (DDC = 0; DDC < VNUMDDC; DDC++)
399 {
400 while ((IQHeadPtr[DDC] - IQReadPtr[DDC]) > VIQBYTESPERFRAME)
401 {
402 //printf("enough data for packet: DDC=%d size=%d\n", DDC, IQHeadPtr[DDC] - IQReadPtr[DDC]);
403 (uint32_t)UDPBuffer[DDC] = htonl(SequenceCounter[DDC]++); // add sequence count
404 memset(UDPBuffer[DDC] + 4, 0, 8); // clear the timestamp data
405 (uint16_t)(UDPBuffer[DDC] + 12) = htons(24); // bits per sample
406 (uint32_t)(UDPBuffer[DDC] + 14) = htons(VIQSAMPLESPERFRAME); // I/Q samples for ths frame
407 //
408 // now add I/Q data & send outgoing packet
409 //
410 memcpy(UDPBuffer[DDC] + 16, IQReadPtr[DDC], VIQBYTESPERFRAME);
411 IQReadPtr[DDC] += VIQBYTESPERFRAME;
412
413 if(DDC==2) {
414 printf("enough data for packet: DDC=%d Residue=%d\n", DDC, IQHeadPtr[DDC] - IQReadPtr[DDC]);
415 int Error;
416 Error = sendmsg((ThreadData+DDC)->Socketid, &datagram[DDC], 0);
417
418 if (Error == -1)
419 {
420 printf("Send Error, DDC=%d, errno=%d, socket id = %d\n", DDC, errno, (ThreadData+DDC)->Socketid);
421 InitError = true;
422 }
423 }
results:
48K SR, line 179 SetP2SampleRate(6, true, 48, false);
Microseconds: 884 ##################################
enough data for packet: DDC=2 Residue=1836
enough data for packet: DDC=2 Residue=408
Microseconds: 2503 ##################################
enough data for packet: DDC=2 Residue=1020
Microseconds: 3838 ##################################
enough data for packet: DDC=2 Residue=1632
enough data for packet: DDC=2 Residue=204
Microseconds: 6345 ##################################
enough data for packet: DDC=2 Residue=840
Microseconds: 7682 ##################################
enough data for packet: DDC=2 Residue=1452
enough data for packet: DDC=2 Residue=24
Microseconds: 9106 ##################################
enough data for packet: DDC=2 Residue=636
Microseconds: 11586 ##################################
enough data for packet: DDC=2 Residue=1272
Microseconds: 13129 ##################################
enough data for packet: DDC=2 Residue=1884
enough data for packet: DDC=2 Residue=456
Microseconds: 14543 ##################################
enough data for packet: DDC=2 Residue=1068
Microseconds: 16955 ##################################
enough data for packet: DDC=2 Residue=1704
enough data for packet: DDC=2 Residue=276
Microseconds: 18371 ##################################
enough data for packet: DDC=2 Residue=888
Microseconds: 19705 ##################################
enough data for packet: DDC=2 Residue=1500
enough data for packet: DDC=2 Residue=72
Microseconds: 22259 ##################################
enough data for packet: DDC=2 Residue=708
192K SR, line 179 SetP2SampleRate(6, true, 192, false);
Microseconds: 1489 ##################################
enough data for packet: DDC=2 Residue=960
Microseconds: 6036 ##################################
enough data for packet: DDC=2 Residue=900
Microseconds: 10677 ##################################
enough data for packet: DDC=2 Residue=840
Microseconds: 15214 ##################################
enough data for packet: DDC=2 Residue=780
Microseconds: 19774 ##################################
enough data for packet: DDC=2 Residue=720
Microseconds: 24383 ##################################
enough data for packet: DDC=2 Residue=660
Microseconds: 30037 ##################################
enough data for packet: DDC=2 Residue=576
384K SR, line 179 SetP2SampleRate(6, true, 384, false);
Microseconds: 97 ##################################
enough data for packet: DDC=2 Residue=156
Microseconds: 203 ##################################
Microseconds: 1338 ##################################
enough data for packet: DDC=2 Residue=624
Microseconds: 2502 ##################################
enough data for packet: DDC=2 Residue=132
Microseconds: 2609 ##################################
Microseconds: 3761 ##################################
enough data for packet: DDC=2 Residue=600
Microseconds: 4924 ##################################
enough data for packet: DDC=2 Residue=108
Microseconds: 5032 ##################################
Microseconds: 6167 ##################################
enough data for packet: DDC=2 Residue=576
Microseconds: 7330 ##################################
enough data for packet: DDC=2 Residue=84
Microseconds: 7442 ##################################
Microseconds: 8578 ##################################
enough data for packet: DDC=2 Residue=552
Microseconds: 9912 ##################################
enough data for packet: DDC=2 Residue=60
Microseconds: 10020 ##################################
Microseconds: 11155 ##################################
enough data for packet: DDC=2 Residue=528
Microseconds: 12357 ##################################
enough data for packet: DDC=2 Residue=60
Microseconds: 12463 ##################################
Microseconds: 13598 ##################################
enough data for packet: DDC=2 Residue=504
Microseconds: 14762 ##################################
enough data for packet: DDC=2 Residue=36
Microseconds: 14867 ##################################
Microseconds: 16003 ##################################
enough data for packet: DDC=2 Residue=504
Microseconds: 17167 ##################################
enough data for packet: DDC=2 Residue=12
Microseconds: 17275 ##################################
Microseconds: 18409 ##################################
enough data for packet: DDC=2 Residue=480
Microseconds: 19572 ##################################
Microseconds: 20706 ##################################
DDC6 found to be setting its sample rate incorrectly. This caused a slow-down in all of the data transfer. DDC6 sample rate corrected and the fault is removed.
I noticed this while working on the multi-client PiHPSDR with native xdma data client1 and network data client2. It's not a show stopper and I was able to work around it by shifting DDC offsets used by client1 and client2.
-scenario-
Local sound is enabled on both PiHPSDR clients. PiHPSDR client1 uses (up to) DDCs 0-3, client2 uses (up to) DDCs 4-9
If I had PiHPSDR client 1 running with 1 receiver @ 192K, then started a 2nd PiHPSDR client1 running with 1 receiver @ 192K, both clients start stuttering audio.
client1 here is using DDC2 and client2 DDC6.
If any other sample rate is used besides 192K, this anomaly goes away. If I instrument the OutDDCIQ.c with timestamps I see that the amount of DDC2 data being sent gets cut in half, hence causing the stuttering.
I thought I'd try this on the latest unchanged p2app code to see if it was a new issue I created or and existing one.
To stage it I modified IncomingDDCSpecific.c to enable DDC6 @ 192K and instrumented OutDDCIQ.c for timestamps, I was able to recreate the anomaly.
See below for specifics:
IncomingDDCSpecific.c 176 SetP2SampleRate(i, Enabled, Word2, Interleaved); 177 Word = Word >> 1; // move onto next DDC enabled bit 178 } 179 SetP2SampleRate(6, true, 192, false); 180 181 // now set register, and see if any changes made; reuse Dither again 182 Dither = WriteP2DDCRateRegister(); 183 if (Dither) 184 HandlerCheckDDCSettings();
OutDDCIQ.c 384 #include <sys/time.h> 385 struct timeval tv; 386 struct timezone tz; 387 388 while(!InitError && SDRActive) 389 { 390 391 // 392 // loop through all DDC I/Q buffers. 393 // while there is enough I/Q data for this DDC in local (ARM) memory, make DDC Packets 394 // then put any residues at the heads of the buffer, ready for new data to come in 395 // 396 gettimeofday(&tv,&tz); 397 printf("Microseconds: %d ##################################\n",tv.tv_usec); 398 for (DDC = 0; DDC < VNUMDDC; DDC++) 399 { 400 while ((IQHeadPtr[DDC] - IQReadPtr[DDC]) > VIQBYTESPERFRAME) 401 { 402 //printf("enough data for packet: DDC=%d size=%d\n", DDC, IQHeadPtr[DDC] - IQReadPtr[DDC]); 403 (uint32_t)UDPBuffer[DDC] = htonl(SequenceCounter[DDC]++); // add sequence count 404 memset(UDPBuffer[DDC] + 4, 0, 8); // clear the timestamp data 405 (uint16_t)(UDPBuffer[DDC] + 12) = htons(24); // bits per sample 406 (uint32_t)(UDPBuffer[DDC] + 14) = htons(VIQSAMPLESPERFRAME); // I/Q samples for ths frame 407 // 408 // now add I/Q data & send outgoing packet 409 // 410 memcpy(UDPBuffer[DDC] + 16, IQReadPtr[DDC], VIQBYTESPERFRAME); 411 IQReadPtr[DDC] += VIQBYTESPERFRAME; 412 413 if(DDC==2) { 414 printf("enough data for packet: DDC=%d Residue=%d\n", DDC, IQHeadPtr[DDC] - IQReadPtr[DDC]); 415 int Error; 416 Error = sendmsg((ThreadData+DDC)->Socketid, &datagram[DDC], 0); 417 418 if (Error == -1) 419 { 420 printf("Send Error, DDC=%d, errno=%d, socket id = %d\n", DDC, errno, (ThreadData+DDC)->Socketid); 421 InitError = true; 422 } 423 }
results:
48K SR, line 179 SetP2SampleRate(6, true, 48, false); Microseconds: 884 ################################## enough data for packet: DDC=2 Residue=1836 enough data for packet: DDC=2 Residue=408 Microseconds: 2503 ################################## enough data for packet: DDC=2 Residue=1020 Microseconds: 3838 ################################## enough data for packet: DDC=2 Residue=1632 enough data for packet: DDC=2 Residue=204 Microseconds: 6345 ################################## enough data for packet: DDC=2 Residue=840 Microseconds: 7682 ################################## enough data for packet: DDC=2 Residue=1452 enough data for packet: DDC=2 Residue=24 Microseconds: 9106 ################################## enough data for packet: DDC=2 Residue=636 Microseconds: 11586 ################################## enough data for packet: DDC=2 Residue=1272 Microseconds: 13129 ################################## enough data for packet: DDC=2 Residue=1884 enough data for packet: DDC=2 Residue=456 Microseconds: 14543 ################################## enough data for packet: DDC=2 Residue=1068 Microseconds: 16955 ################################## enough data for packet: DDC=2 Residue=1704 enough data for packet: DDC=2 Residue=276 Microseconds: 18371 ################################## enough data for packet: DDC=2 Residue=888 Microseconds: 19705 ################################## enough data for packet: DDC=2 Residue=1500 enough data for packet: DDC=2 Residue=72 Microseconds: 22259 ################################## enough data for packet: DDC=2 Residue=708
192K SR, line 179 SetP2SampleRate(6, true, 192, false); Microseconds: 1489 ################################## enough data for packet: DDC=2 Residue=960 Microseconds: 6036 ################################## enough data for packet: DDC=2 Residue=900 Microseconds: 10677 ################################## enough data for packet: DDC=2 Residue=840 Microseconds: 15214 ################################## enough data for packet: DDC=2 Residue=780 Microseconds: 19774 ################################## enough data for packet: DDC=2 Residue=720 Microseconds: 24383 ################################## enough data for packet: DDC=2 Residue=660 Microseconds: 30037 ################################## enough data for packet: DDC=2 Residue=576
384K SR, line 179 SetP2SampleRate(6, true, 384, false); Microseconds: 97 ################################## enough data for packet: DDC=2 Residue=156 Microseconds: 203 ################################## Microseconds: 1338 ################################## enough data for packet: DDC=2 Residue=624 Microseconds: 2502 ################################## enough data for packet: DDC=2 Residue=132 Microseconds: 2609 ################################## Microseconds: 3761 ################################## enough data for packet: DDC=2 Residue=600 Microseconds: 4924 ################################## enough data for packet: DDC=2 Residue=108 Microseconds: 5032 ################################## Microseconds: 6167 ################################## enough data for packet: DDC=2 Residue=576 Microseconds: 7330 ################################## enough data for packet: DDC=2 Residue=84 Microseconds: 7442 ################################## Microseconds: 8578 ################################## enough data for packet: DDC=2 Residue=552 Microseconds: 9912 ################################## enough data for packet: DDC=2 Residue=60 Microseconds: 10020 ################################## Microseconds: 11155 ################################## enough data for packet: DDC=2 Residue=528 Microseconds: 12357 ################################## enough data for packet: DDC=2 Residue=60 Microseconds: 12463 ################################## Microseconds: 13598 ################################## enough data for packet: DDC=2 Residue=504 Microseconds: 14762 ################################## enough data for packet: DDC=2 Residue=36 Microseconds: 14867 ################################## Microseconds: 16003 ################################## enough data for packet: DDC=2 Residue=504 Microseconds: 17167 ################################## enough data for packet: DDC=2 Residue=12 Microseconds: 17275 ################################## Microseconds: 18409 ################################## enough data for packet: DDC=2 Residue=480 Microseconds: 19572 ################################## Microseconds: 20706 ##################################