PageRenderTime 37ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/sampler.py

https://gitlab.com/nexemjail/mir
Python | 223 lines | 148 code | 50 blank | 25 comment | 20 complexity | db7646b55ffff926967eca6576a7a18a MD5 | raw file
  1. import numpy as np
  2. import librosa
  3. import scipy
  4. import scipy.signal
  5. from math import sqrt
  6. from math import log
  7. import scipy.signal.spectral
  8. def compute_variance(signal, mean):
  9. N = len(signal)
  10. return 1.0 / (N-1) * np.sum(signal-mean)
  11. def normalize_signal(signal, mean, variance):
  12. for index in xrange(len(signal)):
  13. signal[index] = (signal[index] - mean)/variance
  14. return signal
  15. def pre_emphasis(signal, alpha=0.9):
  16. new_sig = signal[1:]-alpha*signal[:-1]
  17. return np.append(signal[0], new_sig)
  18. def window_signal(signal, window_len=25):
  19. w = np.hamming(window_len)
  20. return np.convolve(w/w.sum(), signal, mode='same')
  21. def zero_crossing_rate(signal):
  22. N = len(signal)
  23. zcr = 0
  24. for i in xrange(1, N):
  25. zcr += np.abs(np.sign(signal[i]) - np.sign(signal[i-1]))
  26. zcr /= (2.0 * N)
  27. return zcr
  28. def temporal_centroid(signal):
  29. # returns centoid in ticks
  30. tc = np.sum(map(lambda (x, y): x*(y*y), enumerate(signal)))/ \
  31. np.sum(map(lambda (x, y): (y*y), enumerate(signal)))
  32. return tc
  33. def root_mean_square(signal):
  34. return np.sqrt(short_time_energy(signal))
  35. def short_time_energy(signal):
  36. N = len(signal)
  37. s = 0.0
  38. for i in xrange(N):
  39. s += abs(signal[i]**2)
  40. return s/N
  41. def autocorellation(signal, sample_rate):
  42. #autocorellation_value = max(librosa.autocorrelate(signal))
  43. signal_length = len(signal)
  44. power_spectrum = np.abs(scipy.fft(signal, n=2 * signal_length + 1 ))**2
  45. auto_corr = max(np.real(scipy.ifft(power_spectrum))[:])
  46. return auto_corr, auto_corr/2
  47. def energy_entropy(signal, num_of_frames = 22050 / 50):
  48. subframes = np.array_split(signal, num_of_frames)
  49. frame_energy = short_time_energy(signal)
  50. e = map(lambda (x, y): short_time_energy(y)/frame_energy,
  51. enumerate(subframes))
  52. entropy = 0
  53. for frame_index in xrange(num_of_frames):
  54. if e[frame_index] != 0:
  55. entropy -= e[frame_index] * log(e[frame_index],2)
  56. return entropy
  57. def spectral_spread(centroid, signal = None, fft_spectrum = None):
  58. if fft_spectrum is None and signal is not None:
  59. fft_spectrum = scipy.real(scipy.fft(signal))
  60. sum_abs_squared = sum(map(lambda (y,x): abs(x)**2, enumerate(fft_spectrum)))
  61. ss = sqrt((centroid ** 2 * sum_abs_squared) / sum_abs_squared)
  62. return ss
  63. def spectral_flux(signal = None, fft_spectrum = None):
  64. if fft_spectrum is None and signal is not None:
  65. fft_spectrum = scipy.real(scipy.fft(signal))
  66. flux_values = []
  67. flux = 0
  68. for element in fft_spectrum:
  69. flux += abs(element)
  70. flux_values.append(flux)
  71. for element in xrange(1, len(fft_spectrum)):
  72. prev = fft_spectrum[element-1]
  73. current = fft_spectrum[element]
  74. flux = abs(abs(current) - abs(prev))
  75. flux_values.append(flux)
  76. return np.array(flux_values)
  77. def spectral_entropy(signal = None, fft_signal = None, num_of_frames =22050 / 50):
  78. if fft_signal is not None and signal is not None:
  79. fft_signal = scipy.real(scipy.fft(signal))
  80. subframes = np.array_split(fft_signal, num_of_frames)
  81. frame_energy = short_time_energy(fft_signal)
  82. e = map(lambda (x, y): short_time_energy(y)/frame_energy,
  83. enumerate(subframes))
  84. entropy = 0
  85. for frame_index in xrange(num_of_frames):
  86. if e[frame_index] != 0:
  87. entropy -= e[frame_index] * log(e[frame_index],2)
  88. return entropy
  89. def compute_mfcc(signal, sample_rate, number_expected=13, num_of_triangular_features=23):
  90. return librosa.feature.mfcc(signal,
  91. sample_rate,
  92. n_mfcc=num_of_triangular_features)[:number_expected]
  93. def spectral_roloff(signal, sample_rate):
  94. return librosa.feature.spectral_rolloff(signal, sample_rate,)
  95. def spectral_centroid(signal, sample_rate):
  96. return librosa.feature.spectral_centroid(signal,sample_rate)
  97. class Sampler(object):
  98. def __init__(self, source, duration = None, sample_rate = None, offset = 0.0):
  99. if isinstance(source, basestring):
  100. self.signal, self.sample_rate = librosa.load(source, duration=duration, offset=offset)
  101. if duration is None:
  102. self.duration = librosa.get_duration(self.signal, sr=self.sample_rate)
  103. else:
  104. self.duration = duration
  105. else:
  106. self.signal = source
  107. self.sample_rate = sample_rate
  108. self.duration = librosa.get_duration(self.signal, sr=sample_rate)
  109. self.pre_process()
  110. def split(self, part_len):
  111. parts_count = self.duration // part_len
  112. return np.array_split(self.signal_emphased, parts_count)
  113. def pre_process(self):
  114. #plt.plot(self.signal,'r',)
  115. #plt.show()
  116. self.normalized_signal = librosa.util.normalize(self.signal)
  117. self.signal_emphased = pre_emphasis(self.normalized_signal)
  118. def compute_features(self):
  119. self.signal_hammed = window_signal(self.signal_emphased)
  120. self.fft = scipy.real(scipy.fft(self.signal_hammed))
  121. self.spectral_flux = spectral_flux(fft_spectrum=self.fft).mean()
  122. self.spectral_cenroid_mean = spectral_centroid\
  123. (self.signal_hammed, self.sample_rate).mean()
  124. self.spectral_spread = spectral_spread(centroid=self.spectral_cenroid_mean, fft_spectrum=self.fft)
  125. self.spectral_roloff_mean = spectral_roloff\
  126. (self.signal_hammed, self.sample_rate).mean()
  127. self.spectral_entropy = spectral_entropy(fft_signal=self.fft)
  128. self.energy_entropy = energy_entropy(self.signal_hammed)
  129. self.zero_crossing_rate = zero_crossing_rate(self.signal_hammed)
  130. self.temporal_centroid = temporal_centroid(self.signal_hammed)
  131. self.short_time_energy = short_time_energy(self.signal)
  132. self.root_mean_square = root_mean_square(self.signal)
  133. self.fundamental_period, self.autocorellation = autocorellation(self.signal_hammed, self.sample_rate)
  134. self.mfcc = compute_mfcc(self.signal_hammed, self.sample_rate)
  135. def extract_features(self):
  136. vector = list()
  137. vector += [self.zero_crossing_rate]
  138. vector += [self.temporal_centroid]
  139. vector += [self.energy_entropy]
  140. vector += [self.root_mean_square]
  141. vector += [self.fundamental_period]
  142. vector += [self.autocorellation]
  143. vector += [self.spectral_roloff_mean]
  144. vector += [self.spectral_spread]
  145. vector += [self.spectral_flux]
  146. vector += [self.spectral_entropy]
  147. vector += [self.spectral_cenroid_mean]
  148. mean = self.mfcc.mean(axis = 1)
  149. vector = np.append(np.array(vector), mean)
  150. return vector
  151. '''
  152. another type of multiprocessing
  153. global song
  154. def convert(path, duration=20.0, half_part_length = 0.1, offset = 0):
  155. whole_song = Sampler(path, duration=duration,offset = offset)
  156. global song
  157. song = whole_song
  158. parts = whole_song.split(half_part_length)
  159. part_arr = [np.append(parts[i-1], parts[i]) for i in xrange(1, len(parts))]
  160. #pl = Pool(4)
  161. samples = map(take_feature, part_arr)
  162. return np.array(samples)
  163. # end of process_converting
  164. '''
  165. if __name__ == "__main__":
  166. pass
  167. #path = "/media/files/musicsamples/genres/pop/pop.00002.au"
  168. #t = time.time()
  169. #df = pandas.DataFrame(convert_with_processes(path))
  170. #print time.time() - t
  171. #df.to_csv("/media/files/file.csv")