audio_spectrogram_plot.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. __author__ = "Christian Heider Nielsen"
  4. __doc__ = r"""
  5. Created on 06/04/2020
  6. """
  7. from pathlib import Path
  8. import numpy
  9. from matplotlib import pyplot
  10. from scipy.io import wavfile
  11. from draugr.drawers import FastFourierTransformPlot, FastFourierTransformSpectrogramPlot
  12. if __name__ == "__main__":
  13. def main() -> None:
  14. """
  15. :rtype: None
  16. """
  17. sampling_rate, audio = wavfile.read(
  18. str(Path.home() / "Data" / "Audio" / "Nightingale-sound.wav")
  19. )
  20. audio = numpy.mean(audio, axis=1)
  21. num_samples = audio.shape[0]
  22. length_sec = num_samples / sampling_rate
  23. print(f"Audio length: {length_sec:.2f} seconds")
  24. def a():
  25. """description"""
  26. n_fft = 32
  27. s = FastFourierTransformPlot(n_fft=n_fft, sampling_rate=sampling_rate)
  28. for sample in audio:
  29. s.draw(sample)
  30. def b():
  31. """description"""
  32. n_fft = 32
  33. delta = 1 / sampling_rate
  34. s = FastFourierTransformSpectrogramPlot(
  35. n_fft=n_fft,
  36. sampling_rate=sampling_rate,
  37. buffer_size_sec=delta * n_fft * 4,
  38. )
  39. for sample in audio:
  40. s.draw(sample)
  41. def c():
  42. """description"""
  43. f, ax = pyplot.subplots()
  44. ax.plot(numpy.arange(num_samples) / sampling_rate, audio)
  45. ax.set_xlabel("Time [s]")
  46. ax.set_ylabel("Amplitude [unknown]")
  47. pyplot.show()
  48. def d():
  49. """description"""
  50. from skimage import util
  51. M = 1024
  52. slices = util.view_as_windows(audio, window_shape=(M,), step=100)
  53. print(f"Audio shape: {audio.shape}, Sliced audio shape: {slices.shape}")
  54. win = numpy.hanning(M + 1)[:-1]
  55. slices = slices * win
  56. slices = slices.T
  57. print("Shape of `slices`:", slices.shape)
  58. spectrum = numpy.fft.fft(slices, axis=0)[: M // 2 + 1 : -1]
  59. spectrum = numpy.abs(spectrum)
  60. f, ax = pyplot.subplots(figsize=(4.8, 2.4))
  61. S = numpy.abs(spectrum)
  62. S = 20 * numpy.log10(S / numpy.max(S))
  63. ax.imshow(
  64. S,
  65. origin="lower",
  66. cmap="viridis",
  67. extent=(0, length_sec, 0, sampling_rate / 2 / 1000),
  68. )
  69. ax.axis("tight")
  70. ax.set_ylabel("Frequency [kHz]")
  71. ax.set_xlabel("Time [s]")
  72. pyplot.show()
  73. d()
  74. main()