// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <limits.h>
#include <stdio.h>
#include <stdint.h>
#include <gtest/gtest.h>
extern "C" {
#include "linear_resampler.h"
}
#define BUF_SIZE 2048
static uint8_t in_buf[BUF_SIZE];
static uint8_t out_buf[BUF_SIZE];
TEST(LinearResampler, ReampleToSlightlyLargerRate) {
int i, rc;
unsigned int count;
unsigned int in_offset = 0;
unsigned int out_offset = 0;
struct linear_resampler *lr;
memset(in_buf, 0, BUF_SIZE);
memset(out_buf, 0, BUF_SIZE);
for (i = 0; i < 100; i++) {
*((int16_t *)(in_buf + i * 4)) = i * 10;
*((int16_t *)(in_buf + i * 4 + 2)) = i * 20;
}
lr = linear_resampler_create(2, 4, 48000, 48001);
count = 20;
rc = linear_resampler_resample(lr, in_buf + 4 * in_offset, &count,
out_buf + 4 * out_offset, 50);
EXPECT_EQ(20, rc);
EXPECT_EQ(20, count);
in_offset += count;
out_offset += rc;
count = 20;
rc = linear_resampler_resample(lr, in_buf + 4 * in_offset, &count,
out_buf + 4 * out_offset, 15);
EXPECT_EQ(15, rc);
EXPECT_EQ(15, count);
/* Assert linear interpotation result. */
for (i = 0; i < 34; i++) {
EXPECT_GE(*(int16_t *)(in_buf + 4 * i),
*(int16_t *)(out_buf + 4 * i));
EXPECT_LE(*(int16_t *)(in_buf + 4 * i),
*(int16_t *)(out_buf + 4 * (i + 1)));
}
linear_resampler_destroy(lr);
}
TEST(LinearResampler, ResampleIntegerFractionToLarger) {
int i, rc;
unsigned int count;
unsigned int in_offset = 0;
unsigned int out_offset = 0;
struct linear_resampler *lr;
memset(in_buf, 0, BUF_SIZE);
memset(out_buf, 0, BUF_SIZE);
for (i = 0; i < 100; i++) {
*((int16_t *)(in_buf + i * 4)) = SHRT_MAX - i;
*((int16_t *)(in_buf + i * 4 + 2)) = SHRT_MAX - i * 10;
}
/* Rate 10 -> 11 */
lr = linear_resampler_create(2, 4, 10, 11);
count = 5;
rc = linear_resampler_resample(lr, in_buf + 4 * in_offset, &count,
out_buf + 4 * out_offset, 10);
EXPECT_EQ(5, rc);
EXPECT_EQ(5, count);
in_offset += count;
out_offset += rc;
count = 6;
/* Assert source rate + 1 frames resample to destination rate + 1
* frames. */
rc = linear_resampler_resample(lr, in_buf + 4 * in_offset, &count,
out_buf + 4 * out_offset, 10);
EXPECT_EQ(7, rc);
EXPECT_EQ(6, count);
in_offset += count;
out_offset += rc;
count = 89;
rc = linear_resampler_resample(lr, in_buf + 4 * in_offset, &count,
out_buf + 4 * out_offset, 100);
EXPECT_EQ(97, rc);
EXPECT_EQ(89, count);
/* Assert linear interpotation result. */
for (i = 0; i < 90; i++) {
EXPECT_LE(*(int16_t *)(in_buf + 4 * i),
*(int16_t *)(out_buf + 4 * i));
EXPECT_LE(*(int16_t *)(in_buf + 4 * i + 2),
*(int16_t *)(out_buf + 4 * i + 2));
}
linear_resampler_destroy(lr);
}
TEST(LinearResampler, ResampleIntegerFractionToLess) {
int i, rc;
unsigned int count;
unsigned int in_offset = 0;
unsigned int out_offset = 0;
struct linear_resampler *lr;
memset(in_buf, 0, BUF_SIZE);
memset(out_buf, 0, BUF_SIZE);
for (i = 0; i < 100; i++) {
*((int16_t *)(in_buf + i * 4)) = SHRT_MIN + i * 10;
*((int16_t *)(in_buf + i * 4 + 2)) = SHRT_MIN + i * 20;
}
/* Rate 10 -> 9 */
lr = linear_resampler_create(2, 4, 10, 9);
count = 6;
rc = linear_resampler_resample(lr, in_buf + 4 * in_offset, &count,
out_buf + 4 * out_offset, 6);
EXPECT_EQ(5, rc);
EXPECT_EQ(6, count);
in_offset += count;
out_offset += rc;
count = 4;
/* Assert source rate frames resample to destination rate frames. */
rc = linear_resampler_resample(lr, in_buf + 4 * in_offset, &count,
out_buf + 4 * out_offset, 4);
EXPECT_EQ(4, rc);
EXPECT_EQ(4, count);
in_offset += count;
out_offset += rc;
count = 90;
rc = linear_resampler_resample(lr, in_buf + 4 * in_offset, &count,
out_buf + 4 * out_offset, 90);
/* Assert linear interpotation result. */
for (i = 0; i < 90; i++) {
EXPECT_LE(*(int16_t *)(in_buf + 4 * i),
*(int16_t *)(out_buf + 4 * i));
EXPECT_LE(*(int16_t *)(in_buf + 4 * i + 2),
*(int16_t *)(out_buf + 4 * i + 2));
}
linear_resampler_destroy(lr);
}
TEST(LinearResampler, ResampleIntegerNoSrcBuffer) {
int rc;
unsigned int count;
struct linear_resampler *lr;
memset(in_buf, 0, BUF_SIZE);
memset(out_buf, 0, BUF_SIZE);
/* Rate 10 -> 9 */
lr = linear_resampler_create(2, 4, 10, 9);
count = 0;
rc = linear_resampler_resample(lr, in_buf, &count,
out_buf, BUF_SIZE);
EXPECT_EQ(0, rc);
EXPECT_EQ(0, count);
linear_resampler_destroy(lr);
}
TEST(LinearResampler, ResampleIntegerNoDstBuffer) {
int rc;
unsigned int count;
struct linear_resampler *lr;
memset(in_buf, 0, BUF_SIZE);
memset(out_buf, 0, BUF_SIZE);
/* Rate 10 -> 9 */
lr = linear_resampler_create(2, 4, 10, 9);
count = BUF_SIZE;
rc = linear_resampler_resample(lr, in_buf, &count,
out_buf, 0);
EXPECT_EQ(0, rc);
EXPECT_EQ(0, count);
linear_resampler_destroy(lr);
}
extern "C" {
void cras_mix_add_scale_stride(int fmt, uint8_t *dst, uint8_t *src,
unsigned int count, unsigned int dst_stride,
unsigned int src_stride, float scaler)
{
unsigned int i;
for (i = 0; i < count; i++) {
int32_t sum;
sum = *(int16_t *)dst + *(int16_t *)src * scaler;
if (sum > INT16_MAX)
sum = INT16_MAX;
else if (sum < INT16_MIN)
sum = INT16_MIN;
*(int16_t*)dst = sum;
dst += dst_stride;
src += src_stride;
}
}
} // extern "C"
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}