0
1
mirror of https://github.com/radio95-rnt/fm95.git synced 2026-02-27 11:33:54 +01:00

updates to the vban95 receiver

This commit is contained in:
2025-05-17 20:52:15 +02:00
parent 5921aae9c2
commit 24c6151088

View File

@@ -71,6 +71,8 @@ typedef struct {
typedef struct {
AudioPacket* packets;
int capacity;
int head;
int tail;
int count;
VBANHeader header;
} AudioBuffer;
@@ -90,6 +92,8 @@ AudioBuffer* create_audio_buffer(int capacity) {
}
buffer->capacity = capacity;
buffer->head = 0;
buffer->tail = 0;
buffer->count = 0;
return buffer;
@@ -103,23 +107,28 @@ void destroy_audio_buffer(AudioBuffer* buffer) {
}
int add_to_buffer(AudioBuffer* buffer, const char* data, size_t size, const VBANHeader* header) {
if (buffer->count >= buffer->capacity) {
return 0;
}
if (size > MAX_AUDIO_DATA_SIZE) {
fprintf(stderr, "Audio data too large for buffer\n");
return -1;
}
memcpy(buffer->packets[buffer->count].data, data, size);
buffer->packets[buffer->count].size = size;
if (buffer->count == buffer->capacity) {
buffer->tail = (buffer->tail + 1) % buffer->capacity;
buffer->count--;
}
AudioPacket* pkt = &buffer->packets[buffer->head];
memcpy(pkt->data, data, size);
pkt->size = size;
memcpy(&buffer->header, header, sizeof(VBANHeader));
buffer->head = (buffer->head + 1) % buffer->capacity;
buffer->count++;
return 1;
}
volatile uint8_t to_run = 1;
static void stop(int signum) {
@@ -131,15 +140,18 @@ static void stop(int signum) {
static PulseOutputDevice output = {0};
void process_audio_buffer(AudioBuffer* buffer, PulseOutputDevice* output_device) {
if (buffer->count == 0) {
return;
while (buffer->count > 0) {
AudioPacket* pkt = &buffer->packets[buffer->tail];
write_PulseOutputDevicef(output_device, pkt->data, pkt->size);
buffer->tail = (buffer->tail + 1) % buffer->capacity;
buffer->count--;
}
for(int i = 0; i < buffer->count; i++) {
// this function internally checks for initialization so no issues here, if not initialized then the data is discarded
write_PulseOutputDevicef(&output, buffer->packets[i].data, buffer->packets[i].size);
}
}
void reset_audio_buffer(AudioBuffer* buffer) {
buffer->head = 0;
buffer->tail = 0;
buffer->count = 0;
}
@@ -215,34 +227,29 @@ int main(int argc, char *argv[]) {
break;
}
if (sender_addr.sin_addr.s_addr == remote_addr_bin.s_addr || strcmp(remote_ip, "0.0.0.0") == 0) {
if (sender_addr.sin_addr.s_addr == remote_addr_bin.s_addr || remote_addr_bin.s_addr == 0) {
VBANHeaderUnion data;
memcpy(&data.raw_data, buffer, sizeof(VBANHeader));
if (memcmp(data.packet_data.vban, "VBAN", 4) != 0) {
continue;
}
if (memcmp(data.packet_data.streamname, stream_name, strlen(stream_name)) != 0) {
continue;
}
if (memcmp(data.packet_data.vban, "VBAN", 4) != 0) continue; // Not VBAN
if (memcmp(data.packet_data.streamname, stream_name, strlen(stream_name)) != 0) continue; // Not this
if (vban_frame == 0) {
// This means either this is our first packet, if it is we'll sync to the sender and if it isn't we'll set to 0 from 0
vban_frame = data.packet_data.frame_num;
} else {
uint32_t expected_frame = vban_frame + 1;
uint32_t expected_frame = vban_frame++;
if (data.packet_data.frame_num != expected_frame) {
int32_t diff = (int32_t)(data.packet_data.frame_num - expected_frame);
if (diff > 0) {
if(quiet == 0) printf("Dropped %d packet(s)\n", diff);
} else if (diff < 0) {
if(quiet == 0) printf("Late or duplicate packet\n");
if (data.packet_data.frame_num > expected_frame) {
// We receiver a higher counter than expected? Must be a dropped packet
uint8_t dropped_packets = (data.packet_data.frame_num - expected_frame); // The offset probably is how many packets we've missed
if(quiet == 0) printf("Dropped %d packets\n", dropped_packets);
} else {
// So we've got a higher count, must be out of order then
if(quiet == 0) printf("Packets received out of order\n");
}
vban_frame = data.packet_data.frame_num;
} else {
vban_frame = expected_frame;
vban_frame = data.packet_data.frame_num; // Resync
}
}
@@ -250,21 +257,21 @@ int main(int argc, char *argv[]) {
vban_last_sr = data.packet_data.sample_rate_idx;
if(quiet == 0) printf("New sample rate of %ld\n", VBAN_SRList[vban_last_sr % VBAN_SR_MAXNUMBER]);
vban_audio_reset = 1;
audio_buffer->count = 0;
reset_audio_buffer(audio_buffer);
}
if(vban_last_format != data.packet_data.format_type) {
vban_last_format = data.packet_data.format_type;
if(quiet == 0) printf("New data format of %s\n", VBAN_TextBITList[vban_last_format % VBAN_BIT_MAXNUMBER]);
if(quiet == 0) printf("New data format of %s\n", VBAN_TextBITList[vban_last_format % VBAN_BIT_MAXNUMBER]); // Here it should be fine to use the modulo, as during the reset we point out the idx may be shit
vban_audio_reset = 1;
audio_buffer->count = 0;
reset_audio_buffer(audio_buffer);
}
if(vban_last_channels != data.packet_data.sample_channels) {
vban_last_channels = data.packet_data.sample_channels;
if(quiet == 0) printf("New channel count of %d\n", vban_last_channels + 1); // Add 1 because VBAN channels are 0-based
vban_audio_reset = 1;
audio_buffer->count = 0;
reset_audio_buffer(audio_buffer);
}
// Handle audio reset if needed