7

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?

Sayakiss
  • 859
  • 7
  • 13
  • 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: http://mathematica.stackexchange.com/questions/4017/computing-and-plotting-a-spectrogram-in-mathematica – Szabolcs Feb 01 '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 01 '16 at 18:03

2 Answers2

13

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}}
rhermans
  • 36,518
  • 4
  • 57
  • 149
7

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

mrz
  • 11,686
  • 2
  • 25
  • 81