1
$\begingroup$

Context: PSD=periodogram(y) in MATLAB gives the PSD (power spectral density) estimate of a sound-source signal. I want to find the local maximum within 3 different x ranges of PSD.

How do I make a vector that maps 1:1 to the PSD -y value vector?enter image description here The x values that MATLAB generates are Hz - frequency values, so I don't want to change the values per se, but create a vector that goes from x=0:3500, but have the same number of elements as the PSD vector, PSD= 32769*1 double.

How do I do this while retaining the same data? PSD plot. acquired with plot(PSD) <-- x values generated by MATLAB

  [1]: https://i.stack.imgur.com/PiYGB.png

    %% formantdaddy will try to do all the steps of the process
% 1. grab sound from folder
% 2. get PSD = Power Spectral Density
% 3. look for local maxima within prefined ranges 
    % 200 - 800 Hz
    % 800 - 1800 Hz
    % 1800 - 3500 Hz
%store data into a struct

clear all;
close all;
clc;
%% audioread .wav file
[y Fs]= audioread('100-daddy1.wav');
%% y=source signal
sourceFig=figure(1);
plot(y);
xlabel('milliseconds'); ylabel('amplitude'); title('spectrogram = voice source signal');

%% PSD - Power Spectral Density <-- peaks here should give formants
filterfcn=figure(2);
PSD=periodogram(y); %calculate the power spectral density of the source signal
plot(PSD);
ylabel('magnitude || intensity of signal'); xlabel('frequency in Hz'); title('PSD of Source');
xlim([0, .35*10^4]);
%% F1 range  
subset1=zeros(1, 601); %create a vector to store PSD values within the range of interest
for x=200:800;
    subset1(x)=PSD(x);% input in the values of interest
end

for x=200:800;
    Y_max=max(subset1);
    F1=x;
end
disp(F1);
disp(Y_max);
% find the max value within the range
%PROBLEM: wanted to find the x value which corresponded to the max y <-- but this actually is the max y value
%PROBLEM: x vector not the same size as PSD values within the range, so many points not considered. 

%% F2 range
subset2=zeros(1, 1001);
for x=800:1800;
    subset2(x)=PSD(x);
end

for x=800:1800;
    Y2_max=max(subset2);
    F2=x;
end
disp(F2);
disp(Y2_max);
%% F3 range
subset3=zeros(1, 1701);
for x=1800:3500;
    subset3(x)=PSD(x);
end
for x=1800:3500;
    Y3_max=max(subset2);
    F3=x;
end
disp(F3);
disp(Y3_max);
%% store values into a struct
Ftable=struct("FileName", "100-daddy1.wav", "F1_Hz", F1, "F2_Hz", F2, "F3_Hz", F3);
$\endgroup$
0
$\begingroup$

For function call [pxx, f] = periodogram(y_soundsource_data,window,nfft, Fs); you can get the pxx = PSD points= vector of y values, and f= frequency points tied 1:1 to the pxx values.

... this requires that you specify nfft & Fs

  1. You can get y_soundsource_data and Fs<-- sampling frequency, from the audioread function. file[y Fs]= audioread('100-daddy1.wav');
  2. window and nfft are not understood by the periodogram function UNLESS you define them.

    • y_soundsource_data and Fs are understood, because audioread returns the data metrics.
    • nfft - refers to the number of points used in the DFT. A larger nfft value will lead to a better estimation. nfft MUST be an integer. You can't have half a point.
    • window = vector of the size of the y_soundsource_data. 1:length_y_soundsource_data
    • both window and nfft need to be defined before you call the periodogram function.

    code

variable data-types and sizes

plot figure(4)

followup keep getting errors with the [pxx,f] = periodogram(_,fs) version of the call. mathworks.com/help/signal/ref/periodogram.html

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.