/* GstRtpDtmfDepay
 *
 * Copyright (C) 2008 Collabora Limited
 * Copyright (C) 2008 Nokia Corporation
 *   Contact: Youness Alaoui <youness.alaoui@collabora.co.uk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
/**
 * SECTION:element-rtpdtmfdepay
 * @see_also: rtpdtmfsrc, rtpdtmfmux
 *
 * This element takes RTP DTMF packets and produces sound. It also emits a
 * message on the #GstBus.
 *
 * The message is called "dtmf-event" and has the following fields
 * <informaltable>
 * <tgroup cols='4'>
 * <colspec colname='Name' />
 * <colspec colname='Type' />
 * <colspec colname='Possible values' />
 * <colspec colname='Purpose' />
 * <thead>
 * <row>
 * <entry>Name</entry>
 * <entry>GType</entry>
 * <entry>Possible values</entry>
 * <entry>Purpose</entry>
 * </row>
 * </thead>
 * <tbody>
 * <row>
 * <entry>type</entry>
 * <entry>G_TYPE_INT</entry>
 * <entry>0-1</entry>
 * <entry>Which of the two methods
 * specified in RFC 2833 to use. The value should be 0 for tones and 1 for
 * named events. Tones are specified by their frequencies and events are specied
 * by their number. This element currently only recognizes events.
 * Do not confuse with "method" which specified the output.
 * </entry>
 * </row>
 * <row>
 * <entry>number</entry>
 * <entry>G_TYPE_INT</entry>
 * <entry>0-16</entry>
 * <entry>The event number.</entry>
 * </row>
 * <row>
 * <entry>volume</entry>
 * <entry>G_TYPE_INT</entry>
 * <entry>0-36</entry>
 * <entry>This field describes the power level of the tone, expressed in dBm0
 * after dropping the sign. Power levels range from 0 to -63 dBm0. The range of
 * valid DTMF is from 0 to -36 dBm0.
 * </entry>
 * </row>
 * <row>
 * <entry>method</entry>
 * <entry>G_TYPE_INT</entry>
 * <entry>1</entry>
 * <entry>This field will always been 1 (ie RTP event) from this element.
 * </entry>
 * </row>
 * </tbody>
 * </tgroup>
 * </informaltable>
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "gstrtpdtmfdepay.h"

#include <string.h>
#include <math.h>

#include <gst/audio/audio.h>
#include <gst/rtp/gstrtpbuffer.h>

#define DEFAULT_PACKET_INTERVAL  50     /* ms */
#define MIN_PACKET_INTERVAL      10     /* ms */
#define MAX_PACKET_INTERVAL      50     /* ms */
#define SAMPLE_RATE              8000
#define SAMPLE_SIZE              16
#define CHANNELS                 1
#define MIN_DUTY_CYCLE           (MIN_INTER_DIGIT_INTERVAL + MIN_PULSE_DURATION)

#define MIN_UNIT_TIME            0
#define MAX_UNIT_TIME            1000
#define DEFAULT_UNIT_TIME        0

#define DEFAULT_MAX_DURATION     0

typedef struct st_dtmf_key
{
  float low_frequency;
  float high_frequency;
} DTMF_KEY;

static const DTMF_KEY DTMF_KEYS[] = {
  {941, 1336},
  {697, 1209},
  {697, 1336},
  {697, 1477},
  {770, 1209},
  {770, 1336},
  {770, 1477},
  {852, 1209},
  {852, 1336},
  {852, 1477},
  {941, 1209},
  {941, 1477},
  {697, 1633},
  {770, 1633},
  {852, 1633},
  {941, 1633},
};

#define MAX_DTMF_EVENTS 16

enum
{
  DTMF_KEY_EVENT_1 = 1,
  DTMF_KEY_EVENT_2 = 2,
  DTMF_KEY_EVENT_3 = 3,
  DTMF_KEY_EVENT_4 = 4,
  DTMF_KEY_EVENT_5 = 5,
  DTMF_KEY_EVENT_6 = 6,
  DTMF_KEY_EVENT_7 = 7,
  DTMF_KEY_EVENT_8 = 8,
  DTMF_KEY_EVENT_9 = 9,
  DTMF_KEY_EVENT_0 = 0,
  DTMF_KEY_EVENT_STAR = 10,
  DTMF_KEY_EVENT_POUND = 11,
  DTMF_KEY_EVENT_A = 12,
  DTMF_KEY_EVENT_B = 13,
  DTMF_KEY_EVENT_C = 14,
  DTMF_KEY_EVENT_D = 15,
};

GST_DEBUG_CATEGORY_STATIC (gst_rtp_dtmf_depay_debug);
#define GST_CAT_DEFAULT gst_rtp_dtmf_depay_debug

enum
{
  /* FILL ME */
  LAST_SIGNAL
};

enum
{
  PROP_0,
  PROP_UNIT_TIME,
  PROP_MAX_DURATION
};

static GstStaticPadTemplate gst_rtp_dtmf_depay_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-raw, "
        "format = (string) \"" GST_AUDIO_NE (S16) "\", "
        "rate = " GST_AUDIO_RATE_RANGE ", " "channels = (int) 1")
    );

static GstStaticPadTemplate gst_rtp_dtmf_depay_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-rtp, "
        "media = (string) \"audio\", "
        "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
        "clock-rate = (int) [ 0, MAX ], "
        "encoding-name = (string) \"TELEPHONE-EVENT\"")
    );

G_DEFINE_TYPE (GstRtpDTMFDepay, gst_rtp_dtmf_depay,
    GST_TYPE_RTP_BASE_DEPAYLOAD);

static void gst_rtp_dtmf_depay_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_rtp_dtmf_depay_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static GstBuffer *gst_rtp_dtmf_depay_process (GstRTPBaseDepayload * depayload,
    GstBuffer * buf);
gboolean gst_rtp_dtmf_depay_setcaps (GstRTPBaseDepayload * filter,
    GstCaps * caps);

static void
gst_rtp_dtmf_depay_class_init (GstRtpDTMFDepayClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstRTPBaseDepayloadClass *gstrtpbasedepayload_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gstelement_class = GST_ELEMENT_CLASS (klass);
  gstrtpbasedepayload_class = GST_RTP_BASE_DEPAYLOAD_CLASS (klass);

  gst_element_class_add_static_pad_template (gstelement_class,
      &gst_rtp_dtmf_depay_src_template);
  gst_element_class_add_static_pad_template (gstelement_class,
      &gst_rtp_dtmf_depay_sink_template);

  GST_DEBUG_CATEGORY_INIT (gst_rtp_dtmf_depay_debug,
      "rtpdtmfdepay", 0, "rtpdtmfdepay element");
  gst_element_class_set_static_metadata (gstelement_class,
      "RTP DTMF packet depayloader", "Codec/Depayloader/Network",
      "Generates DTMF Sound from telephone-event RTP packets",
      "Youness Alaoui <youness.alaoui@collabora.co.uk>");

  gobject_class->set_property =
      GST_DEBUG_FUNCPTR (gst_rtp_dtmf_depay_set_property);
  gobject_class->get_property =
      GST_DEBUG_FUNCPTR (gst_rtp_dtmf_depay_get_property);

  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_UNIT_TIME,
      g_param_spec_uint ("unit-time", "Duration unittime",
          "The smallest unit (ms) the duration must be a multiple of (0 disables it)",
          MIN_UNIT_TIME, MAX_UNIT_TIME, DEFAULT_UNIT_TIME,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MAX_DURATION,
      g_param_spec_uint ("max-duration", "Maximum duration",
          "The maxumimum duration (ms) of the outgoing soundpacket. "
          "(0 = no limit)", 0, G_MAXUINT, DEFAULT_MAX_DURATION,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gstrtpbasedepayload_class->process =
      GST_DEBUG_FUNCPTR (gst_rtp_dtmf_depay_process);
  gstrtpbasedepayload_class->set_caps =
      GST_DEBUG_FUNCPTR (gst_rtp_dtmf_depay_setcaps);

}

static void
gst_rtp_dtmf_depay_init (GstRtpDTMFDepay * rtpdtmfdepay)
{
  rtpdtmfdepay->unit_time = DEFAULT_UNIT_TIME;
}

static void
gst_rtp_dtmf_depay_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstRtpDTMFDepay *rtpdtmfdepay;

  rtpdtmfdepay = GST_RTP_DTMF_DEPAY (object);

  switch (prop_id) {
    case PROP_UNIT_TIME:
      rtpdtmfdepay->unit_time = g_value_get_uint (value);
      break;
    case PROP_MAX_DURATION:
      rtpdtmfdepay->max_duration = g_value_get_uint (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_rtp_dtmf_depay_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstRtpDTMFDepay *rtpdtmfdepay;

  rtpdtmfdepay = GST_RTP_DTMF_DEPAY (object);

  switch (prop_id) {
    case PROP_UNIT_TIME:
      g_value_set_uint (value, rtpdtmfdepay->unit_time);
      break;
    case PROP_MAX_DURATION:
      g_value_set_uint (value, rtpdtmfdepay->max_duration);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

gboolean
gst_rtp_dtmf_depay_setcaps (GstRTPBaseDepayload * filter, GstCaps * caps)
{
  GstCaps *filtercaps, *srccaps;
  GstStructure *structure = gst_caps_get_structure (caps, 0);
  gint clock_rate = 8000;       /* default */

  gst_structure_get_int (structure, "clock-rate", &clock_rate);
  filter->clock_rate = clock_rate;

  filtercaps =
      gst_pad_get_pad_template_caps (GST_RTP_BASE_DEPAYLOAD_SRCPAD (filter));

  filtercaps = gst_caps_make_writable (filtercaps);
  gst_caps_set_simple (filtercaps, "rate", G_TYPE_INT, clock_rate, NULL);

  srccaps = gst_pad_peer_query_caps (GST_RTP_BASE_DEPAYLOAD_SRCPAD (filter),
      filtercaps);
  gst_caps_unref (filtercaps);

  gst_pad_set_caps (GST_RTP_BASE_DEPAYLOAD_SRCPAD (filter), srccaps);
  gst_caps_unref (srccaps);

  return TRUE;
}

static GstBuffer *
gst_dtmf_src_generate_tone (GstRtpDTMFDepay * rtpdtmfdepay,
    GstRTPDTMFPayload payload)
{
  GstBuffer *buf;
  GstMapInfo map;
  gint16 *p;
  gint tone_size;
  double i = 0;
  double amplitude, f1, f2;
  double volume_factor;
  DTMF_KEY key = DTMF_KEYS[payload.event];
  guint32 clock_rate;
  GstRTPBaseDepayload *depayload = GST_RTP_BASE_DEPAYLOAD (rtpdtmfdepay);
  gint volume;
  static GstAllocationParams params = { 0, 1, 0, 0, };

  clock_rate = depayload->clock_rate;

  /* Create a buffer for the tone */
  tone_size = (payload.duration * SAMPLE_SIZE * CHANNELS) / 8;
  buf = gst_buffer_new_allocate (NULL, tone_size, &params);
  GST_BUFFER_DURATION (buf) = payload.duration * GST_SECOND / clock_rate;
  volume = payload.volume;

  gst_buffer_map (buf, &map, GST_MAP_WRITE);
  p = (gint16 *) map.data;

  volume_factor = pow (10, (-volume) / 20);

  /*
   * For each sample point we calculate 'x' as the
   * the amplitude value.
   */
  for (i = 0; i < (tone_size / (SAMPLE_SIZE / 8)); i++) {
    /*
     * We add the fundamental frequencies together.
     */
    f1 = sin (2 * M_PI * key.low_frequency * (rtpdtmfdepay->sample /
            clock_rate));
    f2 = sin (2 * M_PI * key.high_frequency * (rtpdtmfdepay->sample /
            clock_rate));

    amplitude = (f1 + f2) / 2;

    /* Adjust the volume */
    amplitude *= volume_factor;

    /* Make the [-1:1] interval into a [-32767:32767] interval */
    amplitude *= 32767;

    /* Store it in the data buffer */
    *(p++) = (gint16) amplitude;

    (rtpdtmfdepay->sample)++;
  }

  gst_buffer_unmap (buf, &map);

  return buf;
}


static GstBuffer *
gst_rtp_dtmf_depay_process (GstRTPBaseDepayload * depayload, GstBuffer * buf)
{

  GstRtpDTMFDepay *rtpdtmfdepay = NULL;
  GstBuffer *outbuf = NULL;
  gint payload_len;
  guint8 *payload = NULL;
  guint32 timestamp;
  GstRTPDTMFPayload dtmf_payload;
  gboolean marker;
  GstStructure *structure = NULL;
  GstMessage *dtmf_message = NULL;
  GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;

  rtpdtmfdepay = GST_RTP_DTMF_DEPAY (depayload);

  gst_rtp_buffer_map (buf, GST_MAP_READ, &rtpbuffer);

  payload_len = gst_rtp_buffer_get_payload_len (&rtpbuffer);
  payload = gst_rtp_buffer_get_payload (&rtpbuffer);

  if (payload_len != sizeof (GstRTPDTMFPayload))
    goto bad_packet;

  memcpy (&dtmf_payload, payload, sizeof (GstRTPDTMFPayload));

  if (dtmf_payload.event > MAX_EVENT)
    goto bad_packet;

  marker = gst_rtp_buffer_get_marker (&rtpbuffer);

  timestamp = gst_rtp_buffer_get_timestamp (&rtpbuffer);

  dtmf_payload.duration = g_ntohs (dtmf_payload.duration);

  /* clip to whole units of unit_time */
  if (rtpdtmfdepay->unit_time) {
    guint unit_time_clock =
        (rtpdtmfdepay->unit_time * depayload->clock_rate) / 1000;
    if (dtmf_payload.duration % unit_time_clock) {
      /* Make sure we don't overflow the duration */
      if (dtmf_payload.duration < G_MAXUINT16 - unit_time_clock)
        dtmf_payload.duration += unit_time_clock -
            (dtmf_payload.duration % unit_time_clock);
      else
        dtmf_payload.duration -= dtmf_payload.duration % unit_time_clock;
    }
  }

  /* clip to max duration */
  if (rtpdtmfdepay->max_duration) {
    guint max_duration_clock =
        (rtpdtmfdepay->max_duration * depayload->clock_rate) / 1000;

    if (max_duration_clock < G_MAXUINT16 &&
        dtmf_payload.duration > max_duration_clock)
      dtmf_payload.duration = max_duration_clock;
  }

  GST_DEBUG_OBJECT (depayload, "Received new RTP DTMF packet : "
      "marker=%d - timestamp=%u - event=%d - duration=%d",
      marker, timestamp, dtmf_payload.event, dtmf_payload.duration);

  GST_DEBUG_OBJECT (depayload,
      "Previous information : timestamp=%u - duration=%d",
      rtpdtmfdepay->previous_ts, rtpdtmfdepay->previous_duration);

  /* First packet */
  if (marker || rtpdtmfdepay->previous_ts != timestamp) {
    rtpdtmfdepay->sample = 0;
    rtpdtmfdepay->previous_ts = timestamp;
    rtpdtmfdepay->previous_duration = dtmf_payload.duration;
    rtpdtmfdepay->first_gst_ts = GST_BUFFER_PTS (buf);

    structure = gst_structure_new ("dtmf-event",
        "number", G_TYPE_INT, dtmf_payload.event,
        "volume", G_TYPE_INT, dtmf_payload.volume,
        "type", G_TYPE_INT, 1, "method", G_TYPE_INT, 1, NULL);
    if (structure) {
      dtmf_message =
          gst_message_new_element (GST_OBJECT (depayload), structure);
      if (dtmf_message) {
        if (!gst_element_post_message (GST_ELEMENT (depayload), dtmf_message)) {
          GST_ERROR_OBJECT (depayload,
              "Unable to send dtmf-event message to bus");
        }
      } else {
        GST_ERROR_OBJECT (depayload, "Unable to create dtmf-event message");
      }
    } else {
      GST_ERROR_OBJECT (depayload, "Unable to create dtmf-event structure");
    }
  } else {
    guint16 duration = dtmf_payload.duration;
    dtmf_payload.duration -= rtpdtmfdepay->previous_duration;
    /* If late buffer, ignore */
    if (duration > rtpdtmfdepay->previous_duration)
      rtpdtmfdepay->previous_duration = duration;
  }

  GST_DEBUG_OBJECT (depayload, "new previous duration : %d - new duration : %d"
      " - diff  : %d - clock rate : %d - timestamp : %" G_GUINT64_FORMAT,
      rtpdtmfdepay->previous_duration, dtmf_payload.duration,
      (rtpdtmfdepay->previous_duration - dtmf_payload.duration),
      depayload->clock_rate, GST_BUFFER_TIMESTAMP (buf));

  /* If late or duplicate packet (like the redundant end packet). Ignore */
  if (dtmf_payload.duration > 0) {
    outbuf = gst_dtmf_src_generate_tone (rtpdtmfdepay, dtmf_payload);


    GST_BUFFER_PTS (outbuf) = rtpdtmfdepay->first_gst_ts +
        (rtpdtmfdepay->previous_duration - dtmf_payload.duration) *
        GST_SECOND / depayload->clock_rate;
    GST_BUFFER_OFFSET (outbuf) =
        (rtpdtmfdepay->previous_duration - dtmf_payload.duration) *
        GST_SECOND / depayload->clock_rate;
    GST_BUFFER_OFFSET_END (outbuf) = rtpdtmfdepay->previous_duration *
        GST_SECOND / depayload->clock_rate;

    GST_DEBUG_OBJECT (depayload,
        "timestamp : %" G_GUINT64_FORMAT " - time %" GST_TIME_FORMAT,
        GST_BUFFER_TIMESTAMP (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));

  }

  gst_rtp_buffer_unmap (&rtpbuffer);

  return outbuf;

bad_packet:
  GST_ELEMENT_WARNING (rtpdtmfdepay, STREAM, DECODE,
      ("Packet did not validate"), (NULL));

  if (rtpbuffer.buffer != NULL)
    gst_rtp_buffer_unmap (&rtpbuffer);

  return NULL;
}

gboolean
gst_rtp_dtmf_depay_plugin_init (GstPlugin * plugin)
{
  return gst_element_register (plugin, "rtpdtmfdepay",
      GST_RANK_MARGINAL, GST_TYPE_RTP_DTMF_DEPAY);
}
