Synteza mowy III: Finał

20.07.2010 - Krzysztof Kercz
TrudnośćTrudność

Fraza.py

Pokaż/ukryj kod źródłowy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#!/usr/bin/python
# -*- coding: utf-8 -*-
 
import Slowo, wav
 
def inter(a, b):
    
    """ Bierze dwie głoski a i b, w domyśle występujące na końcu
        i na początku wyrazów stojących obok siebie we frazie. 
        Zwraca je po zajściu (lub nie) upodobnienia międzywyrazowego """
    
    if a.dzwieczna != b.dzwieczna and not (
            a.stopien_zblizenia in [u'półsamogłoskowa',
                u'drżąca', u'nosowa', u'boczna'] or 
                b.stopien_zblizenia in [u'półsamogłoskowa',
                u'drżąca', u'nosowa', u'boczna']):
        a.zmien_dzwiecznosc()
    return a,b
 
class Fraza:
    def __init__(self, phrase, filename=None):
        self.fraza = map(lambda word: Slowo.Slowo(word), phrase.split())
        
        # upodobnienia międzywyrazowe
        for i in range(len(self.fraza)-1):
            a,b = self.fraza[i][-1],self.fraza[i+1][0]
            (self.fraza[i][-1],self.fraza[i+1][0]) = inter(a, b)
            
        self.bytes = ""
        self.filename = None
        
        #jeśli w konstruktorze podano nazwę pliku, dokonujemy syntezy
        if filename:
            self.write(filename)
        
    def get_bytes(self):
        for S in self:
            self.bytes += S.get_bytes()
        return self.bytes
        
    def write(self,filename):
    """Zapisuje reprezentację dźwiękową frazy do pliku filename"""
        
        if len(self.bytes) == 0: self.get_bytes()
        F = wav.create_wave(filename, self.bytes)
        self.filename = filename
        return filename
            
    def __iter__(self):
        return self.fraza.__iter__()
            
    def __getitem__(self,i):
        return self.fraza[i]
            
    def __repr__(self):
        return str(self.fraza)
            
    def __str__(self):
        return ' '.join(map(lambda x:str(x), self.fraza))

Mamy głoski, mamy słowa - co nam zostało? Frazy! Fraza to ciąg słów wypowiedzianych na jednym oddechu. Kolejnym etapem byłoby już zdanie. Być może za jakiś czas zastanowimy się nad sprawami takimi jak akcent zdaniowy czy intonacja, na razie jednak zatrzymamy się tutaj i zadowolimy syntezowaniem jedynie prostych fraz.

Mając frazy, musimy wziąć pod uwagę jeszcze jedno zjawisko fonetyczne - upodobnienia międzywyrazowe. Przypomnijmy, co pisaliśmy o tym w pierwszej części cyklu: upodobnienia międzywyrazowe - frazy wypowiadamy na jednym oddechu, więc między dwoma wyrazami mogą zajść takie same zjawiska jak w ich wnętrzu, przykład: grot żelazny -> /g r o d rz e l a z n y/ .W konstruktorze frazy, po rozbiciu wejściowego zdania na pojedyncze słowa i dokonaniu ich fonemizacji, bierzemy wszystkie pary słów sąsiadujących i sprawdzamy, czy zachodzi upodobnienie; jeśli tak - podmieniamy odpowiednie głoski (linie 24-27 i funkcja inter(a, b)).

W tej klasie umieściliśmy funkcjonalność syntezowania fraz. Funkcja Fraza.get_bytes() pobiera listę bajtów reprezentujących frazę w dość oczywisty sposób: konkatenuje listy bajtów słów tworzących tę frazę. Pozostaje nam tylko zapisać plik dźwiękowy - dokonujemy tego funkcją Fraza.write(filename), która korzysta z modułu wav (opowiemy o nim na następnej stronie) by zapisać plik dźwiękowy na dysku.

Aby użyć tej klasy, wystarczy uruchomić ją w trybie interaktywnym Pythona i już możemy dokonywać syntezy. Dla przykładu, by zapisać frazę dzień dobry do pliku powitanie.wav napiszemy:

>>> print Fraza(u'dzień dobry', 'powitanie.wav')
dzi-e-ni d-O-b-r-y
Konstruktor zwraca obiekt klasy Fraza, więc jeśli napiszemy przed wywołaniem print, to dodatkowo program wypisze nam reprezentację fonetyczną frazy (samogłoski napisane wielką literą są akcentowane).

5
Twoja ocena: Brak Ocena: 5 (1 ocena)

Copyright © 2008-2010 Wrocławski Portal Informatyczny

design: rafalpolito.com