File Exchange Pick of the Week

Our best user submissions

The Speech Transmission Index (STI)

Posted by Sean de Wolski,

Sean‘s pick this week is The Speech Transmission Index (STI) by Jacob D.

Background

According to Wikipedia, the Speech Transmission Index is a metric ranging from 0 to 1 that can be used to understand how intelligible speech will be across a room. Jacob has provided us a with a tool to do this.

I wanted to test it with the three microphones I have on my desk:

  • Laptop microphone (low quality)
  • Headset (high quality, used for recording webinars)
  • Speaker (decent quality)

To use this, I needed to generate an impulse response and record it on the three devices. This was surprisingly simple with
Simulink and the Audio System Toolbox. I created a simple Simulink model and used three Audio Device Reader Blocks to read from the three mics, each linked to its own WAV file writer.

Here’s the Simulink model and the audio signal displayed with a dashboard scope.

Then, being sophisticated, I took a ChannelLock wrench and used it to hit a book on my desk next to the microphones to generate the impulse response. Don’t worry, the book was one of those unexciting ones you get from corporate training sessions, not something technical.

With the audio files stored, I can then read each one in and calculate its STI. To simplify this, I’m used some of the “Big Data” tools which provide an easy interface for working with many files even if the data aren’t large. Here I will use a fileDatastore with a custom read function which reads the file, calculates its STI, and plots the original signal. Notice that I do not need to handle the looping over the files and other bookkeeping things myself.

Here’s the custom read function, calcSTI:

function thisSTI = calcSTI(filename)
% Gets STI given audio filename    
    info = audioinfo(filename);
    fs = info.SampleRate;
    data = audioread(filename);
    thisSTI = STI(data, fs);
    hold on
    plot(data, 'DisplayName', filename)
end

Use it to read all files and display results:

ds = fileDatastore('*.wav', 'ReadFcn', @calcSTI)
stis = readall(ds);
leg = legend('show');
leg.Interpreter = 'none';
leg.Location = 'southoutside';
ylabel('Audio Signal')
xlabel('Samples')
STIs = table(ds.Files, stis, 'VariableNames', {'Filename', 'STI'})
ds = 
  FileDatastore with properties:

      Files: {
             'C:\Documents\MATLAB\potw\STI\outputhandset.wav';
             'C:\Documents\MATLAB\potw\STI\outputheadset.wav';
             'C:\Documents\MATLAB\potw\STI\outputlaptop.wav'
             }
    ReadFcn: @calcSTI
STIs =
  3×2 table
                        Filename                          STI   
    ________________________________________________    ________
    'C:\Documents\MATLAB\potw\STI\outputhandset.wav'    [0.8083]
    'C:\Documents\MATLAB\potw\STI\outputheadset.wav'    [0.9348]
    'C:\Documents\MATLAB\potw\STI\outputlaptop.wav'     [0.7363]

The STIs look about like what I would expect with the headset being the best, the speaker phone in the middle, and the laptop the lowest.

Comments

Give it a try and let us know what you think here or leave a comment for Jacob.

Get the MATLAB code

Published with MATLAB® R2017a

Add A Comment

What is 3 + 7?

Preview: hide