fowt floating point audio data does not seem to work
Currently the audio message reading code treats it as if it's S16 but that's probably not correct?
I tried the following experiment. It seems almost correct but has a lot of distortions.
diff --git a/libndi.c b/libndi.c
index 61b52e6..c43463b 100644
--- a/libndi.c
+++ b/libndi.c
@@ -242,12 +242,14 @@ static int process_audio_message(ndi_ctx *ndi_ctx, uint8_t *data, int header_len
uint32_t num_channels = (data[11] << 24) | (data[10] << 16) | (data[9] << 8) | data[8];
uint32_t sample_rate = (data[15] << 24) | (data[14] << 16) | (data[13] << 8) | data[12];
float scale_factors[16];
+ int bps = 0;
// XXX: some more things in the header
data += header_len;
if(fourcc == MKTAG('f','o','w','t')) {
uint32_t num_nonzero_channels = 0;
+ bps = sizeof(float);
for(uint32_t i = 0; i < num_channels; i++) {
uint32_t tmp = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
memcpy(&scale_factors[i], &tmp, sizeof(float));
@@ -258,6 +260,7 @@ static int process_audio_message(ndi_ctx *ndi_ctx, uint8_t *data, int header_len
}
}
else if(fourcc == MKTAG('s','o','w','t')) {
+ bps = sizeof(int16_t);
for(uint32_t i = 0; i < num_channels; i++) {
scale_factors[i] = 1.0f;
}
@@ -270,19 +273,36 @@ static int process_audio_message(ndi_ctx *ndi_ctx, uint8_t *data, int header_len
ndi_data.sample_rate = sample_rate;
for(uint32_t i = 0; i < num_channels; i++) {
- ndi_data.buf[i] = av_buffer_alloc(ndi_data.num_channels * ndi_data.samples * sizeof(int16_t));
+ ndi_data.buf[i] = av_buffer_alloc(ndi_data.num_channels * ndi_data.samples * bps);
if(!ndi_data.buf[i]) {
ret = -1;
goto end;
}
}
- for(uint32_t j = 0; j < samples; j++) {
- for(uint32_t i = 0; i < num_channels; i++) {
- ndi_data.buf[i]->data[2*j+0] = data[1];
- ndi_data.buf[i]->data[2*j+1] = data[0];
- data += sizeof(int16_t);
- }
+ if (bps == 2) {
+ for(uint32_t j = 0; j < samples; j++) {
+ for(uint32_t i = 0; i < num_channels; i++) {
+ ndi_data.buf[i]->data[2*j+0] = data[1];
+ ndi_data.buf[i]->data[2*j+1] = data[0];
+ data += sizeof(int16_t);
+ }
+ }
+ } else if (bps == 4) {
+ for(uint32_t j = 0; j < samples; j++) {
+ for(uint32_t i = 0; i < num_channels; i++) {
+ ndi_data.buf[i]->data[4*j+0] = data[3];
+ ndi_data.buf[i]->data[4*j+1] = data[2];
+ ndi_data.buf[i]->data[4*j+2] = data[1];
+ ndi_data.buf[i]->data[4*j+3] = data[0];
+
+ {
+ float *f = (float *) &ndi_data.buf[i]->data[4*j];
+ *f /= scale_factors[i];
+ }
+ data += sizeof(float);
+ }
+ }
}
ndi_ctx->callback(&ndi_data);
It also causes some valgrind warnings but only for the first frame it seems (and bound checks are missing):
==82561== Invalid read of size 1
==82561== at 0x484BAEF: process_audio_message (libndi.c:294)
==82561== by 0x484BAEF: process_ndi_packet (libndi.c:377)
==82561== by 0x484BAEF: handle_ndi_packet (libndi.c:411)
==82561== by 0x484BAEF: receive_ndi_packet (libndi.c:437)
==82561== by 0x484C08F: libndi_receive_data (libndi.c:613)
==82561== by 0x10A461: main (ndi_gst.c:300)
==82561== Address 0x5ee0e38 is 3 bytes after a block of size 53 alloc'd
==82561== at 0x483877F: malloc (vg_replace_malloc.c:309)
==82561== by 0x484B637: handle_ndi_packet (libndi.c:406)
==82561== by 0x484B637: receive_ndi_packet (libndi.c:437)
==82561== by 0x484C08F: libndi_receive_data (libndi.c:613)
==82561== by 0x10A461: main (ndi_gst.c:300)
==82561==
==82561== Invalid read of size 1
==82561== at 0x484BB01: process_audio_message (libndi.c:295)
==82561== by 0x484BB01: process_ndi_packet (libndi.c:377)
==82561== by 0x484BB01: handle_ndi_packet (libndi.c:411)
==82561== by 0x484BB01: receive_ndi_packet (libndi.c:437)
==82561== by 0x484C08F: libndi_receive_data (libndi.c:613)
==82561== by 0x10A461: main (ndi_gst.c:300)
==82561== Address 0x5ee0e37 is 2 bytes after a block of size 53 alloc'd
==82561== at 0x483877F: malloc (vg_replace_malloc.c:309)
==82561== by 0x484B637: handle_ndi_packet (libndi.c:406)
==82561== by 0x484B637: receive_ndi_packet (libndi.c:437)
==82561== by 0x484C08F: libndi_receive_data (libndi.c:613)
==82561== by 0x10A461: main (ndi_gst.c:300)
==82561==
==82561== Invalid read of size 1
==82561== at 0x484BB13: process_audio_message (libndi.c:296)
==82561== by 0x484BB13: process_ndi_packet (libndi.c:377)
==82561== by 0x484BB13: handle_ndi_packet (libndi.c:411)
==82561== by 0x484BB13: receive_ndi_packet (libndi.c:437)
==82561== by 0x484C08F: libndi_receive_data (libndi.c:613)
==82561== by 0x10A461: main (ndi_gst.c:300)
==82561== Address 0x5ee0e36 is 1 bytes after a block of size 53 alloc'd
==82561== at 0x483877F: malloc (vg_replace_malloc.c:309)
==82561== by 0x484B637: handle_ndi_packet (libndi.c:406)
==82561== by 0x484B637: receive_ndi_packet (libndi.c:437)
==82561== by 0x484C08F: libndi_receive_data (libndi.c:613)
==82561== by 0x10A461: main (ndi_gst.c:300)
==82561==
==82561== Invalid read of size 1
==82561== at 0x484BB25: process_audio_message (libndi.c:297)
==82561== by 0x484BB25: process_ndi_packet (libndi.c:377)
==82561== by 0x484BB25: handle_ndi_packet (libndi.c:411)
==82561== by 0x484BB25: receive_ndi_packet (libndi.c:437)
==82561== by 0x484C08F: libndi_receive_data (libndi.c:613)
==82561== by 0x10A461: main (ndi_gst.c:300)
==82561== Address 0x5ee0e35 is 0 bytes after a block of size 53 alloc'd
==82561== at 0x483877F: malloc (vg_replace_malloc.c:309)
==82561== by 0x484B637: handle_ndi_packet (libndi.c:406)
==82561== by 0x484B637: receive_ndi_packet (libndi.c:437)
==82561== by 0x484C08F: libndi_receive_data (libndi.c:613)
==82561== by 0x10A461: main (ndi_gst.c:300)
==82561==