text: #!/usr/bin/env python3
  # Copyright    2021  Xiaomi Corp.        (authors: Fangjun Kuang)
  #
  # See ../../../../LICENSE for clarification regarding multiple authors
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  
  """
  This file computes fbank features of the musan dataset.
  It looks for manifests in the directory data/manifests.
  
  The generated fbank features are saved in data/fbank.
  """
  
  import logging
  from pathlib import Path
  
  import torch
  from lhotse import CutSet, LilcomChunkyWriter, combine
  from lhotse.features.kaldifeat import (
      KaldifeatFbank,
      KaldifeatFbankConfig,
      KaldifeatFrameOptions,
      KaldifeatMelOptions,
  )
  from lhotse.recipes.utils import read_manifests_if_cached
  
  # Torch's multithreaded behavior needs to be disabled or
  # it wastes a lot of CPU and slow things down.
  # Do this outside of main() in case it needs to take effect
  # even when we are not invoking the main (e.g. when spawning subprocesses).
  torch.set_num_threads(1)
  torch.set_num_interop_threads(1)
  
  
  def compute_fbank_musan():
      src_dir = Path("data/manifests")
      output_dir = Path("data/fbank")
  
      sampling_rate = 16000
      num_mel_bins = 80
  
      extractor = KaldifeatFbank(
          KaldifeatFbankConfig(
              frame_opts=KaldifeatFrameOptions(sampling_rate=sampling_rate),
              mel_opts=KaldifeatMelOptions(num_bins=num_mel_bins),
              device="cuda",
          )
      )
  
      dataset_parts = (
          "music",
          "speech",
          "noise",
      )
      manifests = read_manifests_if_cached(
          dataset_parts=dataset_parts, output_dir=src_dir
      )
      assert manifests is not None
  
      musan_cuts_path = src_dir / "cuts_musan.jsonl.gz"
  
      if musan_cuts_path.is_file():
          logging.info(f"{musan_cuts_path} already exists - skipping")
          return
  
      logging.info("Extracting features for Musan")
  
      # create chunks of Musan with duration 5 - 10 seconds
      musan_cuts = (
          CutSet.from_manifests(
              recordings=combine(
                  part["recordings"] for part in manifests.values()
              )
          )
          .cut_into_windows(10.0)
          .filter(lambda c: c.duration > 5)
          .compute_and_store_features_batch(
              extractor=extractor,
              storage_path=output_dir / "feats_musan",
              batch_duration=500,
              num_workers=4,
              storage_type=LilcomChunkyWriter,
          )
      )
  
      logging.info(f"Saving to {musan_cuts_path}")
      musan_cuts.to_file(musan_cuts_path)
  
  
  if __name__ == "__main__":
      formatter = (
          "%(asctime)s %(levelname)s [%(filename)s:%(lineno)d] %(message)s"
      )
      logging.basicConfig(format=formatter, level=logging.INFO)
      compute_fbank_musan()
  