preprocessing.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. print('preprocessing.py: dir() -> ', dir())
  2. print('preprocessing.py: __name__ -> ', __name__)
  3. import subprocess, os, glob, shutil
  4. import magic
  5. from . import settings as settings_module
  6. settings = settings_module.settings
  7. def process(uploaded_file, transcript, tmp_dir):
  8. ################## Noise Removal ##################
  9. os.mkdir(tmp_dir)
  10. filetype = magic.from_buffer(uploaded_file)
  11. input_file = tmp_dir + '/orig'
  12. format_file = tmp_dir + '/format.wav'
  13. silence_file = tmp_dir + '/silence.wav'
  14. clean_file = tmp_dir + '/clean.wav'
  15. noise_profile = tmp_dir + '/noise.prof'
  16. with open(input_file, "wb") as f:
  17. f.write(uploaded_file)
  18. assert(os.path.exists(input_file))
  19. try:
  20. subprocess.check_output(['ffmpeg', '-i', input_file, format_file])
  21. ffmpeg_silence = subprocess.check_output([
  22. 'ffmpeg', '-i', input_file,
  23. '-af', 'silencedetect=n=-30dB:d=0.5',
  24. '-f', 'null', '-'
  25. ], stderr=subprocess.STDOUT).decode('utf-8').split('\n')
  26. silence_ranges = list(zip(
  27. [line.split(" ")[4] for line in ffmpeg_silence
  28. if 'silence_start' in line],
  29. [line.split(" ")[4] for line in ffmpeg_silence
  30. if 'silence_end' in line]
  31. ))
  32. subprocess.check_output(['ffmpeg', '-i', input_file,
  33. '-af', "aselect='" + '+'.join(
  34. ['between(t,' + r[0] + ',' + r[1]+')' for r in silence_ranges]
  35. ) + "', asetpts=N/SR/TB",
  36. silence_file
  37. ])
  38. assert(os.path.exists(silence_file))
  39. subprocess.check_output([
  40. 'sox', silence_file, '-n', 'noiseprof', noise_profile
  41. ])
  42. subprocess.check_output(['chmod', '777', noise_profile])
  43. subprocess.check_output([
  44. 'sox', format_file, clean_file,
  45. 'noisered', noise_profile, '0.2'
  46. ])
  47. assert(os.path.exists(clean_file))
  48. except e:
  49. clean_file = input_file
  50. ################## Forced Alignment ##################
  51. corpus_dir = tmp_dir + '/corpus'
  52. output_dir = tmp_dir + '/output'
  53. os.mkdir(corpus_dir)
  54. os.mkdir(output_dir)
  55. subprocess.check_output([
  56. 'ffmpeg' ,
  57. '-i' , clean_file,
  58. '-acodec', 'pcm_s16le',
  59. '-ac' , '1',
  60. '-ar' , '16000',
  61. corpus_dir + '/recording.wav'
  62. ])
  63. subprocess.run(['chmod', '777', '-R', tmp_dir])
  64. with open(corpus_dir + '/recording.txt', 'w') as f:
  65. f.write(transcript)
  66. with open(tmp_dir + '/align.sh', 'w') as f:
  67. f.write("""#!/usr/bin/env bash
  68. source /opt/conda/etc/profile.d/conda.sh
  69. conda activate aligner
  70. mfa align ./corpus/ english english ./output/ --clean
  71. """)
  72. assert(os.path.exists(tmp_dir + '/align.sh'))
  73. subprocess.check_output(['chmod', '777', tmp_dir + '/align.sh'])
  74. cwd = os.getcwd()
  75. os.chdir(tmp_dir)
  76. try:
  77. # shell out so we can `source`
  78. subprocess.check_output(['./align.sh'], stderr=subprocess.STDOUT)
  79. except subprocess.CalledProcessError as e:
  80. print("CalledProcessError")
  81. print(e)
  82. print(str(e.output, 'utf-8'))
  83. except Exception as e:
  84. print("Error")
  85. print(e)
  86. os.chdir(cwd)
  87. ################## Phonetic Processing ##################
  88. for recording, grid in zip(
  89. glob.glob(corpus_dir + '/*.wav'),
  90. glob.glob(output_dir + '/*.TextGrid')
  91. ):
  92. praat_output = subprocess.check_output([
  93. './textgrid-formants.praat', recording, grid
  94. ]).decode('utf-8')
  95. with open(grid.replace('.TextGrid', '.tsv'), 'w') as f:
  96. f.write(praat_output)
  97. shutil.rmtree(tmp_dir)
  98. return praat_output