Beispiel #1
0
def test_separator():
    backend = SegmentsBackend('cree')
    text = 'achi acho'

    sep = separator.default_separator
    assert backend.phonemize(text, separator=sep) == u'ʌtʃɪ ʌtʃʊ '
    assert backend.phonemize(text, separator=sep, strip=True) == u'ʌtʃɪ ʌtʃʊ'
Beispiel #2
0
def version():
    """Return version information for front and backends"""
    # version of the phonemizer
    version = ('phonemizer-' +
               pkg_resources.get_distribution('phonemizer').version)

    # for each backend, check if it is available or not. If so get its version
    available = []
    unavailable = []

    if EspeakBackend.is_available():
        available.append('espeak-' +
                         ('ng-' if EspeakBackend.is_espeak_ng() else '') +
                         EspeakBackend.version())
    else:  # pragma: nocover
        unavailable.append('espeak')

    if FestivalBackend.is_available():
        available.append('festival-' + FestivalBackend.version())
    else:  # pragma: nocover
        unavailable.append('festival')

    if SegmentsBackend.is_available():
        available.append('segments-' + SegmentsBackend.version())
    else:  # pragma: nocover
        unavailable.append('segments')

    # resumes the backends status in the final version string
    if available:
        version += '\navailable backends: ' + ', '.join(available)
    if unavailable:  # pragma: nocover
        version += '\nuninstalled backends: ' + ', '.join(unavailable)

    return version
def test_segments():
    text = 'achi, acho!'
    expected1 = 'ʌtʃɪ ʌtʃʊ'
    expected2 = 'ʌtʃɪ, ʌtʃʊ!'
    expected3 = 'ʌtʃɪ ʌtʃʊ '
    expected4 = 'ʌtʃɪ, ʌtʃʊ!'

    out1 = SegmentsBackend('cree',
                           preserve_punctuation=False).phonemize([text],
                                                                 strip=True)[0]
    assert out1 == expected1

    out2 = SegmentsBackend('cree',
                           preserve_punctuation=True).phonemize([text],
                                                                strip=True)[0]
    assert out2 == expected2

    out3 = SegmentsBackend('cree', preserve_punctuation=False).phonemize(
        [text], strip=False)[0]
    assert out3 == expected3

    out4 = SegmentsBackend('cree',
                           preserve_punctuation=True).phonemize([text],
                                                                strip=False)[0]
    assert out4 == expected4
Beispiel #4
0
def test_separator():
    backend = SegmentsBackend('cree')
    text = 'achi acho'

    sep = separator.default_separator
    assert backend.phonemize(text, separator=sep) == u'ʌtʃɪ ʌtʃʊ '
    assert backend.phonemize(text, separator=sep, strip=True) == u'ʌtʃɪ ʌtʃʊ'
Beispiel #5
0
def test_separator_3():
    backend = SegmentsBackend('cree')
    text = 'achi acho'

    sep = separator.Separator(word=' ', syllable=None, phone='_')
    assert backend.phonemize(text, separator=sep) == u'ʌ_tʃ_ɪ_ ʌ_tʃ_ʊ_ '
    assert backend.phonemize(text, separator=sep, strip=True) \
        == u'ʌ_tʃ_ɪ ʌ_tʃ_ʊ'
Beispiel #6
0
def test_separator_5():
    backend = SegmentsBackend('cree')
    text = 'achi acho'

    sep = separator.Separator(phone=' ', word='_')
    assert backend.phonemize(text, separator=sep) == u'ʌ tʃ ɪ _ʌ tʃ ʊ _'
    assert backend.phonemize(text, separator=sep, strip=True) \
        == u'ʌ tʃ ɪ_ʌ tʃ ʊ'
Beispiel #7
0
def test_separator_2():
    backend = SegmentsBackend('cree')
    text = ['achi acho']

    sep = Separator(word='_', phone=' ')
    assert backend.phonemize(text, separator=sep) == [u'ʌ tʃ ɪ _ʌ tʃ ʊ _']
    assert backend.phonemize(text, separator=sep, strip=True) \
        == [u'ʌ tʃ ɪ_ʌ tʃ ʊ']
Beispiel #8
0
def test_separator_5():
    backend = SegmentsBackend('cree')
    text = 'achi acho'

    sep = separator.Separator(phone=' ', word='_')
    assert backend.phonemize(text, separator=sep) == u'ʌ tʃ ɪ _ʌ tʃ ʊ _'
    assert backend.phonemize(text, separator=sep, strip=True) \
        == u'ʌ tʃ ɪ_ʌ tʃ ʊ'
Beispiel #9
0
def test_separator_3():
    backend = SegmentsBackend('cree')
    text = 'achi acho'

    sep = separator.Separator(word=' ', syllable=None, phone='_')
    assert backend.phonemize(text, separator=sep) == u'ʌ_tʃ_ɪ_ ʌ_tʃ_ʊ_ '
    assert backend.phonemize(text, separator=sep, strip=True) \
        == u'ʌ_tʃ_ɪ ʌ_tʃ_ʊ'
Beispiel #10
0
def test_separator_4():
    backend = SegmentsBackend('cree')
    text = 'achi acho'

    # TODO bug when sep.phone == ' ' with no sep.word
    sep = separator.Separator(phone=' ', word='')
    assert backend.phonemize(text, separator=sep) == u'ʌ tʃ ɪ ʌ tʃ ʊ '
    assert backend.phonemize(text, separator=sep, strip=True) \
        == u'ʌ tʃ ɪʌ tʃ ʊ'
Beispiel #11
0
def test_separator_4():
    backend = SegmentsBackend('cree')
    text = 'achi acho'

    # TODO bug when sep.phone == ' ' with no sep.word
    sep = separator.Separator(phone=' ', word='')
    assert backend.phonemize(text, separator=sep) == u'ʌ tʃ ɪ ʌ tʃ ʊ '
    assert backend.phonemize(text, separator=sep, strip=True) \
        == u'ʌ tʃ ɪʌ tʃ ʊ'
Beispiel #12
0
def test_multiline():
    backend = SegmentsBackend('cree')
    assert backend.phonemize('a') == u'ʌ '
    assert backend.phonemize('aa') == u'ʌʌ '
    assert backend.phonemize('a\n') == u'ʌ '
    assert backend.phonemize('a\na') == u'ʌ \nʌ '
    assert backend.phonemize('a\na\n') == u'ʌ \nʌ '
Beispiel #13
0
def version():
    """Return version information for front and backends"""
    version = ('phonemizer-' +
               pkg_resources.get_distribution('phonemizer').version)

    return version + '\navailable backends: ' + ', '.join(
        ('festival-' + FestivalBackend.version(),
         ('espeak-' + ('ng-' if EspeakBackend.is_espeak_ng() else '') +
          EspeakBackend.version()), 'segments-' + SegmentsBackend.version()))
Beispiel #14
0
def test_multiline():
    backend = SegmentsBackend('cree')
    assert backend.language == 'cree'

    assert backend.phonemize(['a']) == [u'ʌ ']
    assert backend.phonemize(['aa']) == [u'ʌʌ ']
    assert backend.phonemize(['a\n']) == [u'ʌ ']
    assert backend.phonemize(['a\na']) == [u'ʌ ʌ ']
    assert backend.phonemize(['a\na\n']) == [u'ʌ ʌ ']
    assert backend.phonemize(['a', 'a']) == [u'ʌ ', 'ʌ ']
    assert backend.phonemize(['a\n', 'a\n']) == [u'ʌ ', 'ʌ ']
Beispiel #15
0
def version():
    """Return version information for front and backends"""
    version = ('phonemizer-'
               + pkg_resources.get_distribution('phonemizer').version)

    return version + '\navailable backends: ' + ', '.join(
        ('festival-' + FestivalBackend.version(),
         ('espeak-' + ('ng-' if EspeakBackend.is_espeak_ng() else '')
          + EspeakBackend.version()),
         'segments-' + SegmentsBackend.version()))
Beispiel #16
0
def test_multiline():
    backend = SegmentsBackend('cree')
    assert backend.phonemize('a') == u'ʌ '
    assert backend.phonemize('aa') == u'ʌʌ '
    assert backend.phonemize('a\n') == u'ʌ '
    assert backend.phonemize('a\na') == u'ʌ \nʌ '
    assert backend.phonemize('a\na\n') == u'ʌ \nʌ '
def test_language(tmpdir):
    # check languages by name
    assert SegmentsBackend.is_supported_language('cree')
    assert not SegmentsBackend.is_supported_language('unexisting')

    # check languages by g2p file
    directory = pkg_resources.resource_filename(
        pkg_resources.Requirement.parse('phonemizer'), 'phonemizer/share')
    assert SegmentsBackend.is_supported_language(
        os.path.join(directory, 'cree.g2p'))
    assert not SegmentsBackend.is_supported_language(
        os.path.join(directory, 'cree'))
    assert not SegmentsBackend.is_supported_language(
        os.path.join(directory, 'unexisting.g2p'))

    # bad syntax in g2p file
    p = tmpdir.join('foo.g2p')
    p.write('\n'.join(['a a', 'b b b', 'c']))
    assert not SegmentsBackend.is_supported_language(p)
Beispiel #18
0
    def recognize(self, wav=None):

        if not self.eng.find("fest") == -1:
            # ======= festival english us only =====================================
            from phonemizer.backend import FestivalBackend
            out1 = FestivalBackend(
                'en-us', preserve_punctuation=False).phonemize(self.text,
                                                               strip=True)
        elif not self.eng.find("esp") == -1:
            # ======= espeak =======================================================
            from phonemizer.backend import EspeakBackend
            if not self.lan.find("en") == -1:
                backend = EspeakBackend('en-us')
            elif not self.lan.find("fr") == -1:
                backend = EspeakBackend('fr-fr')
            elif not self.lan.find("de") == -1 or not self.lan.find(
                    "ger") == -1:
                backend = EspeakBackend('de-de')
            elif not self.lan.find("ita") == -1:
                backend = EspeakBackend('it-it')
            elif not self.lan.find("esp") == -1 or not self.lan.find(
                    "spa") == -1:
                backend = EspeakBackend('es-es')
            else:
                print("Invalid Language specified")
                exit(1)
            sep = separator.Separator(word=';eword ', syllable=None, phone=' ')
            out1 = backend.phonemize(self.text, sep, False)
        elif not self.eng.find("mbr") == -1:
            # ====== mbrola ========================================================
            from phonemizer.backend import EspeakBackend, EspeakMbrolaBackend
            if EspeakMbrolaBackend.is_available():
                if not self.lan.find("en") == -1:
                    EspeakMbrolaBackend('mb-en1')
                elif not self.lan.find("fr") == -1:
                    EspeakMbrolaBackend('mb-fr2')
                elif not self.lan.find("de") == -1 or not self.lan.find(
                        "ger") == -1:
                    EspeakMbrolaBackend('mb-de1')
                elif not self.lan.find("ita") == -1:
                    EspeakMbrolaBackend('mb-es1')
                elif not self.lan.find("esp") == -1 or not self.lan.find(
                        "spa") == -1:
                    EspeakMbrolaBackend('mb-it3')
                else:
                    print("Invalid Language specified")
                    exit(1)
                sep = separator.Separator(word=';eword ',
                                          syllable=None,
                                          phone=' ')
                out1 = backend.phonemize(self.text, sep, False)
        elif not self.eng.find("seg") == -1:
            # ===== segment ========================================================
            from phonemizer.backend import SegmentsBackend
            if not self.lan.find("ja") == -1:
                backend = SegmentsBackend('japanese')
            else:
                print("Invalid Language specified")
                exit(1)
            sep = separator.Separator(word=';eword ', syllable=None, phone=' ')
            out1 = backend.phonemize(self.text, sep, False)
        else:
            print("Invalid Language specified")
            exit(1)
        print(out1)  # return the result string to the speach engine
Beispiel #19
0
def test_bad_morpheme():
    backend = SegmentsBackend('cree')
    with pytest.raises(ValueError):
        backend.phonemize('A')
Beispiel #20
0
def parse_args():
    """Argument parser for the phonemization script"""
    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description='''Multilingual text to phonemes converter

The 'phonemize' program allows simple phonemization of words and texts
in many language using three backends: espeak, festival and segments.

- espeak is a text-to-speech software supporting multiple languages
  and IPA (Internatinal Phonetic Alphabet) output. See
  http://espeak.sourceforge.net or
  https://github.com/espeak-ng/espeak-ng

- festival is also a text-to-speech software. Currently only American
  English is supported and festival uses a custom phoneset
  (http://www.festvox.org/bsv/c4711.html), but festival is the only
  backend supporting tokenization at the syllable
  level. See http://www.cstr.ed.ac.uk/projects/festival

- segments is a Unicode tokenizer that build a phonemization from a
  grapheme to phoneme mapping provided as a file by the user. See
  https://github.com/cldf/segments.

See the '--language' option below for details on the languages
supported by each backend.

''',
        epilog='''
   Languages supported by the festival backend are:
   {festival}

   Languages supported by the segments backend are:
   {segments}
   Instead of a language you can also provide a file specifying a
   grapheme to phoneme mapping (see the files above for exemples).

   Languages supported by the espeak backend are:
   {espeak}


Exemples:

* Phonemize a US English text with espeak

   $ echo 'hello world' | phonemize -l en-us -b espeak
   həloʊ wɜːld

* Phonemize a US English text with festival

   $ echo 'hello world' | phonemize -l en-us -b festival
   hhaxlow werld

* Phonemize a Japanese text with segments

  $ echo 'konnichiwa tsekai' | phonemize -l japanese -b segments
  konnitʃiwa t͡sekai

* Add a separator between phones

  $ echo 'hello world' | phonemize -l en-us -b festival -p '-' --strip
  hh-ax-l-ow w-er-l-d

* Phonemize some French text file using espeak

  $ phonemize -l fr-fr -b espeak text.txt -o phones.txt
        '''.format(festival='\n'.join(
            '\t{}\t->\t{}'.format(k, v)
            for k, v in sorted(FestivalBackend.supported_languages().items())),
                   segments='\n'.join(
                       '\t{}\t->\t{}'.format(k, v) for k, v in sorted(
                           SegmentsBackend.supported_languages().items())),
                   espeak='\n'.join(
                       '\t{}\t->\t{}'.format(k, v) for k, v in sorted(
                           EspeakBackend.supported_languages().items()))))

    # general arguments
    parser.add_argument('--version',
                        action='store_true',
                        help='show version information and exit.')

    group = parser.add_mutually_exclusive_group()
    group.add_argument('-v',
                       '--verbose',
                       action='store_true',
                       help='write all log messages to stderr '
                       '(displays only warnings by default).')
    group.add_argument('-q',
                       '--quiet',
                       action='store_true',
                       help='do not display any log message, even warnings.')

    parser.add_argument(
        '-j',
        '--njobs',
        type=int,
        metavar='<int>',
        default=1,
        help='number of parallel jobs, default is %(default)s.')

    # input/output arguments
    group = parser.add_argument_group('input/output')
    group.add_argument(
        'input',
        default=sys.stdin,
        nargs='?',
        metavar='<file>',
        help='input text file to phonemize, if not specified read from stdin.')

    group.add_argument(
        '-o',
        '--output',
        default=sys.stdout,
        metavar='<file>',
        help='output text file to write, if not specified write to stdout.')

    group = parser.add_argument_group('separators')
    group.add_argument('-p',
                       '--phone-separator',
                       metavar='<str>',
                       default=separator.default_separator.phone,
                       help='phone separator, default is "%(default)s".')

    group.add_argument('-w',
                       '--word-separator',
                       metavar='<str>',
                       default=separator.default_separator.word,
                       help='word separator, default is "%(default)s".')

    group.add_argument(
        '-s',
        '--syllable-separator',
        metavar='<str>',
        default=separator.default_separator.syllable,
        help='''syllable separator, only valid for festival backend,
        this option has no effect if espeak or segments is used.
        Default is "%(default)s".''')

    group.add_argument('--strip',
                       action='store_true',
                       help='removes the end separators in phonemized tokens.')

    group = parser.add_argument_group('backends')
    group.add_argument(
        '-b',
        '--backend',
        metavar='<str>',
        default='espeak',
        choices=['espeak', 'festival', 'segments'],
        help="""the phonemization backend, must be 'espeak', 'festival' or
        'segments'. Default is %(default)s.""")

    group = parser.add_argument_group('specific to espeak backend')
    group.add_argument(
        '--with-stress',
        action='store_true',
        help='''when the option is set, the stresses on phonemes are present
        (stresses characters are ˈ'ˌ). By default stresses are removed.''')
    group.add_argument(
        '--sampa',
        action='store_true',
        help='''only valid for espeak-ng and NOT supported for espeak, use the
        "sampa" (Speech Assessment Methods Phonetic Alphabet) alphabet instead
        of "ipa" (International Phonetic Alphabet).''')
    group.add_argument(
        '--language-switch',
        default='keep-flags',
        choices=['keep-flags', 'remove-flags', 'remove-utterance'],
        help="""espeak can pronounce some words in another language (typically
        English) when phonemizing a text. This option setups the policy to use
        when such a language switch occurs. Three values are available:
        'keep-flags' (the default), 'remove-flags' or 'remove-utterance'. The
        'keep-flags' policy keeps the language switching flags, for example
        (en) or (jp), in the output. The 'remove-flags' policy removes them and
        the 'remove-utterance' policy removes the whole line of text including
        a language switch.""")

    group = parser.add_argument_group('language')
    group.add_argument(
        '-l',
        '--language',
        metavar='<str|file>',
        default='en-us',
        help='''the language code of the input text, see below for a list of
        supported languages. According to the language code you
        specify, the appropriate backend (segments, espeak or
        festival) will be called in background. Default is
        %(default)s.''')

    return parser.parse_args()
Beispiel #21
0
def parse_args():
    """Argument parser for the phonemization script"""
    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description='''Multilingual text to phonemes converter

The 'phonemize' program allows simple phonemization of words and texts
in many language using three backends: espeak, festival and segments.

- espeak is a text-to-speech software supporting multiple languages
  and IPA (Internatinal Phonetic Alphabet) output. See
  http://espeak.sourceforge.net or
  https://github.com/espeak-ng/espeak-ng

- festival is also a text-to-speech software. Currently only American
  English is supported and festival uses a custom phoneset
  (http://www.festvox.org/bsv/c4711.html), but festival is the only
  backend supporting tokenization at the syllable
  level. See http://www.cstr.ed.ac.uk/projects/festival

- segments is a Unicode tokenizer that build a phonemization from a
  grapheme to phoneme mapping provided as a file by the user. See
  https://github.com/cldf/segments.

See the '--language' option below for details on the languages
supported by each backend.

''',
        epilog='''
   Languages supported by the festival backend are:
   {festival}

   Languages supported by the segments backend are:
   {segments}
   Instead of a language you can also provide a file specifying a
   grapheme to phoneme mapping (see the files above for exemples).

   Languages supported by the espeak backend are:
   {espeak}


Exemples:

* Phonemize a US English text with espeak

   $ echo 'hello world' | phonemize -l en-us -b espeak
   həloʊ wɜːld

* Phonemize a US English text with festival

   $ echo 'hello world' | phonemize -l en-us -b festival
   hhaxlow werld

* Phonemize a Japanese text with segments

  $ echo 'konnichiwa tsekai' | phonemize -l japanese -b segments
  konnitʃiwa t͡sekai

* Add a separator between phones

  $ echo 'hello world' | phonemize -l en-us -b festival -p '-' --strip
  hh-ax-l-ow w-er-l-d

* Phonemize some French text file using espeak

  $ phonemize -l fr-fr -b espeak text.txt -o phones.txt
        '''.format(
            festival='\n'.join(
                '\t{}\t->\t{}'.format(k, v) for k, v in
                sorted(FestivalBackend.supported_languages().items())),
            segments='\n'.join(
                '\t{}\t->\t{}'.format(k, v) for k, v in
                sorted(SegmentsBackend.supported_languages().items())),
            espeak='\n'.join(
                '\t{}\t->\t{}'.format(k, v) for k, v in
                sorted(EspeakBackend.supported_languages().items()))))

    # general arguments
    parser.add_argument(
        '--version', action='store_true',
        help='show version information and exit')

    parser.add_argument(
        '-v', '--verbose', action='store_true',
        help='write some log messages to stderr')

    parser.add_argument(
        '-j', '--njobs', type=int, metavar='<int>', default=1,
        help='number of parallel jobs, default is %(default)s')

    # input/output arguments
    group = parser.add_argument_group('input/output')
    group.add_argument(
        'input', default=sys.stdin, nargs='?', metavar='<file>',
        help='input text file to phonemize, if not specified read from stdin')

    group.add_argument(
        '-o', '--output', default=sys.stdout, metavar='<file>',
        help='output text file to write, if not specified write to stdout')

    group = parser.add_argument_group('separators')
    group.add_argument(
        '-p', '--phone-separator', metavar='<str>',
        default=separator.default_separator.phone,
        help='phone separator, default is "%(default)s"')

    group.add_argument(
        '-w', '--word-separator', metavar='<str>',
        default=separator.default_separator.word,
        help='word separator, default is "%(default)s"')

    group.add_argument(
        '-s', '--syllable-separator', metavar='<str>',
        default=separator.default_separator.syllable,
        help='''syllable separator is available only for the festival backend,
        this option has no effect if espeak or segments is used.
        Default is "%(default)s"''')

    group.add_argument(
        '--strip', action='store_true',
        help='removes the end separators in phonemized tokens')

    group = parser.add_argument_group('language')

    group.add_argument(
        '-b', '--backend', metavar='<str>', default='espeak',
        choices=['espeak', 'festival', 'segments'],
        help="""the phonemization backend, must be 'espeak', 'festival' or
        'segments'. Default is %(default)s""")

    group.add_argument(
        '-l', '--language', metavar='<str|file>', default='en-us',
        help='''the language code of the input text, see below for a list of
        supported languages. According to the language code you
        specify, the appropriate backend (segments, espeak or
        festival) will be called in background. Default is
        %(default)s''')

    return parser.parse_args()
Beispiel #22
0
def test_bad_morpheme():
    backend = SegmentsBackend('cree')
    with pytest.raises(ValueError):
        backend.phonemize('A')