Using GNU Octave to Characterize Noise of Digital Recording Path

GroupDIY Audio Forum

Help Support GroupDIY Audio Forum:

This site may earn a commission from merchant affiliate links, including eBay, Amazon, and others.

Bo Deadly

Well-known member
Joined
Dec 22, 2015
Messages
3,266
Location
New Jersey, USA
I wanted to compare performance of my recording rig with 3 digital recorders (MOTU Traveler mk3, Zoom R16 and Tascam SD-20M) so I thought I would plot the noise spectra using GNU Octave and post the results. The below Octave script averages together many spectra from the stft function (short-time Fourier transform) and does a little filtering with sgolayfilt to bring out the peaks. Octave (and it's inspiration Matlab) can generate extremely high quality plots.

To generate the wav file, send the DUT a reference tone (I used 1kHz) and adjust the level to 0dBFS (aka "Full-Scale"). Listen to find the threshold of clipping. Record 10 sec of the ref. tone. Then turn off the ref tone and terminate the input of the DUT. Record another 10 sec of this "silence". Add that now ~20s wav file to the below script and viola - awesome detailed spectrum. Adjust to taste.

For example, here is a series of spectra that compare the noise floors of 3 consumer digital recording devices:

Screenshot%2Bfrom%2B2018-05-21%2B01-43-14.png


The
Code:
noise.m
Octave / Matlab script:

Code:
[SIZE=13px]pkg load signal

clear all;
close all;

function [f, s, m] = wavfft(filename, chan, offset, nfft, nmult)

    [y, fs] = audioread(filename, [1, 2]);
    osam = offset * fs;

    [y, fs] = audioread(filename, [osam, osam + nfft]); 
    y = y(:, chan);

    s = stft(y, 80 * nmult, 24 * nmult, 64 * nmult, 1);
    s = mean(s, 2);
    s = 20*log10(s);
    s = sgolayfilt(s, 5, 21); 
    m = max(s); 

    n = length(s);
    f = fs*(0:n-1)/n/2;

endfunction

function pltwavfft(filename, chan, offset_reftone, npow, nmult, rgb)

    hold on 

    [f, s, m] = wavfft(filename, chan, offset_reftone + 0, 2^npow, nmult); 
    s = s .- m; # adjust 0dB to peak of test tone
    semilogx(f, s, 'color', [0.9, 0.9, 0.9]);

    [f, s, x] = wavfft(filename, chan, offset_reftone + 10, 2^npow, nmult); 
    s = s .- m; # adjust 0dB to peak of test tone
    semilogx(f, s, 'color', [0, 0, 0]); 

    axis([20 20000 -150 0])
    grid on

endfunction

subplot(1, 3, 1);
pltwavfft('NoiseStep_Traveler_5.wav', 1, 3, 16, 512, [0.1, 0.1, 0.1])
title('50 Ohm Term. > MOTU Traveler mk3');
subplot(1, 3, 2);
pltwavfft('NoiseStep_TascamSD20M_50r.wav', 1, 3, 16, 512, [0.1, 0.1, 0.1])
title('50 Ohm Term. > Tascam SD-20M');
subplot(1, 3, 3);
pltwavfft('NoiseStep_ZoomR16_50r_sox.wav', 1, 3, 16, 512, [0.1, 0.1, 0.1])
title('50 Ohm Term. > Zoom R16');[/SIZE]
 
squarewave said:
... the test tone is 1kHz but for some reason it's coming through as 1.1kHz.
Looks like 2K, with both odd and even  harmonics to me. And some 120hz power supply buzz with odd harmonics.

Gene
 
Here's another interesting thing <snip hypothesis that turned out to be wrong>  ...

UPDATE:

Actually the low frequency noise is coming from the Neve mic pre. I played around and found that adjusting the input trim does not add noise low frequency or otherwise. At least not at low levels of trim.

Here's another example of the Octave script above. These plots compare the noise floors of custom Neve and API pres:

Screenshot%2Bfrom%2B2018-05-21%2B01-30-07.png


So it seems my Neve pre with one gain stage has actually less noise than my API-style pre. But with the second gain stage, low frequency noise increases. Not sure if that's normal.
 
Gene Pink said:
Looks like 2K, with both odd and even  harmonics to me. And some 120hz power supply buzz with odd harmonics.
You're right! It's 2kHz. So maybe I need to divide by 2 somewhere.

But those harmonics are just the function generator which we don't care about.
 
The general rule for systems is use large gain / low noise as the first device in a chain,  in this case a mic pre.

So yes you want to maximize signal in the front end to minimize the degradation to the S/N ratio. Was particularly important for 16 bit recording. The same issues exist with 24 bit,  they are just less noticeable, and often less of a priority.
 
I have updated the "noise.m" script above and I updated two posts with corrections and newer more accurate plots. Hopefully someone finds this useful.
 
Back
Top