- samplesOut = ab->data;
- samplesOutLeft = ab->mDataByteSize / sizeof (float);
- while(packets && nbuffers > 0) {
- if(packets->used == packets->nsamples) {
- /* TODO if we dropped a packet then we should introduce a gap here */
- struct packet *const f = packets;
- packets = f->next;
- free(f);
- pthread_cond_broadcast(&cond);
- continue;
- }
- if(samplesOutLeft == 0) {
- --nbuffers;
- ++ab;
- samplesOut = ab->data;
- samplesOutLeft = ab->mDataByteSize / sizeof (float);
- continue;
+ while(nbuffers > 0) {
+ float *samplesOut = ab->mData;
+ size_t samplesOutLeft = ab->mDataByteSize / sizeof (float);
+
+ while(samplesOutLeft > 0) {
+ /* Look for a suitable packet, dropping any unsuitable ones along the
+ * way. Unsuitable packets are ones that are in the past. */
+ while(npackets
+ && (!packets[sequence]
+ || le(packets[sequence]->timestamp
+ + packets[sequence]->nsamples,
+ next_timestamp)))
+ drop_packet(sequence++);
+ p = packets[sequence];
+ if(p) {
+ if(contains(p, next_timestamp)) {
+ /* This packet is suitable */
+ const uint32_t packet_end = p->timestamp + p->nsamples;
+ const uint32_t offset = next_timestamp - p->timestamp;
+ const uint16_t *ptr =
+ (void *)(p->samples_raw + offset * sizeof (uint16_t));
+ uint32_t samples_available = packet_end - next_timestamp;
+ if(samples_available > samplesOutLeft)
+ samples_available = samplesOutLeft;
+ next_timestamp += samples_available;
+ samplesOutLeft -= samples_available;
+ while(samples_available-- > 0)
+ *samplesOut++ = (int16_t)ntohs(*ptr++) * (0.5 / 32767);
+ /* We don't bother junking the packet or advancing sequence - that'll
+ * be dealt with next time round */
+ continue;
+ }
+ }
+ /* We didn't find a suitable packet (though there might still be
+ * unsuitable ones). We infill with 0s. */
+ if(p) {
+ /* There is a next packet, only infill up to that point */
+ uint32_t samples_available = p->timestamp - next_timestamp;
+
+ if(samples_available > samplesOutLeft)
+ samples_available = samplesOutLeft;
+ info("infill by %"PRIu32, samples_available);
+ /* Convniently the buffer is 0 to start with */
+ next_timestamp += samples_available;
+ samplesOut += samples_available;
+ samplesOutLeft -= samples_available;
+ } else {
+ /* There's no next packet at all */
+ info("infilled by %zu", samplesOutLeft);
+ next_timestamp += samplesOutLeft;
+ samplesOut += samplesOutLeft;
+ samplesOutLeft = 0;
+ }