Skip to content

Commit d313ea7

Browse files
committed
WIP Reduce size of buffer.
This method uses the elastic clock to delay by 32 which allows reducing the size. Missing delay less based on sequence numbers & handling "lag"
1 parent ebd662f commit d313ea7

File tree

2 files changed

+23
-67
lines changed

2 files changed

+23
-67
lines changed

src/output.c

+22-67
Original file line numberDiff line numberDiff line change
@@ -39,24 +39,6 @@ static unsigned int elastic_average_samples(const output_t *st, const elastic_bu
3939
return dec->avg * (st->radio->mode == NRSC5_MODE_FM ? RADIO_FRAME_SAMPLES_FM : RADIO_FRAME_SAMPLES_AM);
4040
}
4141

42-
static unsigned int elastic_compute_sequence_position(const elastic_buffer_t *elastic, unsigned int seq)
43-
{
44-
return (MAX_AUDIO_PACKETS + seq - elastic->ptr[elastic->write].seq) % MAX_AUDIO_PACKETS;
45-
}
46-
47-
static void elastic_realign_forward(elastic_buffer_t *elastic, unsigned int forward, unsigned int pdu_seq, unsigned int avg, unsigned int seq)
48-
{
49-
elastic->write = (elastic->write + forward) % elastic->size;
50-
elastic->ptr[elastic->write].seq = seq;
51-
52-
unsigned int offset = pdu_seq * avg;
53-
54-
if (((offset + 64 - seq) % MAX_AUDIO_PACKETS) < 32)
55-
offset = (offset + 32) % MAX_AUDIO_PACKETS;
56-
57-
elastic->read = (elastic->write - elastic->delay - seq + offset) % elastic->size;
58-
}
59-
6042
static unsigned int elastic_write_available(const elastic_buffer_t *elastic)
6143
{
6244
return elastic->size - elastic->write + elastic->read - 1;
@@ -207,20 +189,17 @@ static void elastic_decode_packet(output_t *st, unsigned int program, int16_t **
207189
void output_align(output_t *st, unsigned int program, unsigned int stream_id, unsigned int pdu_seq, unsigned int latency, unsigned int avg, unsigned int seq, unsigned int nop)
208190
{
209191
elastic_buffer_t *elastic = &st->elastic[program][stream_id];
210-
unsigned int forward;
211192

212193
if (stream_id != 0)
213194
return; // TODO: Process enhanced stream
214195

215196
elastic->latency = latency * 2;
216197
elastic->avg = avg;
217198

218-
// Create Elastic buffer
219199
if (!elastic->ptr)
220200
{
221-
// Buffer Diagram: ||delay|| + ||64|| + ||delay||
222201
elastic->delay = elastic->latency;
223-
elastic->size = (elastic->delay * 2) + MAX_AUDIO_PACKETS;
202+
elastic->size = MAX_AUDIO_PACKETS;
224203
elastic->ptr = malloc(elastic->size * sizeof(*elastic->ptr));
225204

226205
for (unsigned int i = 0; i < elastic->size; i++)
@@ -229,30 +208,12 @@ void output_align(output_t *st, unsigned int program, unsigned int stream_id, un
229208
elastic->ptr[i].seq = -1;
230209
}
231210

232-
// Startup the buffer
233-
elastic->write = elastic->delay;
234-
235-
// Startup the clock
236-
elastic->clock = elastic_average_samples(st, elastic);
237-
238-
// Align Writer (buffer->delay + seq) & Reader
239-
elastic_realign_forward(elastic, seq, pdu_seq, avg, seq);
240-
241-
log_debug("Elastic buffer created. Program: %d, Size %d bytes, Read %d pos, Write: %d pos, Delay: %d, Average: %d", program, elastic->size, elastic->read, elastic->write, elastic->delay, elastic->avg);
242-
}
243-
else
244-
{
245-
// FIXME: Figure out a better way to design the buffer to avoid needing to re-sync
246-
// This is due to "lag" that could happen.
247-
// We are relying on reader to have the correct sequence number to delay the writer
211+
elastic->clock = st->radio->mode == NRSC5_MODE_FM ? FFT_FM : FFT_AM;
212+
elastic->write = seq;
213+
elastic->ptr[elastic->write].seq = seq;
248214

249-
// Re-sync (lost-synchronization with reader and writer)
250-
forward = elastic_compute_sequence_position(elastic, seq);
251-
if (elastic_write_available(elastic) < forward + nop)
252-
{
253-
elastic_realign_forward(elastic, forward, pdu_seq, avg, seq);
254-
log_debug("Elastic buffer realigned. Program: %d, Read %d pos, Write: %d pos", program, elastic->read, elastic->write);
255-
}
215+
// TODO: Calculate current delay based on sequence number
216+
elastic->read = (seq - elastic->latency) % elastic->size;
256217
}
257218

258219
#ifdef USE_FAAD2
@@ -274,6 +235,8 @@ void output_align(output_t *st, unsigned int program, unsigned int stream_id, un
274235

275236
void output_advance_elastic(output_t *st, int pos, unsigned int used)
276237
{
238+
// TODO maybe add resync here based on OFDM sequence numbers?
239+
277240
for (int i = 0; i < MAX_PROGRAMS; i++)
278241
{
279242
elastic_buffer_t *elastic = &st->elastic[i][0];
@@ -304,6 +267,7 @@ void output_advance_elastic(output_t *st, int pos, unsigned int used)
304267
{
305268
log_debug("Decoder buffer full for program: %d. Skipped samples. bug?", i);
306269
}
270+
dec->started = 1;
307271
#endif
308272
}
309273
elastic->clock -= sample_avg;
@@ -325,15 +289,15 @@ void output_advance(output_t *st, unsigned int len, int mode)
325289
unsigned int audio_frames, silence_frames, frames_len;
326290

327291
// Skip if no buffer
328-
if (st->elastic[i][0].write == 0)
292+
if (!dec->started)
329293
continue;
330294

331295
// Program started in the middle of the sample.
332296
// Insert silence to makeup for it. It takes time to generate samples
333297
if (dec->input_start_pos > 0)
334298
{
335-
iq_hd_samples = (len - dec->input_start_pos);
336-
iq_delay_samples = (len - iq_hd_samples);
299+
iq_hd_samples = len - dec->input_start_pos;
300+
iq_delay_samples = len - iq_hd_samples;
337301
}
338302
else
339303
{
@@ -350,7 +314,7 @@ void output_advance(output_t *st, unsigned int len, int mode)
350314

351315
if (decoder_buffer_read_available(dec) < audio_frames)
352316
{
353-
log_error("Missing output samples. Requested: %d Available: %d", audio_frames, decoder_buffer_read_available(dec));
317+
log_error("Missing output samples for program %d. Requested: %d Available: %d", i, audio_frames, decoder_buffer_read_available(dec));
354318
audio_frames = decoder_buffer_read_available(dec);
355319
}
356320

@@ -372,20 +336,14 @@ void output_push(output_t *st, uint8_t *pkt, unsigned int len, unsigned int prog
372336
if (stream_id != 0)
373337
return; // TODO: Process enhanced stream
374338

375-
if (elastic_write_available(elastic) == 0)
376-
{
377-
log_error("elastic buffer full. skipped packet. bug?");
378-
return;
379-
}
380-
381-
unsigned int forward = elastic_compute_sequence_position(elastic, seq);
382-
unsigned int pos = (elastic->write + forward) % elastic->size;
339+
if (elastic->ptr[seq].size != 0)
340+
log_warn("Packet %d already exists in elastic buffer for program %d. Overwriting.", seq, program);
383341

384-
memcpy(elastic->ptr[pos].data, pkt, len);
385-
elastic->ptr[pos].size = len;
386-
elastic->ptr[pos].seq = seq;
342+
memcpy(elastic->ptr[seq].data, pkt, len);
343+
elastic->ptr[seq].size = len;
344+
elastic->ptr[seq].seq = seq;
387345

388-
elastic->write = pos;
346+
elastic->write = seq;
389347
}
390348

391349
static void aas_free_lot(aas_file_t *file)
@@ -452,6 +410,7 @@ void output_reset(output_t *st)
452410
dec->write = 0;
453411
dec->read = 0;
454412
dec->delay = 0;
413+
dec->started = 0;
455414
dec->input_start_pos = -1;
456415

457416
if (dec->output_buffer)
@@ -469,12 +428,8 @@ void output_init(output_t *st, nrsc5_t *radio)
469428
memset(st->services, 0, sizeof(st->services));
470429

471430
#ifdef USE_FAAD2
472-
for (int i = 0; i < MAX_PROGRAMS; i++)
473-
{
474-
st->decoder[i].aacdec = NULL;
475-
st->decoder[i].leftover = 0;
476-
}
477-
431+
memset(st->decoder, 0, sizeof(st->decoder));
432+
memset(st->elastic, 0, sizeof(st->elastic));
478433
memset(st->silence, 0, sizeof(st->silence));
479434
#endif
480435

src/output.h

+1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ typedef struct
105105
unsigned int write, read, leftover, delay;
106106

107107
int input_start_pos;
108+
int started;
108109
} decoder_t;
109110
#endif
110111

0 commit comments

Comments
 (0)