def perform_command(self): """ Perform command and return the appropriate exit code. :rtype: int """ if len(self.actual_arguments) < 1: return self.print_help() audio_file_path = self.actual_arguments[0] try: audiofile = AudioFile(audio_file_path, rconf=self.rconf, logger=self.logger) audiofile.read_properties() if self.has_option([u"-f", u"--full"]): audiofile.read_samples_from_file() self.print_generic(audiofile.__unicode__()) return self.NO_ERROR_EXIT_CODE except OSError: self.print_error(u"Cannot read file '%s'" % (audio_file_path)) self.print_error( u"Make sure the input file path is written/escaped correctly") except AudioFileProbeError: self.print_error(u"Unable to call the ffprobe executable '%s'" % (self.rconf[RuntimeConfiguration.FFPROBE_PATH])) self.print_error(u"Make sure the path to ffprobe is correct") except AudioFileUnsupportedFormatError: self.print_error(u"Cannot read properties of file '%s'" % (audio_file_path)) self.print_error( u"Make sure the input file has a format supported by ffprobe") return self.ERROR_EXIT_CODE
def load(self, path, rp=False, rs=False): af = AudioFile(gf.absolute_path(path, __file__)) if rp: af.read_properties() if rs: af.read_samples_from_file() return af
def _read_audio_data(self, file_path): """ Read audio data from file. :rtype: tuple (True, (duration, sample_rate, codec, data)) or (False, None) on exception """ try: self.log(u"Reading audio data...") # if we know the TTS outputs to PCM16 mono WAVE # with the correct sample rate, # we can read samples directly from it, # without an intermediate conversion through ffmpeg audio_file = AudioFile(file_path=file_path, file_format=self.OUTPUT_AUDIO_FORMAT, rconf=self.rconf, logger=self.logger) audio_file.read_samples_from_file() self.log( [u"Duration of '%s': %f", file_path, audio_file.audio_length]) self.log(u"Reading audio data... done") return (True, (audio_file.audio_length, audio_file.audio_sample_rate, audio_file.audio_format, audio_file.audio_samples)) except (AudioFileUnsupportedFormatError, OSError) as exc: self.log_exc( u"An unexpected error occurred while reading audio data", exc, True, None) return (False, None)
def load(self, path, rp=False, rs=False): af = AudioFile(gf.absolute_path(path, __file__)) if rp: af.read_properties() if rs: af.read_samples_from_file() return af
def perform_command(self): """ Perform command and return the appropriate exit code. :rtype: int """ if len(self.actual_arguments) < 1: return self.print_help() audio_file_path = self.actual_arguments[0] try: audiofile = AudioFile(audio_file_path, rconf=self.rconf, logger=self.logger) audiofile.read_properties() if self.has_option([u"-f", u"--full"]): audiofile.read_samples_from_file() self.print_generic(audiofile.__unicode__()) return self.NO_ERROR_EXIT_CODE except OSError: self.print_error(u"Cannot read file '%s'" % (audio_file_path)) self.print_error(u"Make sure the input file path is written/escaped correctly") except AudioFileProbeError: self.print_error(u"Unable to call the ffprobe executable '%s'" % (self.rconf[RuntimeConfiguration.FFPROBE_PATH])) self.print_error(u"Make sure the path to ffprobe is correct") except AudioFileUnsupportedFormatError: self.print_error(u"Cannot read properties of file '%s'" % (audio_file_path)) self.print_error(u"Make sure the input file has a format supported by ffprobe") return self.ERROR_EXIT_CODE
def test_load_audio_file(self): af = AudioFile(gf.absolute_path(self.AUDIO_FILE_WAVE, __file__)) af.read_samples_from_file() audiofile = AudioFileMFCC(audio_file=af) self.assertIsNotNone(audiofile.all_mfcc) self.assertAlmostEqual(audiofile.audio_length, TimeValue("53.3"), places=1) # 53.266
def test_compute_mfcc(self): try: import aeneas.cmfcc.cmfcc audio_file = AudioFile(self.AUDIO) audio_file.read_samples_from_file() mfcc_c = (aeneas.cmfcc.cmfcc.compute_from_data( audio_file.audio_samples, audio_file.audio_sample_rate, 40, 13, 512, 133.3333, 6855.4976, 0.97, 0.025, 0.010)[0]).transpose() self.assertEqual(mfcc_c.shape[0], 13) self.assertGreater(mfcc_c.shape[1], 0) except ImportError: pass
def _load_audio_file(self): """ Load audio in memory. :rtype: :class:`~aeneas.audiofile.AudioFile` """ self._step_begin(u"load audio file") audio_file = AudioFile( file_path=self.task.audio_file_path_absolute, is_mono_wave=False, rconf=self.rconf, logger=self.logger ) audio_file.read_samples_from_file() self._step_end() return audio_file
def _load_audio_file(self): """ Load audio in memory. :rtype: :class:`~aeneas.audiofile.AudioFile` """ self._step_begin(u"load audio file") audio_file = AudioFile(file_path=self.task.audio_file_path_absolute, is_mono_wave=False, rconf=self.rconf, logger=self.logger) audio_file.read_samples_from_file() self._step_end() return audio_file
def _load_audio_file(self): """ Load audio in memory. :rtype: :class:`~aeneas.audiofile.AudioFile` """ self._step_begin(u"load audio file") # NOTE file_format=None forces conversion to # PCM16 mono WAVE with default sample rate audio_file = AudioFile(file_path=self.task.audio_file_path_absolute, file_format=None, rconf=self.rconf, logger=self.logger) audio_file.read_samples_from_file() self._step_end() return audio_file
def _load_audio_file(self): """ Load audio in memory. :rtype: :class:`~aeneas.audiofile.AudioFile` """ self._step_begin(u"load audio file") # NOTE file_format=None forces conversion to # PCM16 mono WAVE with default sample rate audio_file = AudioFile( file_path=self.task.audio_file_path_absolute, file_format=None, rconf=self.rconf, logger=self.logger ) audio_file.read_samples_from_file() self._step_end() return audio_file
def test_compute_mfcc(self): try: import aeneas.cmfcc.cmfcc audio_file = AudioFile(self.AUDIO) audio_file.read_samples_from_file() mfcc_c = (aeneas.cmfcc.cmfcc.compute_from_data( audio_file.audio_samples, audio_file.audio_sample_rate, 40, 13, 512, 133.3333, 6855.4976, 0.97, 0.025, 0.010 )[0]).transpose() self.assertEqual(mfcc_c.shape[0], 13) self.assertGreater(mfcc_c.shape[1], 0) except ImportError: pass
def test_load_audio_file(self): af = AudioFile(gf.absolute_path(self.AUDIO_FILE_WAVE, __file__)) af.read_samples_from_file() audiofile = AudioFileMFCC(audio_file=af) self.assertIsNotNone(audiofile.all_mfcc) self.assertAlmostEqual(audiofile.audio_length, TimeValue("53.3"), places=1) # 53.266
def perform_command(self): """ Perform command and return the appropriate exit code. :rtype: int """ if len(self.actual_arguments) < 2: return self.print_help() input_file_path = self.actual_arguments[0] output_file_path = self.actual_arguments[1] if not self.check_input_file(input_file_path): return self.ERROR_EXIT_CODE if not self.check_output_file(output_file_path): return self.ERROR_EXIT_CODE fast = self.has_option("--fast") fragment_text = self.has_option("--text") h_zoom = gf.safe_int(self.has_option_with_value("--hzoom"), 5) label = self.has_option_with_value("--label") time_step = gf.safe_int(self.has_option_with_value("--time-step"), 0) v_zoom = gf.safe_int(self.has_option_with_value("--vzoom"), 30) labels = not self.has_option("--no-labels") begin_times = not self.has_option("--no-begin-times") end_times = not self.has_option("--no-end-times") begin_guides = not self.has_option("--no-begin-guides") end_guides = not self.has_option("--no-end-guides") try: # import or ImportError from aeneas.plotter import PlotLabelset from aeneas.plotter import PlotTimeScale from aeneas.plotter import PlotWaveform from aeneas.plotter import Plotter # create plotter object self.print_info(u"Plotting to file...") plotter = Plotter(rconf=self.rconf, logger=self.logger) # add waveform afm = AudioFile(input_file_path, rconf=self.rconf, logger=self.logger) afm.read_samples_from_file() plotter.add_waveform( PlotWaveform(afm, label=label, fast=fast, rconf=self.rconf, logger=self.logger)) # add time scale, if requested if time_step > 0: plotter.add_timescale( PlotTimeScale(afm.audio_length, time_step=time_step, rconf=self.rconf, logger=self.logger)) # add labelsets, if any for i in range(len(self.actual_arguments)): if (self.actual_arguments[i] == "-i") and (i + 1 < len(self.actual_arguments)): label_file_path = self.actual_arguments[i + 1] extension = gf.file_extension(label_file_path) if extension == "vad": labelset = self._read_syncmap_file( label_file_path, SyncMapFormat.TSV, False) ls = PlotLabelset(labelset, parameters=None, rconf=self.rconf, logger=self.logger) ls.parameters["labels"] = False ls.parameters["begin_time"] = begin_times ls.parameters["end_time"] = end_times ls.parameters["begin_guide"] = begin_guides ls.parameters["end_guide"] = end_guides plotter.add_labelset(ls) if extension in SyncMapFormat.ALLOWED_VALUES: labelset = self._read_syncmap_file( label_file_path, extension, fragment_text) ls = PlotLabelset(labelset, parameters=None, rconf=self.rconf, logger=self.logger) ls.parameters["labels"] = labels ls.parameters["begin_time"] = begin_times ls.parameters["end_time"] = end_times ls.parameters["begin_guide"] = begin_guides ls.parameters["end_guide"] = end_guides plotter.add_labelset(ls) # output to file plotter.draw_png(output_file_path, h_zoom=h_zoom, v_zoom=v_zoom) self.print_info(u"Plotting to file... done") self.print_success(u"Created file '%s'" % output_file_path) return self.NO_ERROR_EXIT_CODE except ImportError: self.print_error( u"You need to install Python module Pillow to output image to file. Run:" ) self.print_error(u"$ pip install Pillow") self.print_error(u"or, to install for all users:") self.print_error(u"$ sudo pip install Pillow") except Exception as exc: self.print_error( u"An unexpected error occurred while generating the image file:" ) self.print_error(u"%s" % exc) return self.ERROR_EXIT_CODE
def perform_command(self): """ Perform command and return the appropriate exit code. :rtype: int """ if len(self.actual_arguments) < 2: return self.print_help() input_file_path = self.actual_arguments[0] output_file_path = self.actual_arguments[1] if not self.check_input_file(input_file_path): return self.ERROR_EXIT_CODE if not self.check_output_file(output_file_path): return self.ERROR_EXIT_CODE fast = self.has_option("--fast") fragment_text = self.has_option("--text") h_zoom = gf.safe_int(self.has_option_with_value("--hzoom"), 5) label = self.has_option_with_value("--label") time_step = gf.safe_int(self.has_option_with_value("--time-step"), 0) v_zoom = gf.safe_int(self.has_option_with_value("--vzoom"), 30) labels = not self.has_option("--no-labels") begin_times = not self.has_option("--no-begin-times") end_times = not self.has_option("--no-end-times") begin_guides = not self.has_option("--no-begin-guides") end_guides = not self.has_option("--no-end-guides") try: # import or ImportError from aeneas.plotter import PlotLabelset from aeneas.plotter import PlotTimeScale from aeneas.plotter import PlotWaveform from aeneas.plotter import Plotter # create plotter object self.print_info(u"Plotting to file...") plotter = Plotter(rconf=self.rconf, logger=self.logger) # add waveform afm = AudioFile(input_file_path, rconf=self.rconf, logger=self.logger) afm.read_samples_from_file() plotter.add_waveform(PlotWaveform(afm, label=label, fast=fast, rconf=self.rconf, logger=self.logger)) # add time scale, if requested if time_step > 0: plotter.add_timescale(PlotTimeScale(afm.audio_length, time_step=time_step, rconf=self.rconf, logger=self.logger)) # add labelsets, if any for i in range(len(self.actual_arguments)): if (self.actual_arguments[i] == "-i") and (i + 1 < len(self.actual_arguments)): label_file_path = self.actual_arguments[i+1] extension = gf.file_extension(label_file_path) if extension == "vad": labelset = self._read_syncmap_file(label_file_path, SyncMapFormat.TSV, False) ls = PlotLabelset(labelset, parameters=None, rconf=self.rconf, logger=self.logger) ls.parameters["labels"] = False ls.parameters["begin_time"] = begin_times ls.parameters["end_time"] = end_times ls.parameters["begin_guide"] = begin_guides ls.parameters["end_guide"] = end_guides plotter.add_labelset(ls) if extension in SyncMapFormat.ALLOWED_VALUES: labelset = self._read_syncmap_file(label_file_path, extension, fragment_text) ls = PlotLabelset(labelset, parameters=None, rconf=self.rconf, logger=self.logger) ls.parameters["labels"] = labels ls.parameters["begin_time"] = begin_times ls.parameters["end_time"] = end_times ls.parameters["begin_guide"] = begin_guides ls.parameters["end_guide"] = end_guides plotter.add_labelset(ls) # output to file plotter.draw_png(output_file_path, h_zoom=h_zoom, v_zoom=v_zoom) self.print_info(u"Plotting to file... done") self.print_success(u"Created file '%s'" % output_file_path) return self.NO_ERROR_EXIT_CODE except ImportError: self.print_error(u"You need to install Python module Pillow to output image to file. Run:") self.print_error(u"$ pip install Pillow") self.print_error(u"or, to install for all users:") self.print_error(u"$ sudo pip install Pillow") except Exception as exc: self.print_error(u"An unexpected error occurred while generating the image file:") self.print_error(u"%s" % exc) return self.ERROR_EXIT_CODE
def _synthesize_single_subprocess(self, text, voice_code, output_file_path): """ Synthesize a single text fragment via ``subprocess``. :rtype: tuple (result, (duration, sample_rate, encoding, samples)) """ self.log(u"Synthesizing using pure Python...") try: # if the TTS engine reads text from file, # write the text into a temporary file if self.CLI_PARAMETER_TEXT_PATH in self.subprocess_arguments: self.log(u"TTS engine reads text from file") tmp_text_file_handler, tmp_text_file_path = gf.tmp_file(suffix=u".txt", root=self.rconf[RuntimeConfiguration.TMP_PATH]) self.log([u"Creating temporary text file '%s'...", tmp_text_file_path]) with io.open(tmp_text_file_path, "w", encoding="utf-8") as tmp_text_file: tmp_text_file.write(text) self.log([u"Creating temporary text file '%s'... done", tmp_text_file_path]) else: self.log(u"TTS engine reads text from stdin") tmp_text_file_handler = None tmp_text_file_path = None # copy all relevant arguments self.log(u"Creating arguments list...") arguments = [] for arg in self.subprocess_arguments: if arg == self.CLI_PARAMETER_VOICE_CODE_FUNCTION: arguments.extend(self._voice_code_to_subprocess(voice_code)) elif arg == self.CLI_PARAMETER_VOICE_CODE_STRING: arguments.append(voice_code) elif arg == self.CLI_PARAMETER_TEXT_PATH: arguments.append(tmp_text_file_path) elif arg == self.CLI_PARAMETER_WAVE_PATH: arguments.append(output_file_path) elif arg == self.CLI_PARAMETER_TEXT_STDIN: # placeholder, do not append pass elif arg == self.CLI_PARAMETER_WAVE_STDOUT: # placeholder, do not append pass else: arguments.append(arg) self.log(u"Creating arguments list... done") # actual call via subprocess self.log(u"Calling TTS engine...") self.log([u"Calling with arguments '%s'", arguments]) self.log([u"Calling with text '%s'", text]) proc = subprocess.Popen( arguments, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True ) if self.CLI_PARAMETER_TEXT_STDIN in self.subprocess_arguments: self.log(u"Passing text via stdin...") if gf.PY2: (stdoutdata, stderrdata) = proc.communicate(input=gf.safe_bytes(text)) else: (stdoutdata, stderrdata) = proc.communicate(input=text) self.log(u"Passing text via stdin... done") else: self.log(u"Passing text via file...") (stdoutdata, stderrdata) = proc.communicate() self.log(u"Passing text via file... done") proc.stdout.close() proc.stdin.close() proc.stderr.close() if self.CLI_PARAMETER_WAVE_STDOUT in self.subprocess_arguments: self.log(u"TTS engine wrote audio data to stdout") self.log([u"Writing audio data to file '%s'...", output_file_path]) with io.open(output_file_path, "wb") as output_file: output_file.write(stdoutdata) self.log([u"Writing audio data to file '%s'... done", output_file_path]) else: self.log(u"TTS engine wrote audio data to file") if tmp_text_file_path is not None: self.log([u"Delete temporary text file '%s'", tmp_text_file_path]) gf.delete_file(tmp_text_file_handler, tmp_text_file_path) self.log(u"Calling TTS ... done") except Exception as exc: self.log_exc(u"An unexpected error occurred while calling TTS engine via subprocess", exc, False, None) return (False, None) # check the file can be read if not gf.file_can_be_read(output_file_path): self.log_exc(u"Output file '%s' cannot be read" % (output_file_path), None, True, None) return (False, None) # return the duration of the output file try: # if we know the TTS outputs to PCM16 mono WAVE, # we can read samples directly from it, # without an intermediate conversion through ffmpeg audio_file = AudioFile( file_path=output_file_path, is_mono_wave=self.OUTPUT_MONO_WAVE, rconf=self.rconf, logger=self.logger ) audio_file.read_samples_from_file() self.log([u"Duration of '%s': %f", output_file_path, audio_file.audio_length]) self.log(u"Synthesizing using pure Python... done") return (True, ( audio_file.audio_length, audio_file.audio_sample_rate, audio_file.audio_format, audio_file.audio_samples )) except (AudioFileUnsupportedFormatError, OSError) as exc: self.log_exc(u"An unexpected error occurred while trying to read the sythesized audio file", exc, True, None) return (False, None)