audio_spectrogram_plot.py 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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():
  14. """ """
  15. sampling_rate, audio = wavfile.read(
  16. str(Path.home() / "Data" / "Audio" / "Nightingale-sound.wav")
  17. )
  18. audio = numpy.mean(audio, axis=1)
  19. num_samples = audio.shape[0]
  20. length_sec = num_samples / sampling_rate
  21. print(f"Audio length: {length_sec:.2f} seconds")
  22. def a():
  23. """ """
  24. n_fft = 32
  25. s = FastFourierTransformPlot(n_fft=n_fft, sampling_rate=sampling_rate)
  26. for sample in audio:
  27. s.draw(sample)
  28. def b():
  29. """ """
  30. n_fft = 32
  31. delta = 1 / sampling_rate
  32. s = FastFourierTransformSpectrogramPlot(
  33. n_fft=n_fft,
  34. sampling_rate=sampling_rate,
  35. buffer_size_sec=delta * n_fft * 4,
  36. )
  37. for sample in audio:
  38. s.draw(sample)
  39. def c():
  40. """ """
  41. f, ax = pyplot.subplots()
  42. ax.plot(numpy.arange(num_samples) / sampling_rate, audio)
  43. ax.set_xlabel("Time [s]")
  44. ax.set_ylabel("Amplitude [unknown]")
  45. pyplot.show()
  46. def d():
  47. """ """
  48. from skimage import util
  49. M = 1024
  50. slices = util.view_as_windows(audio, window_shape=(M,), step=100)
  51. print(f"Audio shape: {audio.shape}, Sliced audio shape: {slices.shape}")
  52. win = numpy.hanning(M + 1)[:-1]
  53. slices = slices * win
  54. slices = slices.T
  55. print("Shape of `slices`:", slices.shape)
  56. spectrum = numpy.fft.fft(slices, axis=0)[: M // 2 + 1 : -1]
  57. spectrum = numpy.abs(spectrum)
  58. f, ax = pyplot.subplots(figsize=(4.8, 2.4))
  59. S = numpy.abs(spectrum)
  60. S = 20 * numpy.log10(S / numpy.max(S))
  61. ax.imshow(
  62. S,
  63. origin="lower",
  64. cmap="viridis",
  65. extent=(0, length_sec, 0, sampling_rate / 2 / 1000),
  66. )
  67. ax.axis("tight")
  68. ax.set_ylabel("Frequency [kHz]")
  69. ax.set_xlabel("Time [s]")
  70. pyplot.show()
  71. d()
  72. main()