Пример #1
0
    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
Пример #2
0
 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
Пример #3
0
    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)
Пример #4
0
 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
Пример #5
0
    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
Пример #6
0
 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
Пример #7
0
 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
Пример #8
0
    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
Пример #9
0
    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
Пример #10
0
    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
Пример #11
0
    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
Пример #12
0
 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
Пример #13
0
 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
Пример #14
0
    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
Пример #15
0
    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
Пример #16
0
    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)