Invalid float values for audio in Apple SDK

Ninakadin

New member
I have created an NDI monitor app for iOS, working quite good. I'm testing with a Newtek NC1 as well as "NDI HX Camera" app on iPhone.
Besides the strange fact, that the app does not deliver timecode for audio frames (bad for synchronization), I have 2 problems with audio, appearing with data from both test devices.

a) When I request v3 audio I receive nice float samples with a crystal clear sound, but I receive irregularly values, that don't correspond to a valid float value.
b) When I receive v2 audio and convert it to 16 Bit audio, the quality is definitely worse than with the float values, sounds like clipped sound, far below CD quality.

I'm mostly interested in problem a)

In my tests between 0.1 and 3.2% of all samples result in "Not a Number" when converting the 4 bytes to a Float / Float32. Here a sample list with audio from NC1, sample rate 48000, 16 channels (I'm using only the first 2), 1920 samples.
First number indicates the channel 0 or 1, second number the index of the sample, after equation the 4 raw bytes, which fail to be converted to a Float / Float32. In this example 17 values were invalid floats.

NaN val[0, 290] = 7f 97 9e 3e
NaN val[0, 803] = ff ed d7 3e
NaN val[0, 995] = 7f ee cd 3e
NaN val[0, 1574] = 7f 97 9e be
NaN val[0, 1734] = ff 96 a8 be
NaN val[1, 122] = 7f 9e 1b 3e
NaN val[1, 348] = 7f 9e 1b 3e
NaN val[1, 402] = 7f 9e 9b bd
NaN val[1, 528] = 7f 9e 1b be
NaN val[1, 626] = 7f 9e 1b 3e
NaN val[1, 985] = 7f 9e 1b 3e
NaN val[1, 1188] = 7f 9e 9b be
NaN val[1, 1244] = ff e5 bc be
NaN val[1, 1512] = 7f 9e 1b 3e
NaN val[1, 1583] = 7f 9e 9b bd
NaN val[1, 1737] = ff ad 74 be
NaN val[1, 1890] = 7f 9e 1b be

If I interpret the IEEE 754 standard for floating point representation correctly, then if the first byte is 7F or FF, then the MSB of the second byte may not be 1 (https://en.wikipedia.org/wiki/Single-precision_floating-point_format). But this is the case in each failed value above.

Below the important lines of source code (Swift). Im using the latest Apple SDK (Install_NDI_Advanced_SDK_v5_Apple.pkg).

func connectTo(source: NDIlib_source_t)->Bool
{
var p_create_settings = NDIlib_recv_create_v3_t(source_to_connect_to: source, color_format: NDIlib_recv_color_format_RGBX_RGBA, bandwidth: NDIlib_recv_bandwidth_highest, allow_video_fields: true, p_ndi_recv_name: nil)
pNDI_recv = NDIlib_recv_create_v3(&p_create_settings)
if (pNDI_recv == nil) {
return false
}
var connectSource = source
NDIlib_recv_connect(pNDI_recv, &connectSource);
}

func receiveNextAudioFrameFloat()
{
var audio_frame: NDIlib_audio_frame_v3_t = NDIlib_audio_frame_v3_t()
let type = NDIlib_recv_capture_v3(pNDI_recv, nil, &audio_frame, nil, 2000);
if (type == NDIlib_frame_type_audio)
{
deliverAudioFloat(audio_frame: audio_frame)
NDIlib_recv_free_audio_v3(pNDI_recv, &audio_frame);
}
}

func deliverAudioFloat(audio_frame: NDIlib_audio_frame_v3_t)
{
let chanCount = min(2, Int(audio_frame.no_channels))
let sampleCount = Int(audio_frame.no_samples)
let sampleRate = Int(audio_frame.sample_rate)
let stride = Int(audio_frame.channel_stride_in_bytes)
var audioBufs: [[Float32]] = []
if (audio_frame.FourCC == NDIlib_FourCC_type_FLTP)
{
let bufPtr: UnsafeMutablePointer<UInt8>! = audio_frame.p_data

// Shortened here: Iterating over buffer in 32 Bit steps, reading 4 Bytes into Data object and createing Float out of it
let aFloat = Float32(bitPattern: UInt32(bigEndian: data.withUnsafeBytes { $0.pointee } ))
if (aFloat.isNaN) {
// print debug info ...
}
// ... deliver buffer to audio manager
}
}

Any idea? Is it a compatibility problem of floating point representation? Apple uses IEEE 754 representation.
You can't hear this "NaN"s, but ignoring it does not seem to be right in my eyes.
 
Last edited:

brianbrice

Software Engineer
If I am understanding that correctly, is that saying to interpret the bytes as big-endian? If so, definitely try it as little-endian.
 

Ninakadin

New member
If I am understanding that correctly, is that saying to interpret the bytes as big-endian? If so, definitely try it as little-endian.
Although I did not really make sense, since I got clear good sound, I did that when I first ran into the problem, but then I only get white noise instead of good sound.
 
Top Bottom