# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS.  All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.

"""Extraction of annotations from audio files.
"""

from __future__ import division
import logging
import os
import shutil
import struct
import subprocess
import sys
import tempfile

try:
  import numpy as np
except ImportError:
  logging.critical('Cannot import the third-party Python package numpy')
  sys.exit(1)

from . import external_vad
from . import exceptions
from . import signal_processing


class AudioAnnotationsExtractor(object):
  """Extracts annotations from audio files.
  """

  # TODO(aleloi): change to enum.IntEnum when py 3.6 is available.
  class VadType(object):
    ENERGY_THRESHOLD = 1  # TODO(alessiob): Consider switching to P56 standard.
    WEBRTC_COMMON_AUDIO = 2  # common_audio/vad/include/vad.h
    WEBRTC_APM = 4  # modules/audio_processing/vad/vad.h

    def __init__(self, value):
      if (not isinstance(value, int)) or not 0 <= value <= 7:
        raise exceptions.InitializationException(
            'Invalid vad type: ' + value)
      self._value = value

    def Contains(self, vad_type):
      return self._value | vad_type == self._value

    def __str__(self):
      vads = []
      if self.Contains(self.ENERGY_THRESHOLD):
        vads.append("energy")
      if self.Contains(self.WEBRTC_COMMON_AUDIO):
        vads.append("common_audio")
      if self.Contains(self.WEBRTC_APM):
        vads.append("apm")
      return "VadType({})".format(", ".join(vads))

  _OUTPUT_FILENAME_TEMPLATE = '{}annotations.npz'

  # Level estimation params.
  _ONE_DB_REDUCTION = np.power(10.0, -1.0 / 20.0)
  _LEVEL_FRAME_SIZE_MS = 1.0
  # The time constants in ms indicate the time it takes for the level estimate
  # to go down/up by 1 db if the signal is zero.
  _LEVEL_ATTACK_MS = 5.0
  _LEVEL_DECAY_MS = 20.0

  # VAD params.
  _VAD_THRESHOLD = 1
  _VAD_WEBRTC_PATH = os.path.join(os.path.dirname(
      os.path.abspath(__file__)), os.pardir, os.pardir)
  _VAD_WEBRTC_COMMON_AUDIO_PATH = os.path.join(_VAD_WEBRTC_PATH, 'vad')

  _VAD_WEBRTC_APM_PATH = os.path.join(
      _VAD_WEBRTC_PATH, 'apm_vad')

  def __init__(self, vad_type, external_vads=None):
    self._signal = None
    self._level = None
    self._level_frame_size = None
    self._common_audio_vad = None
    self._energy_vad = None
    self._apm_vad_probs = None
    self._apm_vad_rms = None
    self._vad_frame_size = None
    self._vad_frame_size_ms = None
    self._c_attack = None
    self._c_decay = None

    self._vad_type = self.VadType(vad_type)
    logging.info('VADs used for annotations: ' + str(self._vad_type))

    if external_vads is None:
      external_vads = {}
    self._external_vads = external_vads

    assert len(self._external_vads) == len(external_vads), (
        'The external VAD names must be unique.')
    for vad in external_vads.values():
      if not isinstance(vad, external_vad.ExternalVad):
        raise exceptions.InitializationException(
            'Invalid vad type: ' + str(type(vad)))
      logging.info('External VAD used for annotation: ' +
                   str(vad.name))

    assert os.path.exists(self._VAD_WEBRTC_COMMON_AUDIO_PATH), \
      self._VAD_WEBRTC_COMMON_AUDIO_PATH
    assert os.path.exists(self._VAD_WEBRTC_APM_PATH), \
      self._VAD_WEBRTC_APM_PATH

  @classmethod
  def GetOutputFileNameTemplate(cls):
    return cls._OUTPUT_FILENAME_TEMPLATE

  def GetLevel(self):
    return self._level

  def GetLevelFrameSize(self):
    return self._level_frame_size

  @classmethod
  def GetLevelFrameSizeMs(cls):
    return cls._LEVEL_FRAME_SIZE_MS

  def GetVadOutput(self, vad_type):
    if vad_type == self.VadType.ENERGY_THRESHOLD:
      return self._energy_vad
    elif vad_type == self.VadType.WEBRTC_COMMON_AUDIO:
      return self._common_audio_vad
    elif vad_type == self.VadType.WEBRTC_APM:
      return (self._apm_vad_probs, self._apm_vad_rms)
    else:
      raise exceptions.InitializationException(
            'Invalid vad type: ' + vad_type)

  def GetVadFrameSize(self):
    return self._vad_frame_size

  def GetVadFrameSizeMs(self):
    return self._vad_frame_size_ms

  def Extract(self, filepath):
    # Load signal.
    self._signal = signal_processing.SignalProcessingUtils.LoadWav(filepath)
    if self._signal.channels != 1:
      raise NotImplementedError('Multiple-channel annotations not implemented')

    # Level estimation params.
    self._level_frame_size = int(self._signal.frame_rate / 1000 * (
        self._LEVEL_FRAME_SIZE_MS))
    self._c_attack = 0.0 if self._LEVEL_ATTACK_MS == 0 else (
        self._ONE_DB_REDUCTION ** (
            self._LEVEL_FRAME_SIZE_MS / self._LEVEL_ATTACK_MS))
    self._c_decay = 0.0 if self._LEVEL_DECAY_MS == 0 else (
        self._ONE_DB_REDUCTION ** (
            self._LEVEL_FRAME_SIZE_MS / self._LEVEL_DECAY_MS))

    # Compute level.
    self._LevelEstimation()

    # Ideal VAD output, it requires clean speech with high SNR as input.
    if self._vad_type.Contains(self.VadType.ENERGY_THRESHOLD):
      # Naive VAD based on level thresholding.
      vad_threshold = np.percentile(self._level, self._VAD_THRESHOLD)
      self._energy_vad = np.uint8(self._level > vad_threshold)
      self._vad_frame_size = self._level_frame_size
      self._vad_frame_size_ms = self._LEVEL_FRAME_SIZE_MS
    if self._vad_type.Contains(self.VadType.WEBRTC_COMMON_AUDIO):
      # WebRTC common_audio/ VAD.
      self._RunWebRtcCommonAudioVad(filepath, self._signal.frame_rate)
    if self._vad_type.Contains(self.VadType.WEBRTC_APM):
      # WebRTC modules/audio_processing/ VAD.
      self._RunWebRtcApmVad(filepath)
    for extvad_name in self._external_vads:
      self._external_vads[extvad_name].Run(filepath)

  def Save(self, output_path, annotation_name=""):
    ext_kwargs = {'extvad_conf-' + ext_vad:
                  self._external_vads[ext_vad].GetVadOutput()
                  for ext_vad in self._external_vads}
    # pylint: disable=star-args
    np.savez_compressed(
        file=os.path.join(
            output_path,
            self.GetOutputFileNameTemplate().format(annotation_name)),
        level=self._level,
        level_frame_size=self._level_frame_size,
        level_frame_size_ms=self._LEVEL_FRAME_SIZE_MS,
        vad_output=self._common_audio_vad,
        vad_energy_output=self._energy_vad,
        vad_frame_size=self._vad_frame_size,
        vad_frame_size_ms=self._vad_frame_size_ms,
        vad_probs=self._apm_vad_probs,
        vad_rms=self._apm_vad_rms,
        **ext_kwargs
    )

  def _LevelEstimation(self):
    # Read samples.
    samples = signal_processing.SignalProcessingUtils.AudioSegmentToRawData(
        self._signal).astype(np.float32) / 32768.0
    num_frames = len(samples) // self._level_frame_size
    num_samples = num_frames * self._level_frame_size

    # Envelope.
    self._level = np.max(np.reshape(np.abs(samples[:num_samples]), (
        num_frames, self._level_frame_size)), axis=1)
    assert len(self._level) == num_frames

    # Envelope smoothing.
    smooth = lambda curr, prev, k: (1 - k) * curr  + k * prev
    self._level[0] = smooth(self._level[0], 0.0, self._c_attack)
    for i in range(1, num_frames):
      self._level[i] = smooth(
          self._level[i], self._level[i - 1], self._c_attack if (
              self._level[i] > self._level[i - 1]) else self._c_decay)

  def _RunWebRtcCommonAudioVad(self, wav_file_path, sample_rate):
    self._common_audio_vad = None
    self._vad_frame_size = None

    # Create temporary output path.
    tmp_path = tempfile.mkdtemp()
    output_file_path = os.path.join(
        tmp_path, os.path.split(wav_file_path)[1] + '_vad.tmp')

    # Call WebRTC VAD.
    try:
      subprocess.call([
          self._VAD_WEBRTC_COMMON_AUDIO_PATH,
          '-i', wav_file_path,
          '-o', output_file_path
      ], cwd=self._VAD_WEBRTC_PATH)

      # Read bytes.
      with open(output_file_path, 'rb') as f:
        raw_data = f.read()

      # Parse side information.
      self._vad_frame_size_ms = struct.unpack('B', raw_data[0])[0]
      self._vad_frame_size = self._vad_frame_size_ms * sample_rate / 1000
      assert self._vad_frame_size_ms in [10, 20, 30]
      extra_bits = struct.unpack('B', raw_data[-1])[0]
      assert 0 <= extra_bits <= 8

      # Init VAD vector.
      num_bytes = len(raw_data)
      num_frames = 8 * (num_bytes - 2) - extra_bits  # 8 frames for each byte.
      self._common_audio_vad = np.zeros(num_frames, np.uint8)

      # Read VAD decisions.
      for i, byte in enumerate(raw_data[1:-1]):
        byte = struct.unpack('B', byte)[0]
        for j in range(8 if i < num_bytes - 3 else (8 - extra_bits)):
          self._common_audio_vad[i * 8 + j] = int(byte & 1)
          byte = byte >> 1
    except Exception as e:
      logging.error('Error while running the WebRTC VAD (' + e.message + ')')
    finally:
      if os.path.exists(tmp_path):
        shutil.rmtree(tmp_path)

  def _RunWebRtcApmVad(self, wav_file_path):
    # Create temporary output path.
    tmp_path = tempfile.mkdtemp()
    output_file_path_probs = os.path.join(
        tmp_path, os.path.split(wav_file_path)[1] + '_vad_probs.tmp')
    output_file_path_rms = os.path.join(
        tmp_path, os.path.split(wav_file_path)[1] + '_vad_rms.tmp')

    # Call WebRTC VAD.
    try:
      subprocess.call([
          self._VAD_WEBRTC_APM_PATH,
          '-i', wav_file_path,
          '-o_probs', output_file_path_probs,
          '-o_rms', output_file_path_rms
      ], cwd=self._VAD_WEBRTC_PATH)

      # Parse annotations.
      self._apm_vad_probs = np.fromfile(output_file_path_probs, np.double)
      self._apm_vad_rms = np.fromfile(output_file_path_rms, np.double)
      assert len(self._apm_vad_rms) == len(self._apm_vad_probs)

    except Exception as e:
      logging.error('Error while running the WebRTC APM VAD (' +
                    e.message + ')')
    finally:
      if os.path.exists(tmp_path):
        shutil.rmtree(tmp_path)
