file_utils.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. from cmath import e
  2. from genericpath import isdir
  3. import os
  4. from re import A
  5. import wave
  6. import logging
  7. from pydub import AudioSegment
  8. import matplotlib.pyplot as plt
  9. import numpy as np
  10. import pandas as pd
  11. import librosa.display
  12. import collections
  13. # Configure logging
  14. logging.basicConfig(level=logging.INFO)
  15. logger = logging.getLogger(__name__)
  16. trainer_classes = {}
  17. def ensure_directory_exists(directory):
  18. if not os.path.exists(directory):
  19. os.makedirs(directory)
  20. def list_files_in_directory(directory, extension=None, deep=0):
  21. if not os.path.exists(directory):
  22. raise FileNotFoundError(f"Directory {directory} does not exist.")
  23. #isarray = type(extension).__name__ in ('list', 'tuple', 'dict')
  24. isarray = isinstance(extension, (list, tuple, dict))
  25. files = []
  26. for file in os.listdir(directory):
  27. if os.path.isdir(directory+file+"/") and deep>0 and file != "processed":
  28. dfs = list_files_in_directory(directory+file+"/", extension=extension, deep=deep-1)
  29. for df in dfs:
  30. files.append(df)
  31. continue
  32. if extension:
  33. if isarray:
  34. found=False
  35. for e in extension:
  36. if file.endswith(e):
  37. found=True
  38. if found==False:
  39. continue
  40. elif not file.endswith(extension):
  41. continue
  42. files.append(directory+file)
  43. return files
  44. def list_directories_in_directory(directory):
  45. if not os.path.exists(directory):
  46. raise FileNotFoundError(f"Directory {directory} does not exist.")
  47. directories = [d for d in os.listdir(directory) if os.path.isdir(os.path.join(directory, d))]
  48. return directories
  49. def save_file(directory, filename, data):
  50. ensure_directory_exists(directory)
  51. file_path = os.path.join(directory, filename)
  52. with open(file_path, 'wb') as file:
  53. file.write(data)
  54. def delete_file(file_path):
  55. if os.path.exists(file_path):
  56. os.remove(file_path)
  57. def get_file_metadata(file_path):
  58. if not os.path.exists(file_path):
  59. raise FileNotFoundError(f"File {file_path} does not exist.")
  60. try:
  61. with wave.open(file_path, 'rb') as wf:
  62. frames = wf.getnframes()
  63. rate = wf.getframerate()
  64. length = frames / float(rate)
  65. size = os.path.getsize(file_path) / 1024 # size in KB
  66. return round(length, 2), round(size, 2)
  67. except wave.Error as e:
  68. logger.error(f"Error processing WAV file {file_path}: {e}")
  69. raise ValueError(f"Error processing WAV file: {e}")
  70. def is_valid_wav(file_path):
  71. try:
  72. with wave.open(file_path, 'rb') as wf:
  73. return True
  74. except wave.Error:
  75. return False
  76. def get_file_size(file_path):
  77. if not os.path.exists(file_path):
  78. raise FileNotFoundError(f"File {file_path} does not exist.")
  79. size = os.path.getsize(file_path)
  80. return get_Size_String(size)
  81. def get_Size_String(value):
  82. ext = ["Byte","KB","MB","GB","TB"]
  83. i = 0
  84. while value > 1024:
  85. value /= 1024
  86. i += 1
  87. return f"{value:.2f} {ext[i]}"
  88. def update_training_time(model_name, additional_time):
  89. training_time_path = f"./model/hotword/{model_name}/training_time.txt"
  90. ensure_directory_exists(os.path.dirname(training_time_path))
  91. if os.path.exists(training_time_path):
  92. with open(training_time_path, "r") as f:
  93. total_time = int(f.read().strip())
  94. else:
  95. total_time = 0
  96. total_time += additional_time
  97. with open(training_time_path, "w") as f:
  98. f.write(str(total_time))
  99. def get_training_time(model_name):
  100. training_time_path = f"./model/hotword/{model_name}/training_time.txt"
  101. if os.path.exists(training_time_path):
  102. with open(training_time_path, "r") as f:
  103. return int(f.read().strip())
  104. return 0
  105. def resample_training_data(training_directory, background_directory=None):
  106. print(" training_directory: "+training_directory)
  107. print(" background_directory: "+background_directory)
  108. input_dir = os.path.join(training_directory)
  109. output_dir = os.path.join(input_dir, 'processed/')
  110. print(" input_dir: "+input_dir)
  111. print(" output_dir: "+output_dir)
  112. ensure_directory_exists(output_dir)
  113. hotword_files = list_files_in_directory(input_dir, extension='.wav')
  114. if background_directory:
  115. background_files = list_files_in_directory(background_directory, extension='.wav')
  116. else:
  117. background_files = []
  118. for hotword_file in hotword_files:
  119. hotword_audio = AudioSegment.from_wav(hotword_file)
  120. fname1=os.path.splitext(os.path.basename(hotword_file))[0]+".wav"
  121. hotword_audio.export(os.path.join(output_dir, fname1), format='wav') # Save raw hotword
  122. for background_file in background_files:
  123. fname1=os.path.splitext(os.path.basename(hotword_file))[0]
  124. fname2=os.path.splitext(os.path.basename(background_file))[0]
  125. mixed_filename = f"{fname1}_{fname2}.wav"
  126. ofile = os.path.join(output_dir, mixed_filename)
  127. if os.path.exists(ofile)==False:
  128. background_audio = AudioSegment.from_wav(background_file)
  129. mixed_audio = hotword_audio.overlay(background_audio, position=0)
  130. print(f" Mixed Filename: {mixed_filename}")
  131. mixed_audio.export(ofile, format='wav')
  132. def preprocessing_training_data(model_dir,data_dir, sc_data_dir, fail_data_dir):
  133. import librosa
  134. data_path_dict = {
  135. 0: list_files_in_directory(fail_data_dir, extension=['.wav','.mp3','.m4a'], deep=3),
  136. 1: list_files_in_directory(data_dir, extension=['.wav','.mp3','.m4a'], deep=3),
  137. 2: list_files_in_directory(sc_data_dir, extension=['.wav','.mp3','.m4a'], deep=3)
  138. }
  139. #walley_sample = "training/background/rec04.wav"
  140. #data, sample_rate = librosa.load(walley_sample)
  141. #plt.title("Wave Form")
  142. #librosa.display.waveplot(data, sr=sample_rate)
  143. #plt.show()
  144. #mfccs = librosa.feature.mfcc(y=data, sr=sample_rate, n_mfcc=40)
  145. #print("Shape of mfcc:", mfccs.shape)
  146. #plt.title("MFCC")
  147. #librosa.display.specshow(mfccs, sr=sample_rate, x_axis='time')
  148. #plt.show()
  149. all_data = []
  150. print(" Load training data")
  151. for class_label, list_of_files in data_path_dict.items():
  152. for single_file in list_of_files:
  153. try:
  154. if single_file[0:2]=="./":
  155. single_file = single_file[2:]
  156. print(f" {class_label}: {single_file}")
  157. audio, sample_rate = librosa.load(single_file)
  158. print(f" Sample-Rate: {sample_rate}")
  159. mfcc = librosa.feature.mfcc(y=audio, sr=sample_rate, n_mfcc=40)
  160. print(f" mfcc: {mfcc}")
  161. mfcc_processed = np.mean(mfcc.T, axis=0)
  162. print(f" mfcc_processed: mfcc_processed")
  163. all_data.append([mfcc_processed, class_label])
  164. print(" Next")
  165. except Exception as e:
  166. print(f" Exception: {str(e)}")
  167. print(f" Info: Succesfully Preprocessed Class Label {class_label}")
  168. df = pd.DataFrame(all_data, columns=["feature", "class_label"])
  169. df.to_pickle(model_dir+"/audio_data.csv")