diff --git a/README.md b/README.md index 837cb35d..310edc10 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ **aeneas** is a Python/C library and a set of tools to automagically synchronize audio and text (aka forced alignment). -* Version: 1.7.2 -* Date: 2017-03-03 +* Version: 1.7.3 +* Date: 2017-03-15 * Developed by: [ReadBeyond](http://www.readbeyond.it/) * Lead Developer: [Alberto Pettarin](http://www.albertopettarin.it/) * License: the GNU Affero General Public License Version 3 (AGPL v3) @@ -316,7 +316,7 @@ No copy rights were harmed in the making of this project. * **April 2016**: the Fruch Foundation kindly sponsored the development and documentation of v1.5.0 -* **December 2016**: the [Centro Internazionale Del Libro Parlato "Adriano Sernagiotto"](http://www.libroparlato.org/) (Feltre, Italy) partially sponsored the development of v1.7.0, v1.7.1, and v1.7.2 +* **December 2016**: the [Centro Internazionale Del Libro Parlato "Adriano Sernagiotto"](http://www.libroparlato.org/) (Feltre, Italy) partially sponsored the development of the v1.7 series ### Supporting diff --git a/README.rst b/README.rst index 94b74082..21268bc5 100644 --- a/README.rst +++ b/README.rst @@ -4,8 +4,8 @@ aeneas **aeneas** is a Python/C library and a set of tools to automagically synchronize audio and text (aka forced alignment). -- Version: 1.7.2 -- Date: 2017-03-03 +- Version: 1.7.3 +- Date: 2017-03-15 - Developed by: `ReadBeyond `__ - Lead Developer: `Alberto Pettarin `__ - License: the GNU Affero General Public License Version 3 (AGPL v3) @@ -359,8 +359,7 @@ Sponsors - **December 2016**: the `Centro Internazionale Del Libro Parlato "Adriano Sernagiotto" `__ (Feltre, - Italy) partially sponsored the development of v1.7.0, v1.7.1, and - v1.7.2 + Italy) partially sponsored the development of the v1.7 series Supporting ~~~~~~~~~~ diff --git a/VERSION b/VERSION index f8a696c8..661e7aea 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.7.2 +1.7.3 diff --git a/aeneas/__init__.py b/aeneas/__init__.py index 624facf0..5739fef0 100644 --- a/aeneas/__init__.py +++ b/aeneas/__init__.py @@ -35,4 +35,4 @@ """ __license__ = "GNU AGPL v3" __status__ = "Production" -__version__ = "1.7.2" +__version__ = "1.7.3" diff --git a/aeneas/audiofile.py b/aeneas/audiofile.py index 3cd804f6..2f09ec32 100644 --- a/aeneas/audiofile.py +++ b/aeneas/audiofile.py @@ -209,9 +209,12 @@ def __init__(self, file_path=None, file_format=None, rconf=None, logger=None): self.__samples = None def __unicode__(self): + fmt = self.file_format + if isinstance(fmt, tuple): + fmt = u"%s %d %d" % fmt msg = [ u"File path: %s" % self.file_path, - u"File format: %s" % self.file_format, + u"File format: %s" % fmt, u"File size (bytes): %s" % gf.safe_int(self.file_size), u"Audio length (s): %s" % gf.safe_float(self.audio_length), u"Audio format: %s" % self.audio_format, @@ -644,4 +647,7 @@ def _update_length(self): This function fails silently if one of the two is ``None``. """ if (self.audio_sample_rate is not None) and (self.__samples is not None): - self.audio_length = TimeValue(self.__samples_length / self.audio_sample_rate) + # NOTE computing TimeValue (... / ...) yields wrong results, + # see issue #168 + # self.audio_length = TimeValue(self.__samples_length / self.audio_sample_rate) + self.audio_length = TimeValue(self.__samples_length) / TimeValue(self.audio_sample_rate) diff --git a/aeneas/cdtw/cdtw_setup.py b/aeneas/cdtw/cdtw_setup.py index 06e5b0c7..061bb9ce 100644 --- a/aeneas/cdtw/cdtw_setup.py +++ b/aeneas/cdtw/cdtw_setup.py @@ -49,7 +49,7 @@ setup( name="cdtw", - version="1.7.2", + version="1.7.3", description="Python C Extension for computing the DTW as fast as your bare metal allows.", ext_modules=[CMODULE], include_dirs=[misc_util.get_numpy_include_dirs()] diff --git a/aeneas/cew/cew_setup.py b/aeneas/cew/cew_setup.py index 00e70ae1..1f044a49 100644 --- a/aeneas/cew/cew_setup.py +++ b/aeneas/cew/cew_setup.py @@ -47,7 +47,7 @@ setup( name="cew", - version="1.7.2", + version="1.7.3", description="Python C Extension for synthesizing text with eSpeak.", ext_modules=[CMODULE] ) diff --git a/aeneas/cfw/cfw_setup.py b/aeneas/cfw/cfw_setup.py index 5fd91f5f..9a51d7fc 100644 --- a/aeneas/cfw/cfw_setup.py +++ b/aeneas/cfw/cfw_setup.py @@ -54,7 +54,7 @@ setup( name="cfw", - version="1.7.2", + version="1.7.3", description="Python C Extension for synthesizing text with Festival.", ext_modules=[CMODULE] ) diff --git a/aeneas/cmfcc/cmfcc_setup.py b/aeneas/cmfcc/cmfcc_setup.py index e159d8e9..2f903848 100644 --- a/aeneas/cmfcc/cmfcc_setup.py +++ b/aeneas/cmfcc/cmfcc_setup.py @@ -50,7 +50,7 @@ setup( name="cmfcc", - version="1.7.2", + version="1.7.3", description="Python C Extension for computing the MFCCs as fast as your bare metal allows.", ext_modules=[CMODULE], include_dirs=[misc_util.get_numpy_include_dirs()] diff --git a/aeneas/cwave/cwave_setup.py b/aeneas/cwave/cwave_setup.py index 0d3a0fed..b208f2a5 100644 --- a/aeneas/cwave/cwave_setup.py +++ b/aeneas/cwave/cwave_setup.py @@ -49,7 +49,7 @@ setup( name="cwave", - version="1.7.2", + version="1.7.3", description="Python C Extension for for reading WAVE files.", ext_modules=[CMODULE], include_dirs=[misc_util.get_numpy_include_dirs()] diff --git a/aeneas/tests/long_test_task_parameters.py b/aeneas/tests/long_test_task_parameters.py index 4cb3e77e..c6ee0ffc 100644 --- a/aeneas/tests/long_test_task_parameters.py +++ b/aeneas/tests/long_test_task_parameters.py @@ -354,6 +354,14 @@ def test_exec_os_task_file_levels_123(self): ("out", "sonnet.json") ], 0) + def test_exec_exact_5600_16000_munparsed_issue_168(self): + self.execute([ + ("in", "../tests/res/audioformats/exact.5600.16000.wav"), + ("in", "../tests/res/inputtext/exact.5600.16000.munparsed.xhtml"), + ("", "task_language=eng|is_text_type=munparsed|os_task_file_format=json|is_text_munparsed_l1_id_regex=p[0-9]+|is_text_munparsed_l2_id_regex=p[0-9]+s[0-9]+|is_text_munparsed_l3_id_regex=p[0-9]+s[0-9]+w[0-9]+"), + ("out", "sonnet.json") + ], 0) + if __name__ == "__main__": unittest.main() diff --git a/aeneas/tests/res/audioformats/exact.5600.16000.wav b/aeneas/tests/res/audioformats/exact.5600.16000.wav new file mode 100644 index 00000000..73213c7f Binary files /dev/null and b/aeneas/tests/res/audioformats/exact.5600.16000.wav differ diff --git a/aeneas/tests/res/inputtext/exact.5600.16000.munparsed.xhtml b/aeneas/tests/res/inputtext/exact.5600.16000.munparsed.xhtml new file mode 100644 index 00000000..4b8512af --- /dev/null +++ b/aeneas/tests/res/inputtext/exact.5600.16000.munparsed.xhtml @@ -0,0 +1,32 @@ + + + + + + + Sonnet I + + +
+

+ + 1 + From + fairest + creatures + we + desire + increase, + That + thereby + beauty’s + rose + might + never + die, + +

+
+ + + diff --git a/aeneas/tests/test_audiofile.py b/aeneas/tests/test_audiofile.py index a81d6ca3..a2c48b63 100644 --- a/aeneas/tests/test_audiofile.py +++ b/aeneas/tests/test_audiofile.py @@ -36,6 +36,7 @@ class TestAudioFile(unittest.TestCase): AUDIO_FILE_WAVE = "res/audioformats/mono.16000.wav" AUDIO_FILE_EMPTY = "res/audioformats/p001.empty" AUDIO_FILE_NOT_WAVE = "res/audioformats/p001.mp3" + AUDIO_FILE_EXACT = "res/audioformats/exact.5600.16000.wav" NOT_EXISTING_FILE = "res/audioformats/x/y/z/not_existing.wav" FILES = [ { @@ -163,6 +164,11 @@ def test_length(self): audiofile.clear_data() self.assertAlmostEqual(audiofile.audio_length, TimeValue("53.3"), places=1) # 53.266 + def test_length_exact(self): + audiofile = self.load(self.AUDIO_FILE_EXACT, rs=True) + audiofile.clear_data() + self.assertAlmostEqual(audiofile.audio_length, TimeValue("5.600"), places=3) # 5.600 + def test_add_samples_file(self): audiofile = self.load(self.AUDIO_FILE_WAVE, rs=True) data = audiofile.audio_samples diff --git a/aeneas/tests/tool_test_read_audio.py b/aeneas/tests/tool_test_read_audio.py index 1e784284..f05b5e12 100644 --- a/aeneas/tests/tool_test_read_audio.py +++ b/aeneas/tests/tool_test_read_audio.py @@ -56,11 +56,23 @@ def test_read_audio(self): ("in", "../tools/res/audio.wav") ], 0) + def test_read_audio_full(self): + self.execute([ + ("in", "../tools/res/audio.wav"), + ("", "-f") + ], 0) + def test_read_audio_mp3(self): self.execute([ ("in", "../tools/res/audio.mp3") ], 0) + def test_read_audio_mp3_full(self): + self.execute([ + ("in", "../tools/res/audio.mp3"), + ("", "-f") + ], 0) + def test_read_audio_path(self): path = os.path.expanduser("~") path = os.path.join(path, ".bin/myffprobe") diff --git a/aeneas/tools/read_audio.py b/aeneas/tools/read_audio.py index 690f83e0..b8fbd5cd 100644 --- a/aeneas/tools/read_audio.py +++ b/aeneas/tools/read_audio.py @@ -51,6 +51,7 @@ class ReadAudioCLI(AbstractCLIProgram): (u"AUDIO_FILE", True) ], "options": [ + u"-f, --full : load samples from file, possibly converting to WAVE" ], "parameters": [ ], @@ -72,6 +73,8 @@ def perform_command(self): 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: diff --git a/aeneas_check_setup.py b/aeneas_check_setup.py index 9525473a..26e6b62a 100644 --- a/aeneas_check_setup.py +++ b/aeneas_check_setup.py @@ -44,7 +44,7 @@ """ __license__ = "GNU AGPL 3" __status__ = "Production" -__version__ = "1.7.2" +__version__ = "1.7.3" ANSI_ERROR = u"\033[91m" ANSI_OK = u"\033[92m" diff --git a/bin/aeneas_check_setup.py b/bin/aeneas_check_setup.py index 9525473a..26e6b62a 100755 --- a/bin/aeneas_check_setup.py +++ b/bin/aeneas_check_setup.py @@ -44,7 +44,7 @@ """ __license__ = "GNU AGPL 3" __status__ = "Production" -__version__ = "1.7.2" +__version__ = "1.7.3" ANSI_ERROR = u"\033[91m" ANSI_OK = u"\033[92m" diff --git a/bin/aeneas_convert_syncmap.py b/bin/aeneas_convert_syncmap.py index c1eebd94..20a7c376 100755 --- a/bin/aeneas_convert_syncmap.py +++ b/bin/aeneas_convert_syncmap.py @@ -40,7 +40,7 @@ """ __license__ = "GNU AGPL 3" __status__ = "Production" -__version__ = "1.7.2" +__version__ = "1.7.3" def main(): diff --git a/bin/aeneas_download.py b/bin/aeneas_download.py index 44ebe480..188b3350 100755 --- a/bin/aeneas_download.py +++ b/bin/aeneas_download.py @@ -40,7 +40,7 @@ """ __license__ = "GNU AGPL 3" __status__ = "Production" -__version__ = "1.7.2" +__version__ = "1.7.3" def main(): diff --git a/bin/aeneas_execute_job.py b/bin/aeneas_execute_job.py index c848915b..75bd45c5 100755 --- a/bin/aeneas_execute_job.py +++ b/bin/aeneas_execute_job.py @@ -42,7 +42,7 @@ """ __license__ = "GNU AGPL 3" __status__ = "Production" -__version__ = "1.7.2" +__version__ = "1.7.3" def main(): diff --git a/bin/aeneas_execute_task.py b/bin/aeneas_execute_task.py index 97b867fd..4a0a9073 100755 --- a/bin/aeneas_execute_task.py +++ b/bin/aeneas_execute_task.py @@ -41,7 +41,7 @@ """ __license__ = "GNU AGPL 3" __status__ = "Production" -__version__ = "1.7.2" +__version__ = "1.7.3" def main(): diff --git a/bin/aeneas_plot_waveform.py b/bin/aeneas_plot_waveform.py index 5f78831d..0958c136 100755 --- a/bin/aeneas_plot_waveform.py +++ b/bin/aeneas_plot_waveform.py @@ -40,7 +40,7 @@ """ __license__ = "GNU AGPL 3" __status__ = "Production" -__version__ = "1.7.2" +__version__ = "1.7.3" def main(): diff --git a/bin/aeneas_synthesize_text.py b/bin/aeneas_synthesize_text.py index 86dbb2d7..df7eb0bf 100755 --- a/bin/aeneas_synthesize_text.py +++ b/bin/aeneas_synthesize_text.py @@ -41,7 +41,7 @@ """ __license__ = "GNU AGPL 3" __status__ = "Production" -__version__ = "1.7.2" +__version__ = "1.7.3" def main(): diff --git a/bin/aeneas_validate.py b/bin/aeneas_validate.py index aec78b4a..239989aa 100755 --- a/bin/aeneas_validate.py +++ b/bin/aeneas_validate.py @@ -47,7 +47,7 @@ """ __license__ = "GNU AGPL 3" __status__ = "Production" -__version__ = "1.7.2" +__version__ = "1.7.3" def main(): diff --git a/check_dependencies.py b/check_dependencies.py index 9525473a..26e6b62a 100644 --- a/check_dependencies.py +++ b/check_dependencies.py @@ -44,7 +44,7 @@ """ __license__ = "GNU AGPL 3" __status__ = "Production" -__version__ = "1.7.2" +__version__ = "1.7.3" ANSI_ERROR = u"\033[91m" ANSI_OK = u"\033[92m" diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index 63f2d022..ee5ec2fd 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -1,6 +1,12 @@ Changelog ========= +v1.7.3 (2017-03-15) +------------------- + +#. Fixed bug #168 and added a regression test for it +#. Added option ``-f, --full`` to ``aeneas.tools.read_audio`` and tests for it + v1.7.2 (2017-03-03) ------------------- diff --git a/docs/source/conf.py b/docs/source/conf.py index 972c72b8..17d9a557 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -60,7 +60,7 @@ # The short X.Y version. version = '1.7' # The full version, including alpha/beta/rc tags. -release = '1.7.2' +release = '1.7.3' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/install_dependencies.sh b/install_dependencies.sh index 142987a5..c4d8ed60 100644 --- a/install_dependencies.sh +++ b/install_dependencies.sh @@ -7,7 +7,7 @@ # Copyright 2015-2017, Alberto Pettarin (www.albertopettarin.it) # """ # __license__ = "GNU AGPL 3" -# __version__ = "1.7.2" +# __version__ = "1.7.3" # __email__ = "aeneas@readbeyond.it" # __status__ = "Production" diff --git a/pyinstaller-aeneas-cli.py b/pyinstaller-aeneas-cli.py index a46ac986..59d799ec 100755 --- a/pyinstaller-aeneas-cli.py +++ b/pyinstaller-aeneas-cli.py @@ -42,7 +42,7 @@ """ __license__ = "GNU AGPL 3" __status__ = "Production" -__version__ = "1.7.2" +__version__ = "1.7.3" def main(): diff --git a/pyinstaller-onedir.spec b/pyinstaller-onedir.spec index c971f881..d86af5bd 100644 --- a/pyinstaller-onedir.spec +++ b/pyinstaller-onedir.spec @@ -9,7 +9,7 @@ #""" #__license__ = "GNU AGPL 3" #__status__ = "Production" -#__version__ = "1.7.2" +#__version__ = "1.7.3" datas = [ # required diff --git a/pyinstaller-onefile.spec b/pyinstaller-onefile.spec index c245945a..3658a374 100644 --- a/pyinstaller-onefile.spec +++ b/pyinstaller-onefile.spec @@ -9,7 +9,7 @@ #""" #__license__ = "GNU AGPL 3" #__status__ = "Production" -#__version__ = "1.7.2" +#__version__ = "1.7.3" datas = [ # required diff --git a/run_all_unit_tests.py b/run_all_unit_tests.py index b8b4a240..e8888e2e 100644 --- a/run_all_unit_tests.py +++ b/run_all_unit_tests.py @@ -41,7 +41,7 @@ """ __license__ = "GNU AGPL 3" __status__ = "Production" -__version__ = "1.7.2" +__version__ = "1.7.3" TEST_DIRECTORY = "aeneas/tests" MAP = { diff --git a/setup.py b/setup.py index 01399fd2..41a149a8 100644 --- a/setup.py +++ b/setup.py @@ -57,7 +57,7 @@ """ __license__ = "GNU AGPL 3" __status__ = "Production" -__version__ = "1.7.2" +__version__ = "1.7.3" ############################################################################## diff --git a/setupmeta.py b/setupmeta.py index 92d5c969..593c9b92 100644 --- a/setupmeta.py +++ b/setupmeta.py @@ -36,7 +36,7 @@ """ __license__ = "GNU AGPL 3" __status__ = "Production" -__version__ = "1.7.2" +__version__ = "1.7.3" ############################################################################## @@ -47,7 +47,7 @@ # package version # NOTE: generate a new one for each PyPI upload, otherwise it will fail -PKG_VERSION = "1.7.2.0" +PKG_VERSION = "1.7.3.0" # required packages to install # NOTE: always use exact version numbers