Skip to content

Commit

Permalink
Merge pull request #153 from readbeyond/devel
Browse files Browse the repository at this point in the history
aeneas v1.5.1
  • Loading branch information
readbeyond authored Dec 21, 2016
2 parents d33b92a + 702eb2b commit d5d6583
Show file tree
Hide file tree
Showing 37 changed files with 109 additions and 64 deletions.
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# aeneas
# aeneas

**aeneas** is a Python/C library and a set of tools to automagically synchronize audio and text (aka forced alignment).

* Version: 1.7.0
* Date: 2016-12-07
* Version: 1.7.1
* Date: 2016-12-21
* 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)
* Contact: [[email protected]](mailto:[email protected])
* Quick Links: [Home](http://www.readbeyond.it/aeneas/) - [GitHub](https://github.com/readbeyond/aeneas/) - [PyPI](https://pypi.python.org/pypi/aeneas/) - [Docs](http://www.readbeyond.it/aeneas/docs/) - [Tutorial](http://www.readbeyond.it/aeneas/docs/clitutorial.html) - [Benchmark](https://readbeyond.github.io/aeneas-benchmark/) - [Mailing List](https://groups.google.com/d/forum/aeneas-forced-alignment) - [Web App](http://aeneasweb.org)


## Goal

**aeneas** automatically generates a **synchronization map**
Expand Down Expand Up @@ -109,7 +109,7 @@ The generic OS-independent procedure is simple:
`espeak`, `ffmpeg`, `ffprobe`, `pip`, and `python`

3. First install `numpy` with `pip` and then `aeneas` (this order is important):

```bash
pip install numpy
pip install aeneas
Expand Down Expand Up @@ -185,7 +185,7 @@ The generic OS-independent procedure is simple:
```bash
python -m aeneas.tools.execute_job job.zip output_directory
```
File `job.zip` should contain a `config.txt` or `config.xml`
configuration file, providing **aeneas**
with all the information needed to parse the input assets
Expand Down Expand Up @@ -251,7 +251,7 @@ which explains how to use the built-in command line tools.
* Extensive test suite including 1,200+ unit/integration/performance tests, that run and must pass before each release
## Limitations and Missing Features
## Limitations and Missing Features
* Audio should match the text: large portions of spurious text or audio might produce a wrong sync map
* Audio is assumed to be spoken: not suitable for song captioning, YMMV for CC applications
Expand Down Expand Up @@ -304,7 +304,7 @@ No copy rights were harmed in the making of this project.
## Supporting and Contributing
### Sponsors
### Sponsors
* **July 2015**: [Michele Gianella](https://plus.google.com/+michelegianella/about) generously supported the development of the boundary adjustment code (v1.0.4)
Expand Down
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.0
- Date: 2016-12-07
- Version: 1.7.1
- Date: 2016-12-21
- 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)
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.7.0
1.7.1
2 changes: 1 addition & 1 deletion aeneas/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@
"""
__license__ = "GNU AGPL v3"
__status__ = "Production"
__version__ = "1.7.0"
__version__ = "1.7.1"
2 changes: 1 addition & 1 deletion aeneas/cdtw/cdtw_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@

setup(
name="cdtw",
version="1.7.0",
version="1.7.1",
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()]
Expand Down
2 changes: 1 addition & 1 deletion aeneas/cew/cew_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@

setup(
name="cew",
version="1.7.0",
version="1.7.1",
description="Python C Extension for synthesizing text with eSpeak.",
ext_modules=[CMODULE]
)
Expand Down
2 changes: 1 addition & 1 deletion aeneas/cfw/cfw_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@

setup(
name="cfw",
version="1.7.0",
version="1.7.1",
description="Python C Extension for synthesizing text with Festival.",
ext_modules=[CMODULE]
)
Expand Down
2 changes: 1 addition & 1 deletion aeneas/cmfcc/cmfcc_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@

setup(
name="cmfcc",
version="1.7.0",
version="1.7.1",
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()]
Expand Down
2 changes: 1 addition & 1 deletion aeneas/cwave/cwave_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@

setup(
name="cwave",
version="1.7.0",
version="1.7.1",
description="Python C Extension for for reading WAVE files.",
ext_modules=[CMODULE],
include_dirs=[misc_util.get_numpy_include_dirs()]
Expand Down
15 changes: 12 additions & 3 deletions aeneas/globalfunctions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1005,18 +1005,27 @@ def delete_directory(path):
pass


def delete_file(handler, path):
def close_file_handler(handler):
"""
Safely delete file.
Safely close the given file handler.
:param object handler: the file handler (as returned by tempfile)
:param string path: the file path
"""
if handler is not None:
try:
os.close(handler)
except:
pass


def delete_file(handler, path):
"""
Safely delete file.
:param object handler: the file handler (as returned by tempfile)
:param string path: the file path
"""
close_file_handler(handler)
if path is not None:
try:
os.remove(path)
Expand Down
8 changes: 8 additions & 0 deletions aeneas/tests/test_globalfunctions.py
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,14 @@ def test_delete_directory_not_existing(self):
gf.delete_directory(orig)
self.assertFalse(gf.directory_exists(orig))

def test_close_file_handler(self):
handler, path = gf.tmp_file()
self.assertTrue(gf.file_exists(path))
gf.close_file_handler(handler)
self.assertTrue(gf.file_exists(path))
gf.delete_file(handler, path)
self.assertFalse(gf.file_exists(path))

def test_delete_file_existing(self):
handler, path = gf.tmp_file()
self.assertTrue(gf.file_exists(path))
Expand Down
1 change: 1 addition & 0 deletions aeneas/tools/abstract_cli_program.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ def run(self, arguments, show_help=True):

# create logger
self.logger = Logger(tee=self.verbose, tee_show_datetime=self.very_verbose)
self.log([u"Running aeneas %s", aeneas_version])
self.log([u"Formal arguments: %s", self.formal_arguments])
self.log([u"Actual arguments: %s", self.actual_arguments])
self.log([u"Runtime configuration: '%s'", self.rconf.config_string])
Expand Down
6 changes: 3 additions & 3 deletions aeneas/tools/execute_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class ExecuteTaskCLI(AbstractCLIProgram):
u"description": u"input: plain text, output: TSV, tts engine: Festival",
u"audio": AUDIO_FILE,
u"text": gf.relative_path("res/plain.txt", __file__),
u"config": u"task_language=eng|is_text_type=plain|os_task_file_format=tsv",
u"config": u"task_language=eng-USA|is_text_type=plain|os_task_file_format=tsv",
u"syncmap": "output/sonnet.festival.tsv",
u"options": u"-r=\"tts=festival\"",
u"show": False
Expand Down Expand Up @@ -205,7 +205,7 @@ class ExecuteTaskCLI(AbstractCLIProgram):
u"description": u"input: multilevel plain text (mplain), different TTS engines, output: JSON",
u"audio": AUDIO_FILE,
u"text": gf.relative_path("res/mplain.txt", __file__),
u"config": u"task_language=eng|is_text_type=mplain|os_task_file_format=json",
u"config": u"task_language=eng-USA|is_text_type=mplain|os_task_file_format=json",
u"syncmap": "output/sonnet.mplain.json",
u"options": u"-r=\"tts_l1=festival|tts_l2=festival|tts_l3=espeak\"",
u"show": False
Expand Down Expand Up @@ -376,7 +376,7 @@ class ExecuteTaskCLI(AbstractCLIProgram):
u"description": u"input: single word granularity plain text, output: AUD, tts engine: Festival, TTS cache on",
u"audio": AUDIO_FILE,
u"text": gf.relative_path("res/words.txt", __file__),
u"config": u"task_language=eng|is_text_type=plain|os_task_file_format=aud",
u"config": u"task_language=eng-USA|is_text_type=plain|os_task_file_format=aud",
u"syncmap": "output/sonnet.words.aud",
u"options": u"-r=\"tts=festival|tts_cache=True\"",
u"show": False
Expand Down
46 changes: 28 additions & 18 deletions aeneas/ttswrappers/basettswrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ def _synthesize_single_python_helper(self, text, voice_code, output_file_path=No
return the audio data at the end of the function call;
if ``False``, just return ``(True, None)`` in case of success.
:rtype: tuple (result, (duration, sample_rate, encoding, data)) or (result, None)
:rtype: tuple (result, (duration, sample_rate, codec, data)) or (result, None)
"""
raise NotImplementedError(u"This function must be implemented in concrete subclasses supporting Python call")

Expand All @@ -489,7 +489,7 @@ def _synthesize_single_c_extension_helper(self, text, voice_code, output_file_pa
If ``output_file_path`` is ``None``,
the audio data will not persist to file at the end of the method.
:rtype: tuple (result, (duration, sample_rate, encoding, data))
:rtype: tuple (result, (duration, sample_rate, codec, data))
"""
raise NotImplementedError(u"This function might be implemented in concrete subclasses supporting C extension call")

Expand Down Expand Up @@ -521,12 +521,12 @@ def _synthesize_single_subprocess_helper(self, text, voice_code, output_file_pat
return the audio data at the end of the function call;
if ``False``, just return ``(True, None)`` in case of success.
:rtype: tuple (result, (duration, sample_rate, encoding, data)) or (result, None)
:rtype: tuple (result, (duration, sample_rate, codec, data)) or (result, None)
"""
# return zero if text is the empty string
if len(text) == 0:
#
# NOTE sample_rate, encoding, data do not matter
# NOTE sample_rate, codec, data do not matter
# if the duration is 0.000 => set them to None
#
self.log(u"len(text) is zero: returning 0.000")
Expand Down Expand Up @@ -640,7 +640,7 @@ def _read_audio_data(self, file_path):
"""
Read audio data from file.
:rtype: tuple (True, (duration, sample_rate, encoding, data)) or (False, None) on exception
:rtype: tuple (True, (duration, sample_rate, codec, data)) or (False, None) on exception
"""
try:
self.log(u"Reading audio data...")
Expand Down Expand Up @@ -680,22 +680,30 @@ def _synthesize_multiple_generic(self, helper_function, text_file, output_file_p
"""
self.log(u"Calling TTS engine using multiple generic function...")

# get sample rate and encoding
self.log(u"Determining codec and sample rate with dummy text...")
succeeded, data = helper_function(
text=u"Dummy text to get sample_rate",
voice_code=self._language_to_voice_code(self.DEFAULT_LANGUAGE),
output_file_path=None
)
if not succeeded:
self.log_crit(u"An unexpected error occurred in helper_function")
return (False, None)
du_nu, sample_rate, encoding, da_nu = data
self.log(u"Determining codec and sample rate with dummy text... done")
# get sample rate and codec
self.log(u"Determining codec and sample rate...")
if (self.OUTPUT_AUDIO_FORMAT is None) or (len(self.OUTPUT_AUDIO_FORMAT) != 3):
self.log(u"Determining codec and sample rate with dummy text...")
succeeded, data = helper_function(
text=u"Dummy text to get sample_rate",
voice_code=self._language_to_voice_code(self.DEFAULT_LANGUAGE),
output_file_path=None
)
if not succeeded:
self.log_crit(u"An unexpected error occurred in helper_function")
return (False, None)
du_nu, sample_rate, codec, da_nu = data
self.log(u"Determining codec and sample rate with dummy text... done")
else:
self.log(u"Reading codec and sample rate from OUTPUT_AUDIO_FORMAT")
codec, channels_nu, sample_rate = self.OUTPUT_AUDIO_FORMAT
self.log(u"Determining codec and sample rate... done")
self.log([u" codec: %s", codec])
self.log([u" sample rate: %d", sample_rate])

# open output file
output_file = AudioFile(rconf=self.rconf, logger=self.logger)
output_file.audio_format = encoding
output_file.audio_format = codec
output_file.audio_channels = 1
output_file.audio_sample_rate = sample_rate

Expand Down Expand Up @@ -821,5 +829,7 @@ def _loop_use_cache(self, helper_function, num, fragment):
self.log(u"Added fragment to cache")
else:
self.log(u"Fragment has zero duration, not adding it to cache")
self.log([u"Closing file handler for cached output file path '%s'", file_path])
gf.close_file_handler(file_handler)
self.log([u"Examining fragment %d (cache)... done", num])
return (True, data)
2 changes: 1 addition & 1 deletion aeneas/ttswrappers/festivalttswrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ class FESTIVALTTSWrapper(BaseTTSWrapper):
ENG_SCT: ENG_SCT,
ENG_USA: ENG_USA,
}
DEFAULT_LANGUAGE = ENG
DEFAULT_LANGUAGE = ENG_USA

CODE_TO_HUMAN = {
CES: u"Czech",
Expand Down
2 changes: 1 addition & 1 deletion aeneas_check_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"""
__license__ = "GNU AGPL 3"
__status__ = "Production"
__version__ = "1.7.0"
__version__ = "1.7.1"

ANSI_ERROR = u"\033[91m"
ANSI_OK = u"\033[92m"
Expand Down
2 changes: 1 addition & 1 deletion bin/aeneas_check_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"""
__license__ = "GNU AGPL 3"
__status__ = "Production"
__version__ = "1.7.0"
__version__ = "1.7.1"

ANSI_ERROR = u"\033[91m"
ANSI_OK = u"\033[92m"
Expand Down
2 changes: 1 addition & 1 deletion bin/aeneas_convert_syncmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"""
__license__ = "GNU AGPL 3"
__status__ = "Production"
__version__ = "1.7.0"
__version__ = "1.7.1"


def main():
Expand Down
2 changes: 1 addition & 1 deletion bin/aeneas_download.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"""
__license__ = "GNU AGPL 3"
__status__ = "Production"
__version__ = "1.7.0"
__version__ = "1.7.1"


def main():
Expand Down
2 changes: 1 addition & 1 deletion bin/aeneas_execute_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"""
__license__ = "GNU AGPL 3"
__status__ = "Production"
__version__ = "1.7.0"
__version__ = "1.7.1"


def main():
Expand Down
2 changes: 1 addition & 1 deletion bin/aeneas_execute_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"""
__license__ = "GNU AGPL 3"
__status__ = "Production"
__version__ = "1.7.0"
__version__ = "1.7.1"


def main():
Expand Down
2 changes: 1 addition & 1 deletion bin/aeneas_plot_waveform.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"""
__license__ = "GNU AGPL 3"
__status__ = "Production"
__version__ = "1.7.0"
__version__ = "1.7.1"


def main():
Expand Down
2 changes: 1 addition & 1 deletion bin/aeneas_synthesize_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"""
__license__ = "GNU AGPL 3"
__status__ = "Production"
__version__ = "1.7.0"
__version__ = "1.7.1"


def main():
Expand Down
2 changes: 1 addition & 1 deletion bin/aeneas_validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"""
__license__ = "GNU AGPL 3"
__status__ = "Production"
__version__ = "1.7.0"
__version__ = "1.7.1"


def main():
Expand Down
2 changes: 1 addition & 1 deletion check_dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"""
__license__ = "GNU AGPL 3"
__status__ = "Production"
__version__ = "1.7.0"
__version__ = "1.7.1"

ANSI_ERROR = u"\033[91m"
ANSI_OK = u"\033[92m"
Expand Down
Loading

0 comments on commit d5d6583

Please sign in to comment.