docstr: This script computes the SDR and SI-SNR metrics and saves
  them into a csv file
docstr_tok: ["This","script","computes","the","SDR","and","SI-SNR","metrics","and","saves","them","into","a","csv","file"]
code: def save_results(self, test_data):
      """This script computes the SDR and SI-SNR metrics and saves
      them into a csv file"""
  
      # Create folders where to store audio
      save_file = os.path.join(
          self.hparams.output_folder, "test_results.csv"
      )
  
      # Variable init
      all_snrs = []
      all_snrs_i = []
      all_delta_ITDs = []
      all_delta_ILDs = []
      csv_columns = ["snt_id", "snr", "snr_i", "delta_ITD", "delta_ILD"]
  
      test_loader = sb.dataio.dataloader.make_dataloader(
          test_data, **self.hparams.dataloader_opts
      )
  
      with open(save_file, "w") as results_csv:
          writer = csv.DictWriter(results_csv, fieldnames=csv_columns)
          writer.writeheader()
  
          # Loop over all test sentence
          with tqdm(test_loader, dynamic_ncols=True) as t:
              for i, batch in enumerate(t):
                  # Apply Separation
                  mixture, mix_len = batch.mix_sig
                  snt_id = batch.id
                  targets = [batch.s1_sig, batch.s2_sig]
                  if self.hparams.num_spks == 3:
                      targets.append(batch.s3_sig)
  
                  with torch.no_grad():
                      predictions, targets = self.compute_forward(
                          batch.mix_sig, targets, sb.Stage.TEST
                      )
  
                  # Compute SNR
                  snr = self.compute_objectives(predictions, targets)
  
                  # Compute SNR improvement
                  mixture_signal = torch.stack(
                      [mixture] * self.hparams.num_spks, dim=-1
                  )
                  mixture_signal = mixture_signal.to(targets.device)
                  snr_baseline = self.compute_objectives(
                      mixture_signal, targets
                  )
                  snr_i = snr - snr_baseline
  
                  # Compute ITD and ILD
                  delta_ITD, delta_ILD = self.cal_interaural_error(
                      predictions, targets
                  )
  
                  # Saving on a csv file
                  row = {
                      "snt_id": snt_id[0],
                      "snr": -snr.item(),
                      "snr_i": -snr_i.item(),
                      "delta_ITD": delta_ITD,
                      "delta_ILD": delta_ILD,
                  }
                  writer.writerow(row)
  
                  # Metric Accumulation
                  all_snrs.append(-snr.item())
                  all_snrs_i.append(-snr_i.item())
                  all_delta_ITDs.append(delta_ITD)
                  all_delta_ILDs.append(delta_ILD)
  
              row = {
                  "snt_id": "avg",
                  "snr": np.array(all_snrs).mean(),
                  "snr_i": np.array(all_snrs_i).mean(),
                  "delta_ITD": np.array(all_delta_ITDs).mean(),
                  "delta_ILD": np.array(all_delta_ILDs).mean(),
              }
              writer.writerow(row)
  
      logger.info("Mean SNR is {}".format(np.array(all_snrs).mean()))
      logger.info("Mean SNRi is {}".format(np.array(all_snrs_i).mean()))
      logger.info(
          "Mean Delta ITD is {}".format(np.array(all_delta_ITDs).mean())
      )
      logger.info(
          "Mean Delta ILD is {}".format(np.array(all_delta_ILDs).mean())
      )
  
imports: import os
  import sys
  import torch
  import torch.nn.functional
  import torchaudio
  import speechbrain
  import speechbrain.nnet.schedulers
  from speechbrain.utils.distributed import run_on_main
  from hyperpyyaml import load_hyperpyyaml
  import numpy
  from tqdm import tqdm
  import csv
  import logging
  from pyroomacoustics.experimental.localization import tdoa
  from speechbrain.processing.features import STFT, spectral_magnitude
  from torch.nn import Conv1d
  from speechbrain.core import AMPConfig
label_desc: Use image node_id 10 for calling the Separation obj's underlying member method code with example usage: obj.save_results(test_data) without return types