普通文本  |  225行  |  5.41 KB

// 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();
}