Main Content

Impulse Response Measurement Using a NI USB-4431 Device

This example shows how to measure an impulse response using a National Instruments (NI) USB-4431 sound and vibration device. You set up the device, create an excitation signal to play, and simultaneously record the response. Finally, you compute the response from the recording and plot the results.

For this example, you need Audio Toolbox™ and Data Acquisition Toolbox™. You also need to have installed the NI drivers (recommended) or the MATLAB NI support package.

Device Setup

Verify if the NI USB-4431 is connected and the proper drivers are installed using the daqlist command.

ans=1×4 table
    DeviceID                Description                  Model                      DeviceInfo               
    ________    ___________________________________    __________    ________________________________________

     "Dev1"     "National Instruments(TM) USB-4431"    "USB-4431"    1×1

Next, knowing that this device only supports clocked operations, you can disable the warning.

ws = warning("off","daq:Session:clockedOnlyChannelsAdded");
% restore warning state when cleared
oc = onCleanup(@() warning(ws));

Setup the NI device with a sampling rate of 48 kHz, one input, and one output.

To do so, create a daq object for NI devices and set Rate to 48 kHz.

FS = 48e3;
dq = daq("ni");
dq.Rate = FS;
dev = "Dev1";

Add one input and one output. In this example, the microphone has its own pre-amplifier, so set the measurement type to Voltage. The output is connected to a powered loudspeaker and the measurement type is set to Voltage.


Stimulus Signal

Create an exponential swept sine going from 20 Hz to 24 kHz over a period of 3 seconds, followed by one second of silence. This limits the maximum impulse response length to one second. You can also set the output level, in this case -18 dB.

irDur = 1;
sweepDur = 3;
outputLevel = -18;
sweepRange = [20 24000];

exc = sweeptone( ...
    sweepDur, irDur, FS, ...
    ExcitationLevel=outputLevel, ...

Response Measurement

Using the readwrite method of the daq object (dq), play the swept sine stimulus (exc) and simultaneously record the response.

data = readwrite(dq,exc);
dq = []; % release

Compute the Impulse Response

Use the impzest function to compute the impulse response (ir) from the stimulus (exc) and its response.

response = data.Variables;
ir = impzest(exc,response);

Create the corresponding time vector.

t_sec = (0:length(ir)-1).'/FS;

Display the Results

Plot the first 10 milliseconds, in this case, 480 samples.

totalDur = sweepDur*FS;
n = 480;
plot(t_sec(1:n), ir(1:n))
title("Impulse Response")
xlabel("Time (s)")
grid on

Impulse Response Measurer App

Another way of writing the code above is to start from a script generated from the Impulse Response Measurer app. Start the app by entering impulseResponseMeasurer at the command prompt. You can also click the app icon on the Apps tab of the MATLAB® Toolstrip. Even without a supported device connected, you can set the Method Settings, Display Settings and a linear or log scale for magnitude and phase responses (using the toolbar that appears when hovering the mouse over these plots). Then, click Generate Script. A new document will appear in the editor with code for an audio device, that you will modify to use the NI USB-4431.


Script Customization

First, you may want to make this a function by adding function capture = irm_usb4431 to the top of the file, and an end statement before the first embedded function.

The function to interface with the NI device can take a complete signal, without proceeding frame by frame. Consequently, remove the code for "Allocate the input/output buffers" and "Copy the excitation to the output buffer".

The code required to "Setup the audio device" can be replaced by code to setup the NI USB-4431 device. Set the sample rate of the device and add an output and at least one input.

dq = daq("ni");
dq.Rate = 48e3; % Sampling rate

The playback and capture loop can be replaced by a readwrite statement. Get the results from data.Variables instead of the buffer. Also get the handle from the first figure to facilitate zooming in.

Now run the customized function irm_usb4431 to obtain the capture data and plot the results and zoom in.

[capture,ax1] = irm_usb4431();
xlim(ax1,[0 10e-3]);

The data is also available programmatically.

capture = struct with fields:
      ImpulseResponse: [1×1 struct]
    MagnitudeResponse: [1×1 struct]
        PhaseResponse: [1×1 struct]

For example, plot the first 480 samples of the impulse response.

figure % new figure
plot(capture.ImpulseResponse.Time(1:480), capture.ImpulseResponse.Amplitude(1:480))
title("Impulse Response")
xlabel("Time (s)")
grid on

See Also