Perceived sharpness of acoustic signal
Acoustic Sharpness of Audio Signal
Compute the acoustic sharpness of turbine noise. Assume it is stationary and was recorded in a diffuse sound field.
[audioIn,fs] = audioread('Turbine-16-44p1-mono-22secs.wav'); sharpness = acousticSharpness(audioIn,fs,'SoundField','diffuse'); fprintf('Acoustic sharpness = %0.2f acum\n',sharpness)
Acoustic sharpness = 1.11 acum
Read in an audio signal.
[audioIn,fs] = audioread('RockDrums-48-stereo-11secs.mp3');
Plot the time-varying sharpness of the signal. Listen to the signal.
Measure Loudness and Sharpness of Stationary Signals
Create two stationary signals with equivalent power: a pink noise signal and a white noise signal.
fs = 48e3; dur = 5; pnoise = 2*pinknoise(dur*fs); wnoise = rand(dur*fs,1) - 0.5; wnoise = wnoise*sqrt(var(pnoise)/var(wnoise));
acousticLoudness using the default ISO 532-1 (Zwicker) method and no output arguments to plot the loudness of the pink noise. Call
acousticLoudness again, this time with output arguments, to get the specific loudness.
[~,pSpecificLoudness] = acousticLoudness(pnoise,fs);
Plot the loudness for the white noise signal and then get the specific loudness values.
[~,wSpecificLoudness] = acousticLoudness(wnoise,fs);
acousticSharpness function to compare the sharpness of the pink noise and white noise.
pSharpness = acousticSharpness(pSpecificLoudness); wSharpness = acousticSharpness(wSpecificLoudness); fprintf('Sharpness of pink noise = %0.2f acum\n',pSharpness)
Sharpness of pink noise = 2.00 acum
fprintf('Sharpness of white noise = %0.2f acum\n',wSharpness)
Sharpness of white noise = 2.62 acum
Effect of Input Levels on Acoustic Sharpness
Create a pink noise signal with a 48 kHz sample rate and a duration of 5 seconds.
fs = 48e3; n = fs*5; pnoise = pinknoise(n);
Specify a vector to sweep over the dB range from -60 to 20. Create a gain vector which, when multiplied by the original signal, results in a signal with the desired output level.
dBSweep = -60:10:20; coefSweep = sqrt((10.^(dBSweep/10))/var(pnoise));
acousticSharpness in a loop with the different signal levels. Determine the sharpness using the default DIN 45692 frequency weighting and the Aures frequency weighting.
sharpnessDIN45692 = zeros(numel(dBSweep),1); sharpnessAures = zeros(numel(dBSweep),1); for ii = 1:numel(dBSweep) signal = pnoise*coefSweep(ii); sharpnessDIN45692(ii) = acousticSharpness(signal,fs); sharpnessAures(ii) = acousticSharpness(signal,fs,'Weighting','Aures'); end
Display the effect of the input level on the acoustic sharpness. The Aures frequency weighting method is more sensitive to the input level.
plot(dBSweep,sharpnessDIN45692,dBSweep,sharpnessAures) legend('Weighting = DIN45692','Weighting = Aures') xlabel('Input Level (dB)') ylabel('Sharpness (acum)') title('Effect of Input Level on Sharpness') axis([dBSweep(1) dBSweep(end) 0 20]) grid on
Compare Time-Varying Sharpness of Music Genres
Read in two audio files: one of an electric guitar with distortion and one of an acoustic guitar. Both audio files have a sample rate of 44.1 kHz. For easy comparison, convert the rock guitar signal to mono and shorten the soft guitar signal to the length of the rock guitar signal.
fs = 44.1e3; rockGuitar = audioread('RockGuitar-16-44p1-stereo-72secs.wav'); softGuitar = audioread('SoftGuitar-44p1_mono-10mins.ogg'); rockGuitar = mean(rockGuitar,2); softGuitar = softGuitar(1:numel(rockGuitar));
Calculate the time-varying sharpness for both the rock guitar and soft guitar.
rGSharpness = acousticSharpness(rockGuitar,fs,'TimeVarying',true); sGSharpness = acousticSharpness(softGuitar,fs,'TimeVarying',true);
Plot the probability distribution based on the observed sharpness of the rock guitar and the soft guitar.
histogram(rGSharpness,'Normalization','probability') hold on histogram(sGSharpness,'Normalization','probability') legend('Electric Guitar','Soft Guitar') xlabel('Sharpness (acum)') ylabel('Probability') title('Time-Varying Acoustic Sharpness (DIN 45692)')
Measure Acoustic Sharpness from Sound Pressure Level
Read in an audio file.
[audioIn,fs] = audioread('Turbine-16-44p1-mono-22secs.wav');
To calculate sound pressure levels from an audio signal, first create an
splMeter object. Call the
splMeter object with the audio input.
spl = splMeter("SampleRate",fs,"Bandwidth","1/3 octave", ... "FrequencyWeighting","Z-weighting","OctaveFilterOrder",6); splMeasurement = spl(audioIn);
Compute the mean SPL level, skipping the first 0.2 seconds. Only keep the bands from 25 Hz to 12.5 kHz (the first 28 bands).
SPLIn = mean(splMeasurement(ceil(0.2*fs):end,1:28));
To determine the acoustic sharpness of the audio signal, call
acousticSharpness using the sound pressure level input.
sharpness = acousticSharpness(SPLIn)
sharpness = 1.1015
audioIn — Audio input
column vector | 2-column matrix
Audio input, specified as a column vector (mono) or matrix with two columns (stereo). Sharpness is computed for each channel (column) independently.
fs — Sample rate (Hz)
Sample rate in Hz, specified as a positive scalar. The recommended sample rate for new recordings is 48 kHz.
The minimum acceptable sample rate is 8 kHz.
calibrationFactor — Microphone calibration factor
sqrt(8) | positive scalar
Microphone calibration factor, specified as a positive scalar. The default
calibration factor corresponds to a full-scale 1 kHz sine wave with a sound pressure
level of 100 dB (SPL). To compute the calibration factor specific to your system, use
SPLIn — Sound pressure level (dB)
Sound pressure level (SPL) in dB, specified as a 1-by-28-by-C array. 28 corresponds to one-third-octave bands between 25 Hz and 12.5 kHz. C is the number of channels.
specificLoudnessIn — Specific loudness (sones/Bark)
Specific loudness in sones/Bark, specified as a T-by-240-by-C array, where:
T is 1 for stationary signals or one per 2 ms for time-varying signals.
240 is the number of Bark bins in the domain for specific loudness. The Bark bins are
C is the number of channels.
You can use the
acousticLoudness function to calculate
specificLoudnessIn using this
[~,specificLoudnessIn] = acousticLoudness(audioIn,fs);
Specify optional pairs of arguments as
the argument name and
Value is the corresponding value.
Name-value arguments must appear after other arguments, but the order of the
pairs does not matter.
Before R2021a, use commas to separate each name and value, and enclose
Name in quotes.
Weighting — Frequency weighting
'DIN 45692' (default) |
Frequency weighting, specified as
'von Bismarck'. By design, the
'Aures' frequency weighting method is more sensitive to amplitude
levels and proper calibration. For details, see Algorithms.
SoundField — Sound field
'free' (default) |
Sound field of audio recording, specified as
PressureReference — Reference pressure (Pa)
20e-6 (default) | positive scalar
Reference pressure for dB calculation in pascals, specified as a positive scalar. The default value, 20 micropascals, is the common value for air.
TimeVarying — Input is time-varying
false (default) |
Input is time-varying, specified as
TimeVarying is set to
true, acoustic sharpness is calculated in 2 ms intervals.
sharpness — Acoustic sharpness (acum)
scalar | vector | matrix
Acoustic sharpness in acum, returned as a scalar, vector, or matrix. Sharpness is computed according to DIN 45692 and ISO 532-1.
Acoustic sharpness is a measurement derived from acoustic loudness. The acoustic loudness
algorithm is described in  and implemented in the
function. The acoustic sharpness calculation is described in . The algorithm for acoustic
sharpness is outlined as follows.
Where N' is the specific loudness in sones/Bark. The
function g(z) and the scaling factor
k depend on the specified
'DIN 45692': k is
set such that a 1 kHz reference tone results in a 1 acum sharpness measurement, and
'von Bismark': k is
'Aures': k is set
 ISO 532-1:2017(E). "Acoustics – Methods for calculating loudness – Part 1: Zwicker method." International Organization for Standardization.
 DIN 45692:2009. "Measurement Technique for the Simulation of the Auditory Sensation of Sharpness." German Institute for Standardization.
C/C++ Code Generation
Generate C and C++ code using MATLAB® Coder™.
Introduced in R2020a