From 4bd2c9df7c1a3cadb29c66d695c42168ec0f279c Mon Sep 17 00:00:00 2001
From: Jean-Baptiste Kempf <jb@videolan.org>
Date: Fri, 26 Jun 2020 22:40:36 +0100
Subject: [PATCH] libndi: Attempt to decode float audio

---
 libndi.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/libndi.c b/libndi.c
index 3cbdc29..c33342b 100644
--- a/libndi.c
+++ b/libndi.c
@@ -243,11 +243,13 @@ static int process_audio_message(ndi_ctx *ndi_ctx, uint8_t *data, int header_len
     uint32_t sample_rate = (data[15] << 24) | (data[14] << 16) | (data[13] << 8) | data[12];
     float scale_factors[16];
     uint32_t num_nonzero_channels = 0;
+    uint16_t bps = sizeof(int16_t);
 
     // XXX: some more things in the header
     data += header_len;
 
     if(fourcc == MKTAG('f','o','w','t')) {
+        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));
@@ -273,7 +275,7 @@ 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;
@@ -282,9 +284,20 @@ static int process_audio_message(ndi_ctx *ndi_ctx, uint8_t *data, int header_len
 
     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(scale_factors[i] == 0.0f)
+                memset(&ndi_data.buf[i]->data[4*j], 0, bps);
+            else {
+                if(bps == 2) {
+                    ndi_data.buf[i]->data[2*j+0] = data[1];
+                    ndi_data.buf[i]->data[2*j+1] = data[0];
+                } else(bps == 4) {
+                    float sf = scale_factors[i] / 32767.0f;
+                    int16_t sample = ((uint16_t)data[1] << 8) | data[0];
+                    sf *= sample;
+                    memcpy(&ndi_data.buf[i]->data[4*j], sf, sizeof(sf));
+                }
+                data += sizeof(int16_t);
+            }
         }
     }
 
-- 
GitLab