Home | History | Annotate | Download | only in neteq
      1 /*
      2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include "webrtc/modules/audio_coding/neteq/dtmf_buffer.h"
     12 
     13 #ifdef WIN32
     14 #include <winsock2.h>  // ntohl()
     15 #else
     16 #include <arpa/inet.h>  // ntohl()
     17 #endif
     18 
     19 #include <iostream>
     20 
     21 #include "testing/gtest/include/gtest/gtest.h"
     22 
     23 // Modify the tests so that they pass with the modifications done to DtmfBuffer
     24 // for backwards bit-exactness. Once bit-exactness is no longer required, this
     25 // #define should be removed (and the code that it enables).
     26 #define LEGACY_BITEXACT
     27 
     28 namespace webrtc {
     29 
     30 static int sample_rate_hz = 8000;
     31 
     32 static uint32_t MakeDtmfPayload(int event, bool end, int volume, int duration) {
     33   uint32_t payload = 0;
     34 //  0                   1                   2                   3
     35 //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     36 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     37 // |     event     |E|R| volume    |          duration             |
     38 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     39   payload |= (event & 0x00FF) << 24;
     40   payload |= (end ? 0x00800000 : 0x00000000);
     41   payload |= (volume & 0x003F) << 16;
     42   payload |= (duration & 0xFFFF);
     43   payload = ntohl(payload);
     44   return payload;
     45 }
     46 
     47 static bool EqualEvents(const DtmfEvent& a,
     48                         const DtmfEvent& b) {
     49   return (a.duration == b.duration
     50       && a.end_bit == b.end_bit
     51       && a.event_no == b.event_no
     52       && a.timestamp == b.timestamp
     53       && a.volume == b.volume);
     54 }
     55 
     56 TEST(DtmfBuffer, CreateAndDestroy) {
     57   DtmfBuffer* buffer = new DtmfBuffer(sample_rate_hz);
     58   delete buffer;
     59 }
     60 
     61 // Test the event parser.
     62 TEST(DtmfBuffer, ParseEvent) {
     63   int event_no = 7;
     64   bool end_bit = true;
     65   int volume = 17;
     66   int duration = 4711;
     67   uint32_t timestamp = 0x12345678;
     68   uint32_t payload = MakeDtmfPayload(event_no, end_bit, volume, duration);
     69   uint8_t* payload_ptr = reinterpret_cast<uint8_t*>(&payload);
     70   DtmfEvent event;
     71   EXPECT_EQ(DtmfBuffer::kOK,
     72             DtmfBuffer::ParseEvent(timestamp, payload_ptr, sizeof(payload),
     73                                    &event));
     74   EXPECT_EQ(duration, event.duration);
     75   EXPECT_EQ(end_bit, event.end_bit);
     76   EXPECT_EQ(event_no, event.event_no);
     77   EXPECT_EQ(timestamp, event.timestamp);
     78   EXPECT_EQ(volume, event.volume);
     79 
     80   EXPECT_EQ(DtmfBuffer::kInvalidPointer,
     81             DtmfBuffer::ParseEvent(timestamp, NULL, 4, &event));
     82 
     83   EXPECT_EQ(DtmfBuffer::kInvalidPointer,
     84             DtmfBuffer::ParseEvent(timestamp, payload_ptr, 4, NULL));
     85 
     86   EXPECT_EQ(DtmfBuffer::kPayloadTooShort,
     87             DtmfBuffer::ParseEvent(timestamp, payload_ptr, 3, &event));
     88 }
     89 
     90 TEST(DtmfBuffer, SimpleInsertAndGet) {
     91   int event_no = 7;
     92   bool end_bit = true;
     93   int volume = 17;
     94   int duration = 4711;
     95   uint32_t timestamp = 0x12345678;
     96   DtmfEvent event(timestamp, event_no, volume, duration, end_bit);
     97   DtmfBuffer buffer(sample_rate_hz);
     98   EXPECT_EQ(DtmfBuffer::kOK, buffer.InsertEvent(event));
     99   EXPECT_EQ(1u, buffer.Length());
    100   EXPECT_FALSE(buffer.Empty());
    101   DtmfEvent out_event;
    102   // Too early to get event.
    103   EXPECT_FALSE(buffer.GetEvent(timestamp - 10, &out_event));
    104   EXPECT_EQ(1u, buffer.Length());
    105   EXPECT_FALSE(buffer.Empty());
    106   // Get the event at its starting timestamp.
    107   EXPECT_TRUE(buffer.GetEvent(timestamp, &out_event));
    108   EXPECT_TRUE(EqualEvents(event, out_event));
    109   EXPECT_EQ(1u, buffer.Length());
    110   EXPECT_FALSE(buffer.Empty());
    111   // Get the event some time into the event.
    112   EXPECT_TRUE(buffer.GetEvent(timestamp + duration / 2, &out_event));
    113   EXPECT_TRUE(EqualEvents(event, out_event));
    114   EXPECT_EQ(1u, buffer.Length());
    115   EXPECT_FALSE(buffer.Empty());
    116   // Give a "current" timestamp after the event has ended.
    117 #ifdef LEGACY_BITEXACT
    118   EXPECT_TRUE(buffer.GetEvent(timestamp + duration + 10, &out_event));
    119 #endif
    120   EXPECT_FALSE(buffer.GetEvent(timestamp + duration + 10, &out_event));
    121   EXPECT_EQ(0u, buffer.Length());
    122   EXPECT_TRUE(buffer.Empty());
    123 }
    124 
    125 TEST(DtmfBuffer, MergingPackets) {
    126   int event_no = 0;
    127   bool end_bit = false;
    128   int volume = 17;
    129   int duration = 80;
    130   uint32_t timestamp = 0x12345678;
    131   DtmfEvent event(timestamp, event_no, volume, duration, end_bit);
    132   DtmfBuffer buffer(sample_rate_hz);
    133   EXPECT_EQ(DtmfBuffer::kOK, buffer.InsertEvent(event));
    134 
    135   event.duration += 80;
    136   EXPECT_EQ(DtmfBuffer::kOK, buffer.InsertEvent(event));
    137 
    138   event.duration += 80;
    139   event.end_bit = true;
    140   EXPECT_EQ(DtmfBuffer::kOK, buffer.InsertEvent(event));
    141 
    142   EXPECT_EQ(1u, buffer.Length());
    143 
    144   DtmfEvent out_event;
    145   EXPECT_TRUE(buffer.GetEvent(timestamp, &out_event));
    146   EXPECT_TRUE(EqualEvents(event, out_event));
    147 }
    148 
    149 // This test case inserts one shorter event completely overlapped by one longer
    150 // event. The expected outcome is that only the longer event is played.
    151 TEST(DtmfBuffer, OverlappingEvents) {
    152   int event_no = 0;
    153   bool end_bit = true;
    154   int volume = 1;
    155   int duration = 80;
    156   uint32_t timestamp = 0x12345678 + 80;
    157   DtmfEvent short_event(timestamp, event_no, volume, duration, end_bit);
    158   DtmfBuffer buffer(sample_rate_hz);
    159   EXPECT_EQ(DtmfBuffer::kOK, buffer.InsertEvent(short_event));
    160 
    161   event_no = 10;
    162   end_bit = false;
    163   timestamp = 0x12345678;
    164   DtmfEvent long_event(timestamp, event_no, volume, duration, end_bit);
    165   EXPECT_EQ(DtmfBuffer::kOK, buffer.InsertEvent(long_event));
    166 
    167   long_event.duration += 80;
    168   EXPECT_EQ(DtmfBuffer::kOK, buffer.InsertEvent(long_event));
    169 
    170   long_event.duration += 80;
    171   long_event.end_bit = true;
    172   EXPECT_EQ(DtmfBuffer::kOK, buffer.InsertEvent(long_event));
    173 
    174   EXPECT_EQ(2u, buffer.Length());
    175 
    176   DtmfEvent out_event;
    177   // Expect to get the long event.
    178   EXPECT_TRUE(buffer.GetEvent(timestamp, &out_event));
    179   EXPECT_TRUE(EqualEvents(long_event, out_event));
    180   // Expect no more events.
    181 #ifdef LEGACY_BITEXACT
    182   EXPECT_TRUE(buffer.GetEvent(timestamp + long_event.duration + 10,
    183                               &out_event));
    184   EXPECT_TRUE(EqualEvents(long_event, out_event));
    185   EXPECT_TRUE(buffer.GetEvent(timestamp + long_event.duration + 10,
    186                               &out_event));
    187   EXPECT_TRUE(EqualEvents(short_event, out_event));
    188 #else
    189   EXPECT_FALSE(buffer.GetEvent(timestamp + long_event.duration + 10,
    190                                &out_event));
    191 #endif
    192   EXPECT_TRUE(buffer.Empty());
    193 }
    194 
    195 TEST(DtmfBuffer, ExtrapolationTime) {
    196   int event_no = 0;
    197   bool end_bit = false;
    198   int volume = 1;
    199   int duration = 80;
    200   uint32_t timestamp = 0x12345678;
    201   DtmfEvent event1(timestamp, event_no, volume, duration, end_bit);
    202   DtmfBuffer buffer(sample_rate_hz);
    203   EXPECT_EQ(DtmfBuffer::kOK, buffer.InsertEvent(event1));
    204   EXPECT_EQ(1u, buffer.Length());
    205 
    206   DtmfEvent out_event;
    207   // Get the event at the start.
    208   EXPECT_TRUE(buffer.GetEvent(timestamp, &out_event));
    209   EXPECT_TRUE(EqualEvents(event1, out_event));
    210   // Also get the event 100 samples after the end of the event (since we're
    211   // missing the end bit).
    212   uint32_t timestamp_now = timestamp + duration + 100;
    213   EXPECT_TRUE(buffer.GetEvent(timestamp_now, &out_event));
    214   EXPECT_TRUE(EqualEvents(event1, out_event));
    215   // Insert another event starting back-to-back with the previous event.
    216   timestamp += duration;
    217   event_no = 1;
    218   DtmfEvent event2(timestamp, event_no, volume, duration, end_bit);
    219   EXPECT_EQ(DtmfBuffer::kOK, buffer.InsertEvent(event2));
    220   EXPECT_EQ(2u, buffer.Length());
    221   // Now we expect to get the new event when supplying |timestamp_now|.
    222   EXPECT_TRUE(buffer.GetEvent(timestamp_now, &out_event));
    223   EXPECT_TRUE(EqualEvents(event2, out_event));
    224   // Expect the the first event to be erased now.
    225   EXPECT_EQ(1u, buffer.Length());
    226   // Move |timestamp_now| to more than 560 samples after the end of the second
    227   // event. Expect that event to be erased.
    228   timestamp_now = timestamp + duration + 600;
    229 #ifdef LEGACY_BITEXACT
    230   EXPECT_TRUE(buffer.GetEvent(timestamp_now, &out_event));
    231 #endif
    232   EXPECT_FALSE(buffer.GetEvent(timestamp_now, &out_event));
    233   EXPECT_TRUE(buffer.Empty());
    234 }
    235 
    236 TEST(DtmfBuffer, TimestampWraparound) {
    237   int event_no = 0;
    238   bool end_bit = true;
    239   int volume = 1;
    240   int duration = 80;
    241   uint32_t timestamp1 = 0xFFFFFFFF - duration;
    242   DtmfEvent event1(timestamp1, event_no, volume, duration, end_bit);
    243   uint32_t timestamp2 = 0;
    244   DtmfEvent event2(timestamp2, event_no, volume, duration, end_bit);
    245   DtmfBuffer buffer(sample_rate_hz);
    246   EXPECT_EQ(DtmfBuffer::kOK, buffer.InsertEvent(event1));
    247   EXPECT_EQ(DtmfBuffer::kOK, buffer.InsertEvent(event2));
    248   EXPECT_EQ(2u, buffer.Length());
    249   DtmfEvent out_event;
    250   EXPECT_TRUE(buffer.GetEvent(timestamp1, &out_event));
    251   EXPECT_TRUE(EqualEvents(event1, out_event));
    252 #ifdef LEGACY_BITEXACT
    253   EXPECT_EQ(1u, buffer.Length());
    254 #else
    255   EXPECT_EQ(2u, buffer.Length());
    256 #endif
    257 
    258   buffer.Flush();
    259   // Reverse the insert order. Expect same results.
    260   EXPECT_EQ(DtmfBuffer::kOK, buffer.InsertEvent(event2));
    261   EXPECT_EQ(DtmfBuffer::kOK, buffer.InsertEvent(event1));
    262   EXPECT_EQ(2u, buffer.Length());
    263   EXPECT_TRUE(buffer.GetEvent(timestamp1, &out_event));
    264   EXPECT_TRUE(EqualEvents(event1, out_event));
    265 #ifdef LEGACY_BITEXACT
    266   EXPECT_EQ(1u, buffer.Length());
    267 #else
    268   EXPECT_EQ(2u, buffer.Length());
    269 #endif
    270 }
    271 
    272 TEST(DtmfBuffer, InvalidEvents) {
    273   int event_no = 0;
    274   bool end_bit = true;
    275   int volume = 1;
    276   int duration = 80;
    277   uint32_t timestamp = 0x12345678;
    278   DtmfEvent event(timestamp, event_no, volume, duration, end_bit);
    279   DtmfBuffer buffer(sample_rate_hz);
    280 
    281   // Invalid event number.
    282   event.event_no = -1;
    283   EXPECT_EQ(DtmfBuffer::kInvalidEventParameters, buffer.InsertEvent(event));
    284   event.event_no = 16;
    285   EXPECT_EQ(DtmfBuffer::kInvalidEventParameters, buffer.InsertEvent(event));
    286   event.event_no = 0;  // Valid value;
    287 
    288   // Invalid volume.
    289   event.volume = -1;
    290   EXPECT_EQ(DtmfBuffer::kInvalidEventParameters, buffer.InsertEvent(event));
    291   event.volume = 37;
    292   EXPECT_EQ(DtmfBuffer::kInvalidEventParameters, buffer.InsertEvent(event));
    293   event.volume = 0;  // Valid value;
    294 
    295   // Invalid duration.
    296   event.duration = -1;
    297   EXPECT_EQ(DtmfBuffer::kInvalidEventParameters, buffer.InsertEvent(event));
    298   event.duration = 0;
    299   EXPECT_EQ(DtmfBuffer::kInvalidEventParameters, buffer.InsertEvent(event));
    300   event.duration = 0xFFFF + 1;
    301   EXPECT_EQ(DtmfBuffer::kInvalidEventParameters, buffer.InsertEvent(event));
    302   event.duration = 1;  // Valid value;
    303 
    304   // Finish with a valid event, just to verify that all is ok.
    305   EXPECT_EQ(DtmfBuffer::kOK, buffer.InsertEvent(event));
    306 }
    307 }  // namespace webrtc
    308