I have:

music = Import["http://www.qlcoder.com/uploads/145425353234642.mp3", "mp3"]

Then I get:

enter image description here

But what I want to get is F(t)=x Hz(means in t, the frequency is x Hz). Then how to get that?

  • 2
    What if there are superimposed sounds of multiple frequencies (as is almost always the case)? Then a simple frequency(t) doesn't make sense. You may want to compute a spectrogram: mathematica.stackexchange.com/questions/4017/… – Szabolcs Feb 1 '16 at 13:10
  • If you know for sure that there is only a single (possibly amplitude and frequency modulated) sine oscillator active (e.g. $f(t)=a(t)sin(\omega(t)),\omega(t)=\omega_0 + \int_0^t 2\pi f(s) ds$), then you can see your waveform as the real part of a complex (as in complex numbers) oscillator. You can then use a Hilbert transform (see here) to get the corresponding imaginary part of that oscillator and use this to reconstruct $a(t)$ and $f(t)$ (which is just $\frac{d\omega(t)}{dt}$). – Thies Heidecke Feb 1 '16 at 18:03
up vote 6 down vote accepted

Duration = 9.95265 sec, frequency in Hz on x axis:

music = Import["http://www.qlcoder.com/uploads/145425353234642.mp3", "mp3"];
amps = music[[1, 1, 1, All]];
namps = Length@amps; (* namps = 438912 corresponds to 9.95265 sec *)

sr = 44100; (* your sampling rate in Hz *)
inc = sr/namps; (* increment *)
freq = Table[f, {f, 0, sr - inc, inc}] // N;

y = Abs@Fourier[amps, FourierParameters -> {-1, 1}];
data = Transpose[{freq, y}];

fmax = 3000; (* you can go up to Nyquist frequence = max frequency = 22050 Hz *)

ListLinePlot[data, Frame -> True, Joined -> True, 
 PlotStyle -> {RGBColor[0, 0, 1], Thickness[0.002]}, 
 FrameLabel -> {{"Amplitude", ""}, {"f (Hz)", ""}}, 
 BaseStyle -> {FontWeight -> "Bold", FontSize -> 20, 
   FontFamily -> "Calibri"}, PlotRange -> {{0, fmax}, All}, 
 ImageSize -> 800]

enter image description here

You can see the spectrum of the first note played, (first 40000 points)

ListLogLogPlot[
 {#, # PeakDetect[#, 5, 10^-2]} &@
  Abs@Fourier@music[[1, 1, 1, 1 ;; 40000]]
 , Joined -> {True, False}
 , PlotStyle -> {Gray, Red}
 , Filling -> Axis
 , PlotRange -> {{100, 1000}, All}
 , PlotTheme -> "Scientific"]

Mathematica graphics

But beware that the scaling is not in Hertz here To get the scaling correct use:

sft[d_, sr_] := Block[{n, ft, fy},
  n = Length[d];
  fy = Take[N@Abs[Fourier[d]], n/2];
  ft = N@Range[0, n/2 - 1] sr/n;
  SortBy[First]@Transpose[{ft, fy}]
  ]

ListLogLogPlot[
 {#, Part[#, 
     Flatten@Position[PeakDetect[#[[All, 2]], 5, 10^-2], 1]]} &@
  sft[music[[1, 1, 1, 1 ;; 40000]], music[[1, 2]]]
 , Joined -> {True, False}
 , PlotStyle -> {Gray, Red}
 , Filling -> Axis
 , PlotRange -> {{100, 1000}, All}
 , PlotTheme -> "Scientific"]

Mathematica graphics

To see the peaks of the first two notes:

Part[#, Flatten@Position[PeakDetect[#[[All, 2]], 5, 10^-2], 1]] &@
 sft[music[[1, 1, 1, 1 ;; 40000]], music[[1, 2]]]
 {{174.195, 4.61849}, {350.595, 5.65904}, {524.79, 3.73059}}
Part[#, Flatten@Position[PeakDetect[#[[All, 2]], 5, 10^-2], 1]] &@
 sft[music[[1, 1, 1, 40001 ;; 70000]], music[[1, 2]]]
{{164.64, 3.93114}, {330.75, 3.66594}, {495.39, 1.70307}, {660.03, 4.29606}, {826.14, 1.9469}}

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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