예제 #1
0
def label2otoini(label, name_wav):
    """
    LabelオブジェクトをOtoIniオブジェクトに変換
    モノフォン、CV、VCV とかの選択肢が必要そう
    otoini_time_order: otoiniの時間オーダー。
    label_time_order : ラベルの時間オーダー。
    """
    # time_order_ratio = label_time_order / otoini_time_order
    time_order_ratio = 10**(-4)

    otoini = _otoini.OtoIni()
    # 各音素PhonemeオブジェクトをOtoオブジェクトに変換して、OtoIniに格納する。
    for phoneme in label:
        oto = _otoini.Oto()
        oto.filename = name_wav
        oto.alias = phoneme.symbol
        oto.offset = phoneme.start * time_order_ratio
        oto.overlap = 0.0
        oto.preutterance = 0.0
        oto.consonant = (phoneme.end - phoneme.start) * time_order_ratio
        oto.cutoff = -(phoneme.end - phoneme.start) * time_order_ratio
        otoini.append(oto)
    return otoini
예제 #2
0
def ust2otoini_mono(ust, name_wav, d_table, dt=100, debug=False):
    """
    UstクラスオブジェクトからOtoIniクラスオブジェクトを生成
    vowel_otoの対称は母音以外に 'N', 'cl' なども含まれる。
    mode : otoiniのエイリアス種別選択
    【パラメータ設定図】
    simple_oto---------------------------------------------------------------
      |||左ブランク・オーバーラップ・先行発声 ||固定範囲・右ブランク
      |||       ノート長 + 2dt (ms)           ||
    -------------------------------------------------------------------------
    子音・半母音用のoto------------------------------------------------------
      ||左ブランク・オーバーラップ |先行発声 ||固定範囲・右ブランク
      ||          dt(ms)           | dt(ms)  ||
    -------------------------------------------------------------------------
    母音用のoto--------------------------------------------------------------
      ||左ブランク・オーバーラップ |先行発声 |固定範囲            |右ブランク
      ||          dt(ms)           | dt(ms)  | ノート長 - dt (ms) |
    -------------------------------------------------------------------------
    """
    ust.make_finalnote_R()  # 最終ノートが休符じゃない場合を対策

    # UstのNoteオブジェクトごとにOtoオブジェクトを生成
    kana_otoini = _otoini.OtoIni()  # simple_otoを入れるリスト
    t = 0  # ノート開始時刻を記録
    for note in ust.notes:
        length = note.length_ms
        simple_oto = _otoini.Oto()  # 各パラメータ位置を両端に集めたOto
        simple_oto.filename = name_wav
        simple_oto.alias = note.lyric
        simple_oto.offset = t
        simple_oto.overlap = 0
        simple_oto.preutterance = 0
        simple_oto.consonant = length
        simple_oto.cutoff = -length  # 負で左ブランク相対時刻, 正で絶対時刻
        kana_otoini.append(simple_oto)
        t += length  # 今のノート終了位置が次のノート開始位置

    # Otoを音素ごとに分割
    mono_otoini = _otoini.OtoIni()  # mono_otoを入れるリスト
    for simple_oto in kana_otoini:
        if debug:
            print(f'    {simple_oto.values}')
        try:
            phonemes = d_table[simple_oto.alias]
        except KeyError as e:
            print('KeyError in utaupy.convert.ust2otoini_mono---------')
            print('ひらがなローマ字変換に失敗しました。半角スペースで音素分割してぶち込みます。')
            print('エラー詳細:', e)
            print('--------------------------------------\n')
            phonemes = simple_oto.alias.split()
            print(phonemes)
        # 子音+母音 「か(k a)」
        if len(phonemes) == 2:
            # 子音部分
            oto = _otoini.Oto()
            oto.filename = name_wav
            oto.alias = phonemes[0]
            oto.offset = simple_oto.offset - (2 * dt)
            oto.overlap = 0
            oto.preutterance = dt
            oto.consonant = 2 * dt
            oto.cutoff = -2 * dt
            mono_otoini.append(oto)
            # 母音部分
            oto = _otoini.Oto()
            oto.filename = name_wav
            oto.alias = phonemes[1]
            oto.offset = simple_oto.offset - dt
            oto.overlap = 0
            oto.preutterance = dt
            oto.consonant = 2 * dt
            oto.cutoff = simple_oto.cutoff - dt
            mono_otoini.append(oto)
        # 母音など 「あ(a)」「ん(cl)」「っ(cl)」「(pau)」「(br)」「(sil)」
        elif len(phonemes) == 1:
            oto = _otoini.Oto()
            oto.filename = name_wav
            oto.alias = phonemes[0]
            oto.offset = simple_oto.offset - dt
            oto.overlap = 0
            oto.preutterance = dt
            oto.consonant = 2 * dt
            oto.cutoff = simple_oto.cutoff - dt
            mono_otoini.append(oto)
        # 子音+半母音+母音 「ぐぁ(g w a)」
        elif len(phonemes) == 3:
            # 子音部分
            oto = _otoini.Oto()
            oto.filename = name_wav
            oto.alias = phonemes[0]
            oto.offset = simple_oto.offset - (2 * dt)
            oto.overlap = 0
            oto.preutterance = dt
            oto.consonant = 2 * dt
            oto.cutoff = -2 * dt
            mono_otoini.append(oto)
            # 半母音部分
            oto = _otoini.Oto()
            oto.filename = name_wav
            oto.alias = phonemes[1]
            oto.offset = simple_oto.offset - dt
            oto.overlap = 0
            oto.preutterance = dt
            oto.consonant = 2 * dt
            oto.cutoff = -2 * dt
            mono_otoini.append(oto)
            # 母音部分
            oto = _otoini.Oto()
            oto.filename = name_wav
            oto.alias = phonemes[2]
            oto.offset = simple_oto.offset
            oto.overlap = 0
            oto.preutterance = dt
            oto.consonant = 2 * dt
            oto.cutoff = simple_oto.cutoff - (2 * dt)
            mono_otoini.append(oto)
        else:
            raise ValueError('len(alias) must be in [1, 2, 3]')

    mono_otoini[0].offset = 0
    mono_otoini[0].preutterance = 0
    return mono_otoini
예제 #3
0
def ust2otoini_romaji_cv(ust,
                         name_wav,
                         d_table,
                         dt=100,
                         replace=True,
                         debug=False):
    """
    UstクラスオブジェクトからOtoIniクラスオブジェクトを生成
    dt   : 左ブランク - オーバーラップ - 先行発声 - 固定範囲と右ブランク の距離
    mode : otoiniのエイリアス種別選択
    【パラメータ設定図】
      | 左ブランク |オーバーラップ| 先行発声 | 固定範囲 |   右ブランク   |
      |   (dt)ms   |    (dt)ms    |  (dt)ms  |  (dt)ms  | (length-2dt)ms |
    """
    ust.make_finalnote_R()  # 最終ノートが休符じゃない場合を対策
    otoini = _otoini.OtoIni()
    t = 0  # ノート開始時刻を記録

    # NOTE: ここnotes[2:-1]とust.values[2:-1]で処理時間に差は出る?
    for note in ust.notes:
        if debug:
            print(f'    {ust}')
        try:
            phonemes = d_table[note.lyric]
        except KeyError as e:
            print(
                f'    [WARN] KeyError in utaupy.convert.ust2otoini_romaji_cv : {e}'
            )
            phonemes = note.lyric.split()

        length = note.length_ms
        oto = _otoini.Oto()
        oto.filename = name_wav  # wavファイル名
        if replace:
            oto.alias = ' '.join(phonemes)  # エイリアスは音素ごとに空白区切り
        else:
            oto.alias = note.lyric
        oto.offset = t - (2 * dt)  # 左ブランクはノート開始位置より2段手前
        oto.preutterance = 2 * dt  # 先行発声はノート開始位置
        oto.consonant = min(3 * dt, length + 2 * dt)  # 子音部固定範囲は先行発声より1段後ろか終端
        oto.cutoff = -(length + 2 * dt)  # 右ブランクはノート終端、負で左ブランク相対時刻、正で絶対時刻

        # 1音素のときはノート開始位置に先行発声を配置
        if len(phonemes) == 1:
            oto.overlap = 0

        # 2,3音素の時はノート開始位置に先行発声、その手前にオーバーラップ
        elif len(phonemes) in (2, 3):
            oto.overlap = dt

        # 4音素以上には未対応。特殊音素と判断して1音素として処理
        else:
            print('\n[WARN] when setting alias : phonemes = {}-------------'.
                  format(phonemes))
            print('1エイリアスあたり 1, 2, 3 音素しか対応していません。')
            oto.alias = ''.join(phonemes)
            oto.overlap = 0

        otoini.append(oto)
        t += length  # 今のノート終了位置が次のノート開始位置

    # 最初が休符なことを想定して、
    otoini[0].offset = 0  # 最初の左ブランクを0にする
    otoini[0].overlap = 0  # 最初のオーバーラップを0にする
    otoini[0].preutterance = 0  # 最初の先行発声を0にする
    otoini[0].cutoff2 -= 2 * dt
    return otoini