I have several sung melodies under each of nine conditions. The melodies are all of slightly different lengths (ranging more or less from 3s to 12s), and each is encoded as a discretised melodic contour (pitch profile), at one sample per ms (fs=1000 Hz). It is those, rather than the original audio, that represent the level of analysis of interest. See top-side of the first set of plots below.


First, I'd like to characterize the average power spectrum of these melodies taken as a group (within each condition), in order to speculate about slow/fast changes in melodic contour. Some, such as Marc Evans - Spectral Melody Decomposition have suggested that, when applying Fourier analysis to investigate the pitch contour of a melody, the lower partials that result are responsible for the overall shape of melody, while the higher partials are responsible the more surface-level ornamentation.

Second, I'd like to compare these characterizations across conditions.


  1. The first set of plots in the code below is a sanity check that produces the correct time-domain profiles of individual melodies (left-hand side). But their power spectrum (right-hand side) always comes up in the same shape, reminiscent of the reciprocal (1/x) function. As per the code comments, detrending the signals doesn’t help (so this is not just an unruly DC component), nor does using FFT() directly, instead of the Welch estimation that I chose. Is this a problem with how the spectrum was computed/displayed? Or is such a result in fact expected? I tried downsampling to reduce the repetition of identical values, but it doesn't make a difference. I also thought that the signal consisting of only a few (very slow) step changes, rather than a proper oscillation of suitable length, might be a problem; but computing the spectrum for a large contour (obtained by merging together all contours within one condition) produces a similar result.

  2. Worse still, the second set of plots shows the average spectra shapes to ALL be (almost identical) 1/x-type shapes, across all my nine conditions. This is despite the melodic contours between and within conditions being very variable.

  3. Although it makes sense for the averaging to be done in the frequency domain, I tried to IFFT each average back into the time domain (second set of plots, left-hand-side). The result is, once again, almost identical signals, whereas I expected to get something resembling various shapes of average melodic contours. Again, is the transform computed somehow incorrectly?

  4. Because of the unequal melody lengths, I've had to either zero-fill up to the length of the longest melody or trim down to the length of the shortest one. None of these compromises is ideal however, as the former I believe introduces artefacts, and the latter loses me lots of samples from the longer melodies. Is there a way to keep each melody's original length?


pxx_within_this_condition = [];
w_within_this_condition = [];

for i_melody = 1:N_melodies
    x = retrievemel(i_melody);          
    x = detrend(x,0); % Detrending the input signal doesn't make a difference to the reported problem.
    Nx = length(x);
    window = floor(Nx * 1/2); % segment length in samples
    noverlap = floor(window/2); % amount of overlap, in samples. 50% seems often used
    nfft = max(256, 2^nextpow2(window));
    fs = 1000;
    [pxx, w] = pwelch(x, hamming(window), noverlap, nfft,    'psd'); % using just "pwelch(x)" (default), specifying spectrumtype = 'power' or 'psd', or just window instead of hamming(window) as an argument, doesnt make a difference to the reported problems
    % using the plain FFT instead of the Welch estimatiom method gives artefactual-looking results also
    %                   pxx = fft(x);
    %                   pxx = abs(pxx/Nx);
    % debug-plotting of individual melodic contours one at a time and their respective spectra
    pxx_within_this_condition = [   pxx_within_this_condition;      pxx'    ];
    w_within_this_condition = [ w_within_this_condition;            w'  ];  

% average
pxx_current_condition = mean(pxx_within_this_condition, 1); % avg across the columns of the matrix (result = row vector). I understand it's ok to average only values in the magnitude/power spectrum, and ignore the phase spectrum
w_current_condition   = mean(  w_within_this_condition, 1);

% plot FFT as estimated by the Welch method
plot(w_current_condition, 10*log10(pxx_current_condition))

% plot in the time domain the signal to which the fq-domain average above would correspond, via IFFT
X = ifft(pxx_current_condition, 'symmetric'); % 'symmetric' ensures that the output is real, though not sure we really have conjugate symmetric vectors


enter image description here

enter image description here

  • $\begingroup$ Sorry, it's not clear what you are trying to do here. Please define "melody" and "condition" in proper technical or scientific terms. Are you using sine waves, are you stitching together samples etc ? What are the actual frequencies ? "Some frequency domain scale" really isn't helpful. I also assume you would want a log frequency axis (as is standard or audio) but it's hard to tell. I'm guessing that all the detail you want to see is squished in the very left edge of your graphs. $\endgroup$
    – Hilmar
    Mar 1, 2023 at 7:48
  • $\begingroup$ Finally, doing a PSD over the whole signal will contain all frequencies. If you want frequency over time you need a spectrogram or short time Fourier transform. $\endgroup$
    – Hilmar
    Mar 1, 2023 at 7:48
  • $\begingroup$ Apologies if this was not clear, I will edit the question later when I am at my PC and provide brief clarification now. "Condition" is meant in the experimental sense of data obtained under different conditions, such as different moments of data collection, or different types of subjects. Melodies aw considered only in terms of their abstractized pitch contours, thus no actual audio (sine or otherwise) is involved. The pitches of the individual notes range more or less between C3 and C5. $\endgroup$
    – z8080
    Mar 1, 2023 at 9:25
  • $\begingroup$ The levity in labeling that x axis had to do with the fact that (due to having last looked at those thing long ago) it's not very clear to me what the units of measurements are for that particular frequency domain plot, given the scaling that happened. Finally, it is not the frequency over time that I want (so a spectrogram per se wouldn't be the right tool), but the frequency components corresponding to each individual melodic profile, so as to later examine - as I mentioned - their average. Hope that makes more sense! $\endgroup$
    – z8080
    Mar 1, 2023 at 13:47


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.