class_docstr: Emulating kaldi extract-segments.cc
  
      Args:
          segments (str): The file format is
              "<segment-id> <recording-id> <start-time> <end-time>
  "
              "e.g. call-861225-A-0050-0065 call-861225-A 5.0 6.5
  "
      
class_docstr_tok: ["Emulating","kaldi","extract-segments.cc","Args",":","segments","(","str",")",":","The","file","format","is","``","<","segment-id",">","<","recording-id",">","<","start-time",">","<","end-time",">","''","``","e.g",".","call-861225-A-0050-0065","call-861225-A","5.0","6.5","''"]
code: def generator(self):
      recodeid_counter = {}
      for utt, (recodeid, st, et) in self.segments_dict.items():
          recodeid_counter[recodeid] = (
              recodeid_counter.get(recodeid, 0) + 1
          )
  
      cached = {}
      for utt, (recodeid, st, et) in self.segments_dict.items():
          wavpath = self.wav_dict[recodeid]
          if recodeid not in cached:
              if wavpath.endswith("|"):
                  if self.multi_columns:
                      raise RuntimeError(
                          "Not supporting multi_columns wav.scp for inputs by pipe"
                      )
                  # Streaming input e.g. cat a.wav |
                  with kaldiio.open_like_kaldi(wavpath, "rb") as f:
                      with BytesIO(f.read()) as g:
                          array, rate = soundfile.read(g)
  
              else:
                  if self.multi_columns:
                      array, rate = soundfile_read(
                          wavs=wavpath.split(),
                          dtype=None,
                          always_2d=False,
                          concat_axis=1,
                      )
                  else:
                      array, rate = soundfile.read(wavpath)
              cached[recodeid] = array, rate
  
          array, rate = cached[recodeid]
          # Keep array until the last query
          recodeid_counter[recodeid] -= 1
          if recodeid_counter[recodeid] == 0:
              cached.pop(recodeid)
          # Convert starting time of the segment to corresponding sample number.
          # If end time is -1 then use the whole file starting from start time.
          if et != -1:
              array = array[int(st * rate) : int(et * rate)]
          else:
              array = array[int(st * rate) :]
  
          yield utt, (array, rate), None, None
  
imports: import argparse
  import logging
  from io import BytesIO
  from pathlib import Path
  from typing import Optional, Tuple
  import humanfriendly
  import kaldiio
  import numpy
  import resampy
  import soundfile
  from tqdm import tqdm
  from typeguard import check_argument_types
  from espnet2.fileio.read_text import read_2columns_text
  from espnet2.fileio.sound_scp import SoundScpWriter, soundfile_read
  from espnet2.fileio.vad_scp import VADScpReader
  from espnet2.utils.types import str2bool
  from espnet.utils.cli_utils import get_commandline_args
label_desc: Use image node_id 2 for calling the SegmentsExtractor obj's underlying member method code with example usage: obj.generator() without return types