code: def get_phoneme_durations(
      data: Dict,
      original_text: str,
      fs: int,
      hop_size: int,
      n_samples: int,
  ):
      """Get phoneme durations."""
      orig_text = original_text.replace(" ", "").rstrip()
      text_pos = 0
      maxTimestamp = data["end"]
      words = [x for x in data["tiers"]["words"]["entries"]]
      phones = (x for x in data["tiers"]["phones"]["entries"])
      word_end = 0.0
      time2punc = {}
      phrase_words = []
      for word in words:
          start, end, label = word
          if start == word_end:
              phrase_words.append(label)
          else:
              # find punctuation at end of previous phrase
              phrase = "".join(phrase_words)
              for letter in phrase:
                  char = orig_text[text_pos]
                  while char != letter:
                      text_pos += 1
                      char = orig_text[text_pos]
                  text_pos += 1
  
              timing = (word_end, start)
              puncs = []
              while text_pos < len(orig_text):
                  char = orig_text[text_pos]
                  if char.isalpha() or char == "'":
                      break
                  else:
                      puncs.append(char)
                      text_pos += 1
              time2punc[timing] = puncs if puncs else ["sil"]
  
              phrase_words = [label]
          word_end = end
  
      # We preserve the start/end timings and not interval lengths
      #   due to rounding errors when converted to frames.
      timings = [0.0]
      new_phones = []
      prev_end = 0.0
      for phone in phones:
          start, end, label = phone
          if start > prev_end:
              # insert punctuation
              try:
                  puncs = time2punc[(prev_end, start)]
              except KeyError:
                  # In some cases MFA word segmentation fails
                  #   and there is a pause inside the word.
                  puncs = ["sil"]
              new_phones.extend(puncs)
              num_puncs = len(puncs)
              pause_time = (start - prev_end) / num_puncs
              for i in range(1, len(puncs) + 1):
                  timings.append(prev_end + pause_time * i)
  
          new_phones.append(label)
          timings.append(end)
          prev_end = end
  
      # Add end-of-utterance punctuations
      if word_end < maxTimestamp:
          text_pos = len(orig_text) - 1
          while orig_text[text_pos] in punctuation:
              text_pos -= 1
          puncs = orig_text[text_pos + 1 :]
          if not puncs:
              puncs = ["sil"]
          new_phones.extend(puncs)
          num_puncs = len(puncs)
          pause_time = (maxTimestamp - word_end) / num_puncs
          for i in range(1, len(puncs) + 1):
              timings.append(prev_end + pause_time * i)
  
      assert len(new_phones) + 1 == len(timings)
  
      # Should use same frame formulation for both
      # STFT frames calculation: https://github.com/librosa/librosa/issues/1288
      # centered stft
  
      total_durations = int(n_samples / hop_size) + 1
      timing_frames = [
          int(timing * fs / hop_size) + 1 for timing in timings
      ]
      durations = [
          timing_frames[i + 1] - timing_frames[i]
          for i in range(len(timing_frames) - 1)
      ]
  
      sum_durations = sum(durations)
      if sum_durations < total_durations:
          missing = total_durations - sum_durations
          durations[-1] += missing
      assert sum(durations) == total_durations
      return new_phones, durations
  
imports: import argparse
  import codecs
  import json
  import logging
  import os
  import re
  import sys
  import traceback
  from pathlib import Path
  from typing import Dict
  import kaldiio
  import soundfile
  from pyopenjtalk import run_frontend
  from espnet2.text.phoneme_tokenizer import PhonemeTokenizer
label_desc: Use image node_id 4 for calling a global function with example usage: get_phoneme_durations(data, original_text, fs, hop_size, n_samples) and returns: new_phones,  durations