class_docstr: A class that enables online (streaming) clustering based diarization.
  
  - The instance created from `OnlineClusteringDiarizer` sets aside a certain amount of memory
    to provide the upcoming inference with history information
  
  - There are two major modules involved: `OnlineSegmentor` and `OnlineSpeakerClustering`.
      OnlineSegmentor: Take the VAD-timestamps and generate segments for each scale
      OnlineSpeakerClustering: Update the entire speaker labels of the given online session
                               while updating the speaker labels of the streaming inputs.
  
  - The overall diarization process is done by calling `diarize_step` function.
    `diarize_step` function goes through the following steps:
      (1) Segmentation (`OnlineSegmentor` class)
      (2) Embedding extraction (`_extract_online_embeddings` function call)
      (3) Online speaker counting and speaker clustering (`OnlineClusteringDiarizer` class)
      (4) Label generation (`generate_cluster_labels` function call)
docstr: Save the temporary input to the class memory buffer.
  
  - Clustering is done for (hist_N + curr_N) number of embeddings.
  - Thus, we need to remove the clustering results on the embedding memory.
  - If self.diar.history_buffer_seg_end is not None, that indicates streaming diarization system
    is starting to save embeddings to its memory. Thus, the new incoming clustering label should be separated.
  - If `is_online = True`, old embeddings outside the window are removed to save GPU memory.
  
  Args:
      scale_idx (int):
          Scale index in integer
      total_cluster_labels (Tensor):
          The speaker labels from the beginning of the session to the current position
      is_online (bool)
          Boolean variable that indicates whether the system is currently in online mode or not
  
  Returns:
      cluster_label_hyp (Tensor):
          Majority voted speaker labels over multiple inferences
docstr_tok: ["Save","the","temporary","input","to","the","class","memory","buffer",".","-","Clustering","is","done","for","(","hist_N","+","curr_N",")","number","of","embeddings",".","-","Thus",",","we","need","to","remove","the","clustering","results","on","the","embedding","memory",".","-","If","self.diar.history_buffer_seg_end","is","not","None",",","that","indicates","streaming","diarization","system","is","starting","to","save","embeddings","to","its","memory",".","Thus",",","the","new","incoming","clustering","label","should","be","separated",".","-","If","`","is_online","=","True","`",",","old","embeddings","outside","the","window","are","removed","to","save","GPU","memory",".","Args",":","scale_idx","(","int",")",":","Scale","index","in","integer","total_cluster_labels","(","Tensor",")",":","The","speaker","labels","from","the","beginning","of","the","session","to","the","current","position","is_online","(","bool",")","Boolean","variable","that","indicates","whether","the","system","is","currently","in","online","mode","or","not","Returns",":","cluster_label_hyp","(","Tensor",")",":","Majority","voted","speaker","labels","over","multiple","inferences"]
code: def save_history_data(
      self,
      scale_idx: int,
      total_cluster_labels: torch.Tensor,
      is_online: bool,
  ) -> torch.Tensor:
      """
      Save the temporary input to the class memory buffer.
  
      - Clustering is done for (hist_N + curr_N) number of embeddings.
      - Thus, we need to remove the clustering results on the embedding memory.
      - If self.diar.history_buffer_seg_end is not None, that indicates streaming diarization system
        is starting to save embeddings to its memory. Thus, the new incoming clustering label should be separated.
      - If `is_online = True`, old embeddings outside the window are removed to save GPU memory.
  
      Args:
          scale_idx (int):
              Scale index in integer
          total_cluster_labels (Tensor):
              The speaker labels from the beginning of the session to the current position
          is_online (bool)
              Boolean variable that indicates whether the system is currently in online mode or not
  
      Returns:
          cluster_label_hyp (Tensor):
              Majority voted speaker labels over multiple inferences
      """
      total_cluster_labels = total_cluster_labels.tolist()
  
      if not is_online:
          self.memory_segment_ranges[scale_idx] = deepcopy(
              self.segment_range_ts[scale_idx]
          )
          self.memory_segment_indexes[scale_idx] = deepcopy(
              self.segment_indexes[scale_idx]
          )
          if scale_idx == self.base_scale_index:
              self.memory_cluster_labels = deepcopy(
                  total_cluster_labels
              )
  
      # Only if there are newly obtained embeddings, update ranges and embeddings.
      elif (
          self.segment_indexes[scale_idx][-1]
          > self.memory_segment_indexes[scale_idx][-1]
      ):
          # Get the global index of the first segment we want to keep in the buffer
          global_stt_idx = max(
              max(self.memory_segment_indexes[scale_idx])
              - self.memory_margin,
              0,
          )
  
          # Convert global index global_stt_idx to buffer index buffer_stt_idx
          segment_indexes_mat = torch.tensor(
              self.segment_indexes[scale_idx]
          )
          buffer_stt_idx = torch.where(
              segment_indexes_mat == global_stt_idx
          )[0][0]
          self.memory_segment_ranges[scale_idx][
              global_stt_idx:
          ] = deepcopy(
              self.segment_range_ts[scale_idx][buffer_stt_idx:]
          )
          self.memory_segment_indexes[scale_idx][
              global_stt_idx:
          ] = deepcopy(self.segment_indexes[scale_idx][buffer_stt_idx:])
          if scale_idx == self.base_scale_index:
              self.memory_cluster_labels[global_stt_idx:] = deepcopy(
                  total_cluster_labels[global_stt_idx:]
              )
              if len(self.memory_cluster_labels) != len(
                  self.memory_segment_ranges[scale_idx]
              ):
                  raise ValueError(
                      "self.memory_cluster_labels and self.memory_segment_ranges should always have the same length, "
                      f"but they have {len(self.memory_cluster_labels)} and {len(self.memory_segment_ranges[scale_idx])}."
                  )
  
          # Remove unnecessary old values
          self._clear_memory(scale_idx)
  
      if not (
          len(self.emb_vectors[scale_idx])
          == len(self.segment_raw_audio[scale_idx])
          == len(self.segment_indexes[scale_idx])
          == len(self.segment_range_ts[scale_idx])
      ):
          raise ValueError(
              "self.emb_vectors, self.segment_raw_audio, self.segment_indexes, and self.segment_range_ts "
              "should always have the same length, "
              f"but they have {len(self.emb_vectors[scale_idx])}, {len(self.segment_raw_audio[scale_idx])}, "
              f"{len(self.segment_indexes[scale_idx])}, and {len(self.segment_range_ts[scale_idx])}, respectively."
          )
  
      if self.use_temporal_label_major_vote:
          cluster_label_hyp = self._temporal_label_major_vote()
      else:
          cluster_label_hyp = self.memory_cluster_labels
      return cluster_label_hyp
  
imports: import os
  import time
  from copy import deepcopy
  from typing import Dict
  import torch
  from omegaconf import DictConfig
  from nemo.collections.asr.models import ClusteringDiarizer
  from nemo.collections.asr.parts.utils.offline_clustering import get_scale_interpolated_embs, split_input_data
  from nemo.collections.asr.parts.utils.online_clustering import OnlineSpeakerClustering
  from nemo.collections.asr.parts.utils.speaker_utils import OnlineSegmentor, audio_rttm_map, generate_cluster_labels, get_embs_and_timestamps
  from nemo.utils import logging, model_utils
label_desc: Use image node_id 12 for calling the OnlineClusteringDiarizer obj's underlying member method code with example usage: obj.save_history_data(scale_idx, total_cluster_labels, is_online) and returns: cluster_label_hyp