Advertisement
Guest User

Untitled

a guest
Oct 21st, 2017
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.91 KB | None | 0 0
  1. import numpy as np
  2. from matplotlib import pyplot as plt
  3. import scipy.io.wavfile as wav
  4. from numpy.lib import stride_tricks
  5.  
  6. """ short time fourier transform of audio signal """
  7. def stft(sig, frameSize, overlapFac=0.5, window=np.hanning):
  8. win = window(frameSize)
  9. hopSize = int(frameSize - np.floor(overlapFac * frameSize))
  10.  
  11. # zeros at beginning (thus center of 1st window should be for sample nr. 0)
  12. samples = np.append(np.zeros(np.floor(frameSize/2.0)), sig)
  13. # cols for windowing
  14. cols = np.ceil( (len(samples) - frameSize) / float(hopSize)) + 1
  15. # zeros at end (thus samples can be fully covered by frames)
  16. samples = np.append(samples, np.zeros(frameSize))
  17.  
  18. frames = stride_tricks.as_strided(samples, shape=(cols, frameSize), strides=(samples.strides[0]*hopSize, samples.strides[0])).copy()
  19. frames *= win
  20.  
  21. return np.fft.rfft(frames)
  22.  
  23. """ scale frequency axis logarithmically """
  24. def logscale_spec(spec, sr=44100, factor=20.):
  25. timebins, freqbins = np.shape(spec)
  26.  
  27. scale = np.linspace(0, 1, freqbins) ** factor
  28. scale *= (freqbins-1)/max(scale)
  29. scale = np.unique(np.round(scale))
  30.  
  31. # create spectrogram with new freq bins
  32. newspec = np.complex128(np.zeros([timebins, len(scale)]))
  33. for i in range(0, len(scale)):
  34. if i == len(scale)-1:
  35. newspec[:,i] = np.sum(spec[:,scale[i]:], axis=1)
  36. else:
  37. newspec[:,i] = np.sum(spec[:,scale[i]:scale[i+1]], axis=1)
  38.  
  39. # list center freq of bins
  40. allfreqs = np.abs(np.fft.fftfreq(freqbins*2, 1./sr)[:freqbins+1])
  41. freqs = []
  42. for i in range(0, len(scale)):
  43. if i == len(scale)-1:
  44. freqs += [np.mean(allfreqs[scale[i]:])]
  45. else:
  46. freqs += [np.mean(allfreqs[scale[i]:scale[i+1]])]
  47.  
  48. return newspec, freqs
  49.  
  50. """ plot spectrogram"""
  51. def plotstft(audiopath, binsize=2**10, plotpath=None, colormap="jet"):
  52. samplerate, samples = wav.read(audiopath)
  53. s = stft(samples, binsize)
  54.  
  55. sshow, freq = logscale_spec(s, factor=1.0, sr=samplerate)
  56. ims = 20.*np.log10(np.abs(sshow)/10e-6) # amplitude to decibel
  57.  
  58. timebins, freqbins = np.shape(ims)
  59.  
  60. plt.figure(figsize=(15, 7.5))
  61. plt.imshow(np.transpose(ims), origin="lower", aspect="auto", cmap=colormap, interpolation="none")
  62. plt.colorbar()
  63.  
  64. plt.xlabel("time (s)")
  65. plt.ylabel("frequency (hz)")
  66. plt.xlim([0, timebins-1])
  67. plt.ylim([0, freqbins])
  68.  
  69. xlocs = np.float32(np.linspace(0, timebins-1, 5))
  70. plt.xticks(xlocs, ["%.02f" % l for l in ((xlocs*len(samples)/timebins)+(0.5*binsize))/samplerate])
  71. ylocs = np.int16(np.round(np.linspace(0, freqbins-1, 10)))
  72. plt.yticks(ylocs, ["%.02f" % freq[i] for i in ylocs])
  73.  
  74. if plotpath:
  75. plt.savefig(plotpath, bbox_inches="tight")
  76. else:
  77. plt.show()
  78.  
  79. plt.clf()
  80.  
  81. plotstft("my_audio_file.wav")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement