Home | History | Annotate | Download | only in tests
      1 // Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <stdio.h>
      6 #include <gtest/gtest.h>
      7 
      8 extern "C" {
      9 #include "cras_audio_format.h"
     10 #include "cras_audio_area.h"
     11 }
     12 
     13 static const int8_t stereo[CRAS_CH_MAX] = {
     14   0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     15 };
     16 static const int8_t mono[CRAS_CH_MAX] = {
     17   -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1,
     18 };
     19 static const int8_t kb_mic[CRAS_CH_MAX] = {
     20   0, 1, -1, -1, 2, -1, -1, -1, -1, -1, -1,
     21 };
     22 
     23 static uint16_t buf1[32];
     24 static uint16_t buf2[32];
     25 struct cras_audio_area *a1;
     26 struct cras_audio_area *a2;
     27 
     28 namespace {
     29 
     30 TEST(AudioArea, CopyAudioArea) {
     31   struct cras_audio_format fmt;
     32   int i;
     33 
     34   fmt.num_channels = 2;
     35   fmt.format = SND_PCM_FORMAT_S16_LE;
     36   for (i = 0; i < CRAS_CH_MAX; i++)
     37     fmt.channel_layout[i] = stereo[i];
     38 
     39   a1 = cras_audio_area_create(2);
     40   a2 = cras_audio_area_create(2);
     41   cras_audio_area_config_channels(a1, &fmt);
     42   cras_audio_area_config_channels(a2, &fmt);
     43   cras_audio_area_config_buf_pointers(a1, &fmt, (uint8_t *)buf1);
     44   cras_audio_area_config_buf_pointers(a2, &fmt, (uint8_t *)buf2);
     45   a1->frames = 16;
     46   a2->frames = 16;
     47 
     48   memset(buf1, 0, 32 * 2);
     49   for (i = 0; i < 32; i++)
     50     buf2[i] = rand();
     51   cras_audio_area_copy(a1, 0, &fmt, a2, 0, 1.0);
     52   for (i = 0; i < 32; i++)
     53     EXPECT_EQ(buf1[i], buf2[i]);
     54 
     55   cras_audio_area_destroy(a1);
     56   cras_audio_area_destroy(a2);
     57 }
     58 
     59 TEST(AudioArea, CopyAudioAreaWithGain) {
     60   struct cras_audio_format fmt;
     61   int i;
     62   /* Check a gain of 10x can be applied. */
     63   float gain_scaler = 10.0f;
     64 
     65   fmt.num_channels = 2;
     66   fmt.format = SND_PCM_FORMAT_S16_LE;
     67   for (i = 0; i < CRAS_CH_MAX; i++)
     68     fmt.channel_layout[i] = stereo[i];
     69 
     70   a1 = cras_audio_area_create(2);
     71   a2 = cras_audio_area_create(2);
     72   cras_audio_area_config_channels(a1, &fmt);
     73   cras_audio_area_config_channels(a2, &fmt);
     74   cras_audio_area_config_buf_pointers(a1, &fmt, (uint8_t *)buf1);
     75   cras_audio_area_config_buf_pointers(a2, &fmt, (uint8_t *)buf2);
     76   a1->frames = 16;
     77   a2->frames = 16;
     78 
     79   memset(buf1, 0, 32 * 2);
     80   /* Let src has some samples smaller than 32768/10 and some samples larger than
     81    * 32768/10 to test clipping. */
     82   for (i = 0; i < 16; i++)
     83     buf2[i] = rand() % 3270;
     84   for (i = 17; i < 32; i++)
     85     buf2[i] = 3280 + rand() % 3200;
     86   cras_audio_area_copy(a1, 0, &fmt, a2, 0, gain_scaler);
     87   for (i = 0; i < 32; i++) {
     88     int32_t expected_value = buf2[i] * gain_scaler;
     89     if (expected_value > INT16_MAX)
     90       expected_value = INT16_MAX;
     91     EXPECT_EQ(buf1[i], expected_value);
     92   }
     93 
     94   cras_audio_area_destroy(a1);
     95   cras_audio_area_destroy(a2);
     96 }
     97 TEST(AudioArea, CopyAudioAreaOffset) {
     98   struct cras_audio_format fmt;
     99   int i;
    100 
    101   fmt.num_channels = 2;
    102   fmt.format = SND_PCM_FORMAT_S16_LE;
    103   for (i = 0; i < CRAS_CH_MAX; i++)
    104     fmt.channel_layout[i] = stereo[i];
    105 
    106   a1 = cras_audio_area_create(2);
    107   a2 = cras_audio_area_create(2);
    108   cras_audio_area_config_channels(a1, &fmt);
    109   cras_audio_area_config_channels(a2, &fmt);
    110   cras_audio_area_config_buf_pointers(a1, &fmt, (uint8_t *)buf1);
    111   cras_audio_area_config_buf_pointers(a2, &fmt, (uint8_t *)buf2);
    112   a1->frames = 16;
    113   a2->frames = 14;
    114 
    115   memset(buf1, 0, 32 * 2);
    116   for (i = 0; i < 32; i++)
    117     buf2[i] = rand();
    118   cras_audio_area_copy(a1, 2, &fmt, a2, 0, 1.0);
    119   EXPECT_EQ(buf1[0], 0);
    120   EXPECT_EQ(buf1[1], 0);
    121   EXPECT_EQ(buf1[2], 0);
    122   EXPECT_EQ(buf1[3], 0);
    123   for (i = 4; i < 32; i++)
    124     EXPECT_EQ(buf1[i], buf2[i-4]);
    125 
    126   cras_audio_area_destroy(a1);
    127   cras_audio_area_destroy(a2);
    128 }
    129 
    130 TEST(AudioArea, CopyAudioAreaOffsetLimit) {
    131   struct cras_audio_format fmt;
    132   int i;
    133 
    134   fmt.num_channels = 2;
    135   fmt.format = SND_PCM_FORMAT_S16_LE;
    136   for (i = 0; i < CRAS_CH_MAX; i++)
    137     fmt.channel_layout[i] = stereo[i];
    138 
    139   a1 = cras_audio_area_create(2);
    140   a2 = cras_audio_area_create(2);
    141   cras_audio_area_config_channels(a1, &fmt);
    142   cras_audio_area_config_channels(a2, &fmt);
    143   cras_audio_area_config_buf_pointers(a1, &fmt, (uint8_t *)buf1);
    144   cras_audio_area_config_buf_pointers(a2, &fmt, (uint8_t *)buf2);
    145   a1->frames = 14;
    146   a2->frames = 14;
    147 
    148   memset(buf1, 0, 32 * 2);
    149   for (i = 0; i < 32; i++)
    150     buf2[i] = rand();
    151   cras_audio_area_copy(a1, 2, &fmt, a2, 0, 1.0);
    152   EXPECT_EQ(buf1[0], 0);
    153   EXPECT_EQ(buf1[1], 0);
    154   EXPECT_EQ(buf1[2], 0);
    155   EXPECT_EQ(buf1[3], 0);
    156   for (i = 4; i < 28; i++)
    157     EXPECT_EQ(buf1[i], buf2[i-4]);
    158   EXPECT_EQ(buf1[28], 0);
    159   EXPECT_EQ(buf1[29], 0);
    160   EXPECT_EQ(buf1[30], 0);
    161   EXPECT_EQ(buf1[31], 0);
    162 
    163   cras_audio_area_destroy(a1);
    164   cras_audio_area_destroy(a2);
    165 }
    166 
    167 TEST(AudioArea, CopyMonoToStereo) {
    168   struct cras_audio_format dst_fmt;
    169   struct cras_audio_format src_fmt;
    170   int i;
    171 
    172   dst_fmt.num_channels = 2;
    173   dst_fmt.format = SND_PCM_FORMAT_S16_LE;
    174   for (i = 0; i < CRAS_CH_MAX; i++)
    175     dst_fmt.channel_layout[i] = stereo[i];
    176   a1 = cras_audio_area_create(2);
    177   a1->frames = 16;
    178   cras_audio_area_config_channels(a1, &dst_fmt);
    179   cras_audio_area_config_buf_pointers(a1, &dst_fmt, (uint8_t *)buf1);
    180 
    181   src_fmt.num_channels = 1;
    182   src_fmt.format = SND_PCM_FORMAT_S16_LE;
    183   for (i = 0; i < CRAS_CH_MAX; i++)
    184     src_fmt.channel_layout[i] = mono[i];
    185   a2 = cras_audio_area_create(1);
    186   a2->frames = 16;
    187   cras_audio_area_config_channels(a2, &src_fmt);
    188   cras_audio_area_config_buf_pointers(a2, &src_fmt, (uint8_t *)buf2);
    189 
    190   memset(buf1, 0, 32 * 2);
    191   for (i = 0; i < 32; i++)
    192     buf2[i] = rand();
    193   cras_audio_area_copy(a1, 0, &dst_fmt, a2, 0, 1.0);
    194   for (i = 0; i < 16; i++) {
    195     EXPECT_EQ(buf1[i * 2], buf2[i]);
    196     EXPECT_EQ(buf1[i * 2 + 1], buf2[i]);
    197   }
    198 
    199   cras_audio_area_destroy(a1);
    200   cras_audio_area_destroy(a2);
    201 }
    202 
    203 TEST(AudioArea, CopyStereoToMono) {
    204   struct cras_audio_format fmt;
    205   int i;
    206 
    207   fmt.num_channels = 1;
    208   fmt.format = SND_PCM_FORMAT_S16_LE;
    209   for (i = 0; i < CRAS_CH_MAX; i++)
    210     fmt.channel_layout[i] = mono[i];
    211   a1 = cras_audio_area_create(1);
    212   a1->frames = 16;
    213   cras_audio_area_config_channels(a1, &fmt);
    214   cras_audio_area_config_buf_pointers(a1, &fmt, (uint8_t *)buf1);
    215 
    216   fmt.num_channels = 2;
    217   for (i = 0; i < CRAS_CH_MAX; i++)
    218     fmt.channel_layout[i] = stereo[i];
    219   a2 = cras_audio_area_create(2);
    220   a2->frames = 16;
    221   cras_audio_area_config_channels(a2, &fmt);
    222   cras_audio_area_config_buf_pointers(a2, &fmt, (uint8_t *)buf2);
    223 
    224   memset(buf1, 0, 32 * 2);
    225   for (i = 0; i < 32; i++)
    226     buf2[i] = rand() % 10000;
    227   cras_audio_area_copy(a1, 0, &fmt, a2, 0, 1.0);
    228   for (i = 0; i < 16; i++)
    229     EXPECT_EQ(buf1[i], buf2[i * 2] + buf2[i * 2 + 1]);
    230 
    231   cras_audio_area_destroy(a1);
    232   cras_audio_area_destroy(a2);
    233 }
    234 
    235 TEST(AudioArea, KeyboardMicCopyStereo) {
    236   struct cras_audio_format fmt;
    237   int i;
    238 
    239   fmt.num_channels = 3;
    240   fmt.format = SND_PCM_FORMAT_S16_LE;
    241   for (i = 0; i < CRAS_CH_MAX; i++)
    242     fmt.channel_layout[i] = kb_mic[i];
    243   a1 = cras_audio_area_create(3);
    244   a1->frames = 10;
    245   cras_audio_area_config_channels(a1, &fmt);
    246   cras_audio_area_config_buf_pointers(a1, &fmt, (uint8_t *)buf1);
    247 
    248   fmt.num_channels = 2;
    249   for (i = 0; i < CRAS_CH_MAX; i++)
    250     fmt.channel_layout[i] = stereo[i];
    251   a2 = cras_audio_area_create(2);
    252   a2->frames = 10;
    253   cras_audio_area_config_channels(a2, &fmt);
    254   cras_audio_area_config_buf_pointers(a2, &fmt, (uint8_t *)buf2);
    255 
    256   memset(buf1, 0, 32 * 2);
    257   for (i = 0; i < 32; i++)
    258     buf2[i] = rand();
    259   cras_audio_area_copy(a1, 0, &fmt, a2, 0, 1.0);
    260   for (i = 0; i < 10; i++) {
    261     EXPECT_EQ(buf1[i * 3], buf2[i * 2]);
    262     EXPECT_EQ(buf1[i * 3 + 1], buf2[i * 2 + 1]);
    263     EXPECT_EQ(buf1[i * 3 + 2], 0);
    264   }
    265 
    266   cras_audio_area_destroy(a1);
    267   cras_audio_area_destroy(a2);
    268 }
    269 
    270 TEST(AudioArea, KeyboardMicCopyFrontCenter) {
    271   struct cras_audio_format dst_fmt;
    272   struct cras_audio_format src_fmt;
    273   int i;
    274 
    275   dst_fmt.num_channels = 3;
    276   dst_fmt.format = SND_PCM_FORMAT_S16_LE;
    277   for (i = 0; i < CRAS_CH_MAX; i++)
    278     dst_fmt.channel_layout[i] = kb_mic[i];
    279   a1 = cras_audio_area_create(3);
    280   a1->frames = 10;
    281   cras_audio_area_config_channels(a1, &dst_fmt);
    282   cras_audio_area_config_buf_pointers(a1, &dst_fmt, (uint8_t *)buf1);
    283 
    284   /* Test 2 channels area with only front center in layout. */
    285   src_fmt.num_channels = 2;
    286   src_fmt.format = SND_PCM_FORMAT_S16_LE;
    287   for (i = 0; i < CRAS_CH_MAX; i++)
    288     src_fmt.channel_layout[i] = -1;
    289   src_fmt.channel_layout[CRAS_CH_FC] = 0;
    290   a2 = cras_audio_area_create(2);
    291   a2->frames = 10;
    292   cras_audio_area_config_channels(a2, &src_fmt);
    293   cras_audio_area_config_buf_pointers(a2, &src_fmt, (uint8_t *)buf2);
    294 
    295   memset(buf1, 0, 32 * 2);
    296   for (i = 0; i < 32; i++)
    297     buf2[i] = rand();
    298   cras_audio_area_copy(a1, 0, &dst_fmt, a2, 0, 1.0);
    299   for (i = 0; i < 10; i++) {
    300     EXPECT_EQ(buf1[i * 3], 0);
    301     EXPECT_EQ(buf1[i * 3 + 1], 0);
    302     EXPECT_EQ(buf1[i * 3 + 2], buf2[i * 2]);
    303   }
    304 
    305   cras_audio_area_destroy(a1);
    306   cras_audio_area_destroy(a2);
    307 }
    308 
    309 }  //  namespace
    310 
    311 extern "C" {
    312 
    313 void cras_mix_add_scale_stride(snd_pcm_format_t fmt, uint8_t *dst, uint8_t *src,
    314 			 unsigned int count, unsigned int dst_stride,
    315 			 unsigned int src_stride, float scaler)
    316 {
    317 	unsigned int i;
    318 
    319 	for (i = 0; i < count; i++) {
    320 		int32_t sum;
    321 		sum = *(int16_t *)dst + *(int16_t *)src * scaler;
    322 		if (sum > INT16_MAX)
    323 			sum = INT16_MAX;
    324 		else if (sum < INT16_MIN)
    325 			sum = INT16_MIN;
    326 		*(int16_t*)dst = sum;
    327 		dst += dst_stride;
    328 		src += src_stride;
    329 	}
    330 }
    331 
    332 }  //  extern "C"
    333 
    334 int main(int argc, char **argv) {
    335   ::testing::InitGoogleTest(&argc, argv);
    336   return RUN_ALL_TESTS();
    337 }
    338