blob: a0b6194e1ebf42051f8127136b98bd52ddbbed98 [file] [log] [blame]
// Copyright (c) 2012 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 <gtest/gtest.h>
#include <sys/param.h>
extern "C" {
#include "cras_fmt_conv.h"
#include "cras_types.h"
}
static int mono_channel_layout[CRAS_CH_MAX] =
{-1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1};
static int stereo_channel_layout[CRAS_CH_MAX] =
{0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
static int surround_channel_layout[CRAS_CH_MAX] =
{0, 1, 2, 3, 4, 5, -1, -1, -1, -1, -1};
static int linear_resampler_needed_val;
static double linear_resampler_ratio = 1.0;
void ResetStub() {
linear_resampler_needed_val = 0;
linear_resampler_ratio = 1.0;
}
// Like malloc or calloc, but fill the memory with random bytes.
static void *ralloc(size_t size) {
unsigned char *buf = (unsigned char *)malloc(size);
while (size--)
buf[size] = rand() & 0xff;
return buf;
}
static void swap_channel_layout(int8_t *layout,
CRAS_CHANNEL a,
CRAS_CHANNEL b) {
int8_t tmp = layout[a];
layout[a] = layout[b];
layout[b] = tmp;
}
// Only support LE, BE should fail.
TEST(FormatConverterTest, InvalidParamsOnlyLE) {
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
struct cras_fmt_conv *c;
ResetStub();
in_fmt.format = out_fmt.format = SND_PCM_FORMAT_S32_BE;
in_fmt.num_channels = out_fmt.num_channels = 2;
c = cras_fmt_conv_create(&in_fmt, &out_fmt, 4096, 0);
EXPECT_EQ(NULL, c);
}
// Test Mono to Stereo mix.
TEST(FormatConverterTest, MonoToStereo) {
struct cras_fmt_conv *c;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
size_t out_frames;
int16_t *in_buff;
int16_t *out_buff;
const size_t buf_size = 4096;
unsigned int in_buf_size = 4096;
ResetStub();
in_fmt.format = SND_PCM_FORMAT_S16_LE;
out_fmt.format = SND_PCM_FORMAT_S16_LE;
in_fmt.num_channels = 1;
out_fmt.num_channels = 2;
in_fmt.frame_rate = 48000;
out_fmt.frame_rate = 48000;
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
ASSERT_NE(c, (void *)NULL);
out_frames = cras_fmt_conv_out_frames_to_in(c, buf_size);
EXPECT_EQ(buf_size, out_frames);
out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
EXPECT_EQ(buf_size, out_frames);
in_buff = (int16_t *)ralloc(buf_size * 2 * cras_get_format_bytes(&in_fmt));
out_buff = (int16_t *)ralloc(buf_size * 2 * cras_get_format_bytes(&out_fmt));
out_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
buf_size);
EXPECT_EQ(buf_size, out_frames);
for (size_t i = 0; i < buf_size; i++) {
if (in_buff[i] != out_buff[i*2] ||
in_buff[i] != out_buff[i*2 + 1]) {
EXPECT_TRUE(false);
break;
}
}
cras_fmt_conv_destroy(c);
free(in_buff);
free(out_buff);
}
// Test Stereo to Mono mix.
TEST(FormatConverterTest, StereoToMono) {
struct cras_fmt_conv *c;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
size_t out_frames;
int16_t *in_buff;
int16_t *out_buff;
unsigned int i;
const size_t buf_size = 4096;
unsigned int in_buf_size = 4096;
ResetStub();
in_fmt.format = SND_PCM_FORMAT_S16_LE;
out_fmt.format = SND_PCM_FORMAT_S16_LE;
in_fmt.num_channels = 2;
out_fmt.num_channels = 1;
in_fmt.frame_rate = 48000;
out_fmt.frame_rate = 48000;
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
ASSERT_NE(c, (void *)NULL);
out_frames = cras_fmt_conv_out_frames_to_in(c, buf_size);
EXPECT_EQ(buf_size, out_frames);
out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
EXPECT_EQ(buf_size, out_frames);
in_buff = (int16_t *)malloc(buf_size * 2 * cras_get_format_bytes(&in_fmt));
out_buff = (int16_t *)malloc(buf_size * cras_get_format_bytes(&out_fmt));
for (i = 0; i < buf_size; i++) {
in_buff[i * 2] = 13450;
in_buff[i * 2 + 1] = -13449;
}
out_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
buf_size);
EXPECT_EQ(buf_size, out_frames);
for (i = 0; i < buf_size; i++) {
EXPECT_EQ(1, out_buff[i]);
}
cras_fmt_conv_destroy(c);
free(in_buff);
free(out_buff);
}
// Test Stereo to Mono mix 24 and 32 bit.
TEST(FormatConverterTest, StereoToMono24bit) {
struct cras_fmt_conv *c;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
size_t out_frames;
int32_t *in_buff;
int32_t *out_buff;
unsigned int i;
const size_t buf_size = 100;
unsigned int in_buf_size = 100;
unsigned int test;
for (test = 0; test < 2; test++) {
ResetStub();
if (test == 0) {
in_fmt.format = SND_PCM_FORMAT_S24_LE;
out_fmt.format = SND_PCM_FORMAT_S24_LE;
} else {
in_fmt.format = SND_PCM_FORMAT_S32_LE;
out_fmt.format = SND_PCM_FORMAT_S32_LE;
}
in_fmt.num_channels = 2;
out_fmt.num_channels = 1;
in_fmt.frame_rate = 48000;
out_fmt.frame_rate = 48000;
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
ASSERT_NE(c, (void *)NULL);
out_frames = cras_fmt_conv_out_frames_to_in(c, buf_size);
EXPECT_EQ(buf_size, out_frames);
out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
EXPECT_EQ(buf_size, out_frames);
in_buff = (int32_t *)malloc(buf_size * cras_get_format_bytes(&in_fmt));
out_buff = (int32_t *)malloc(buf_size * cras_get_format_bytes(&out_fmt));
// TODO(dgreid) - s/0x10000/1/ once it stays full bits the whole way.
for (i = 0; i < buf_size; i++) {
in_buff[i * 2] = 13450 << 16;
in_buff[i * 2 + 1] = -in_buff[i * 2] + 0x10000;
}
out_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
buf_size);
EXPECT_EQ(buf_size, out_frames);
for (i = 0; i < buf_size; i++) {
EXPECT_EQ(0x10000, out_buff[i]);
}
cras_fmt_conv_destroy(c);
free(in_buff);
free(out_buff);
}
}
// Test 5.1 to Stereo mix.
TEST(FormatConverterTest, SurroundToStereo) {
struct cras_fmt_conv *c;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
size_t out_frames;
int16_t *in_buff;
int16_t *out_buff;
unsigned int i;
const size_t buf_size = 4096;
unsigned int in_buf_size = 4096;
ResetStub();
in_fmt.format = SND_PCM_FORMAT_S16_LE;
out_fmt.format = SND_PCM_FORMAT_S16_LE;
in_fmt.num_channels = 6;
out_fmt.num_channels = 2;
in_fmt.frame_rate = 48000;
out_fmt.frame_rate = 48000;
for (i = 0; i < CRAS_CH_MAX; i++)
in_fmt.channel_layout[i] = surround_channel_layout[i];
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
ASSERT_NE(c, (void *)NULL);
out_frames = cras_fmt_conv_out_frames_to_in(c, buf_size);
EXPECT_EQ(buf_size, out_frames);
out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
EXPECT_EQ(buf_size, out_frames);
in_buff = (int16_t *)malloc(buf_size * 2 * cras_get_format_bytes(&in_fmt));
/* Swap channel to FL = 13450, RL = -100.
* Assert right channel is silent.
*/
for (i = 0; i < buf_size; i++) {
in_buff[i * 6] = 13450;
in_buff[i * 6 + 1] = 0;
in_buff[i * 6 + 2] = -100;
in_buff[i * 6 + 3] = 0;
in_buff[i * 6 + 4] = 0;
in_buff[i * 6 + 5] = 0;
}
out_buff = (int16_t *)malloc(buf_size * 2 * cras_get_format_bytes(&out_fmt));
out_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
buf_size);
EXPECT_EQ(buf_size, out_frames);
for (i = 0; i < buf_size; i++)
EXPECT_LT(0, out_buff[i * 2]);
/* Swap channel to FR = 13450, RR = -100.
* Assert left channel is silent.
*/
swap_channel_layout(in_fmt.channel_layout, CRAS_CH_FL, CRAS_CH_FR);
swap_channel_layout(in_fmt.channel_layout, CRAS_CH_RL, CRAS_CH_RR);
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
out_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
buf_size);
EXPECT_EQ(buf_size, out_frames);
for (i = 0; i < buf_size; i++)
EXPECT_LT(0, out_buff[i * 2 + 1]);
/* Swap channel to FC = 13450, LFE = -100.
* Assert output left and right has equal magnitude.
*/
swap_channel_layout(in_fmt.channel_layout, CRAS_CH_FR, CRAS_CH_FC);
swap_channel_layout(in_fmt.channel_layout, CRAS_CH_RR, CRAS_CH_LFE);
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
out_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
buf_size);
EXPECT_EQ(buf_size, out_frames);
for (i = 0; i < buf_size; i++) {
EXPECT_NE(0, out_buff[i * 2]);
EXPECT_EQ(out_buff[i * 2], out_buff[i * 2 + 1]);
}
/* Swap channel to FR = 13450, FL = -100.
* Assert output left is positive and right is negative. */
swap_channel_layout(in_fmt.channel_layout, CRAS_CH_LFE, CRAS_CH_FR);
swap_channel_layout(in_fmt.channel_layout, CRAS_CH_FC, CRAS_CH_FL);
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
out_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
buf_size);
EXPECT_EQ(buf_size, out_frames);
for (i = 0; i < buf_size; i++) {
EXPECT_LT(0, out_buff[i * 2]);
EXPECT_GT(0, out_buff[i * 2 + 1]);
}
cras_fmt_conv_destroy(c);
free(in_buff);
free(out_buff);
}
// Test 2 to 1 SRC.
TEST(FormatConverterTest, Convert2To1) {
struct cras_fmt_conv *c;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
size_t out_frames;
int16_t *in_buff;
int16_t *out_buff;
const size_t buf_size = 4096;
unsigned int in_buf_size = 4096;
ResetStub();
in_fmt.format = out_fmt.format = SND_PCM_FORMAT_S16_LE;
in_fmt.num_channels = out_fmt.num_channels = 2;
in_fmt.frame_rate = 96000;
out_fmt.frame_rate = 48000;
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
ASSERT_NE(c, (void *)NULL);
out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
EXPECT_EQ(buf_size/2, out_frames);
in_buff = (int16_t *)ralloc(buf_size * 2 * cras_get_format_bytes(&in_fmt));
out_buff = (int16_t *)ralloc(buf_size/2 * cras_get_format_bytes(&out_fmt));
out_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
buf_size / 2);
cras_fmt_conv_destroy(c);
free(in_buff);
free(out_buff);
}
// Test 1 to 2 SRC.
TEST(FormatConverterTest, Convert1To2) {
struct cras_fmt_conv *c;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
size_t out_frames;
int16_t *in_buff;
int16_t *out_buff;
const size_t buf_size = 4096;
unsigned int in_buf_size = 4096;
ResetStub();
in_fmt.format = out_fmt.format = SND_PCM_FORMAT_S16_LE;
in_fmt.num_channels = out_fmt.num_channels = 2;
in_fmt.frame_rate = 22050;
out_fmt.frame_rate = 44100;
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
ASSERT_NE(c, (void *)NULL);
out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
EXPECT_EQ(buf_size*2, out_frames);
in_buff = (int16_t *)ralloc(buf_size * 2 * cras_get_format_bytes(&in_fmt));
out_buff = (int16_t *)ralloc(buf_size*2 * cras_get_format_bytes(&out_fmt));
out_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
buf_size * 2);
cras_fmt_conv_destroy(c);
free(in_buff);
free(out_buff);
}
// Test 1 to 2 SRC with mono to stereo conversion.
TEST(FormatConverterTest, Convert1To2MonoToStereo) {
struct cras_fmt_conv *c;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
size_t out_frames;
int16_t *in_buff;
int16_t *out_buff;
const size_t buf_size = 4096;
unsigned int in_buf_size = 4096;
ResetStub();
in_fmt.format = out_fmt.format = SND_PCM_FORMAT_S16_LE;
in_fmt.num_channels = 1;
out_fmt.num_channels = 2;
in_fmt.frame_rate = 22050;
out_fmt.frame_rate = 44100;
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
ASSERT_NE(c, (void *)NULL);
out_frames = cras_fmt_conv_out_frames_to_in(c, buf_size);
EXPECT_EQ(buf_size / 2, out_frames);
out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
EXPECT_EQ(buf_size * 2, out_frames);
in_buff = (int16_t *)ralloc(buf_size * 2 * cras_get_format_bytes(&in_fmt));
out_buff = (int16_t *)ralloc(buf_size * 2 * cras_get_format_bytes(&out_fmt));
out_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
buf_size * 2);
cras_fmt_conv_destroy(c);
free(in_buff);
free(out_buff);
}
// Test 32 to 16 bit conversion.
TEST(FormatConverterTest, ConvertS32LEToS16LE) {
struct cras_fmt_conv *c;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
size_t out_frames;
int32_t *in_buff;
int16_t *out_buff;
const size_t buf_size = 4096;
unsigned int in_buf_size = 4096;
ResetStub();
in_fmt.format = SND_PCM_FORMAT_S32_LE;
out_fmt.format = SND_PCM_FORMAT_S16_LE;
in_fmt.num_channels = out_fmt.num_channels = 2;
in_fmt.frame_rate = 48000;
out_fmt.frame_rate = 48000;
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
ASSERT_NE(c, (void *)NULL);
out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
EXPECT_EQ(buf_size, out_frames);
in_buff = (int32_t *)ralloc(buf_size * 2 * cras_get_format_bytes(&in_fmt));
out_buff = (int16_t *)ralloc(buf_size * cras_get_format_bytes(&out_fmt));
out_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
buf_size);
EXPECT_EQ(buf_size, out_frames);
for (unsigned int i = 0; i < buf_size; i++)
EXPECT_EQ((int16_t)(in_buff[i] >> 16), out_buff[i]);
cras_fmt_conv_destroy(c);
free(in_buff);
free(out_buff);
}
// Test 24 to 16 bit conversion.
TEST(FormatConverterTest, ConvertS24LEToS16LE) {
struct cras_fmt_conv *c;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
size_t out_frames;
int32_t *in_buff;
int16_t *out_buff;
const size_t buf_size = 4096;
unsigned int in_buf_size = 4096;
ResetStub();
in_fmt.format = SND_PCM_FORMAT_S24_LE;
out_fmt.format = SND_PCM_FORMAT_S16_LE;
in_fmt.num_channels = out_fmt.num_channels = 2;
in_fmt.frame_rate = 48000;
out_fmt.frame_rate = 48000;
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
ASSERT_NE(c, (void *)NULL);
out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
EXPECT_EQ(buf_size, out_frames);
in_buff = (int32_t *)ralloc(buf_size * 2 * cras_get_format_bytes(&in_fmt));
out_buff = (int16_t *)ralloc(buf_size * cras_get_format_bytes(&out_fmt));
out_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
buf_size);
EXPECT_EQ(buf_size, out_frames);
for (unsigned int i = 0; i < buf_size; i++)
EXPECT_EQ((int16_t)(in_buff[i] >> 8), out_buff[i]);
cras_fmt_conv_destroy(c);
free(in_buff);
free(out_buff);
}
// Test 8 to 16 bit conversion.
TEST(FormatConverterTest, ConvertU8LEToS16LE) {
struct cras_fmt_conv *c;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
size_t out_frames;
uint8_t *in_buff;
int16_t *out_buff;
const size_t buf_size = 4096;
unsigned int in_buf_size = 4096;
ResetStub();
in_fmt.format = SND_PCM_FORMAT_U8;
out_fmt.format = SND_PCM_FORMAT_S16_LE;
in_fmt.num_channels = 2;
out_fmt.num_channels = 2;
in_fmt.frame_rate = 48000;
out_fmt.frame_rate = 48000;
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
ASSERT_NE(c, (void *)NULL);
out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
EXPECT_EQ(buf_size, out_frames);
in_buff = (uint8_t *)ralloc(buf_size * 2 * cras_get_format_bytes(&in_fmt));
out_buff = (int16_t *)ralloc(buf_size * cras_get_format_bytes(&out_fmt));
out_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
buf_size);
EXPECT_EQ(buf_size, out_frames);
for (unsigned int i = 0; i < buf_size; i++)
EXPECT_EQ(((int16_t)(in_buff[i] - 128) << 8), out_buff[i]);
cras_fmt_conv_destroy(c);
free(in_buff);
free(out_buff);
}
// Test 16 to 32 bit conversion.
TEST(FormatConverterTest, ConvertS16LEToS32LE) {
struct cras_fmt_conv *c;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
size_t out_frames;
int16_t *in_buff;
int32_t *out_buff;
const size_t buf_size = 4096;
unsigned int in_buf_size = 4096;
ResetStub();
in_fmt.format = SND_PCM_FORMAT_S16_LE;
out_fmt.format = SND_PCM_FORMAT_S32_LE;
in_fmt.num_channels = out_fmt.num_channels = 2;
in_fmt.frame_rate = 48000;
out_fmt.frame_rate = 48000;
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
ASSERT_NE(c, (void *)NULL);
out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
EXPECT_EQ(buf_size, out_frames);
in_buff = (int16_t *)ralloc(buf_size * cras_get_format_bytes(&in_fmt));
out_buff = (int32_t *)ralloc(buf_size * cras_get_format_bytes(&out_fmt));
out_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
buf_size);
EXPECT_EQ(buf_size, out_frames);
for (unsigned int i = 0; i < buf_size; i++)
EXPECT_EQ(((int32_t)in_buff[i] << 16), out_buff[i]);
cras_fmt_conv_destroy(c);
free(in_buff);
free(out_buff);
}
// Test 16 to 24 bit conversion.
TEST(FormatConverterTest, ConvertS16LEToS24LE) {
struct cras_fmt_conv *c;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
size_t out_frames;
int16_t *in_buff;
int32_t *out_buff;
const size_t buf_size = 4096;
unsigned int in_buf_size = 4096;
ResetStub();
in_fmt.format = SND_PCM_FORMAT_S16_LE;
out_fmt.format = SND_PCM_FORMAT_S24_LE;
in_fmt.num_channels = out_fmt.num_channels = 2;
in_fmt.frame_rate = 48000;
out_fmt.frame_rate = 48000;
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
ASSERT_NE(c, (void *)NULL);
out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
EXPECT_EQ(buf_size, out_frames);
in_buff = (int16_t *)ralloc(buf_size * cras_get_format_bytes(&in_fmt));
out_buff = (int32_t *)ralloc(buf_size * 2 * cras_get_format_bytes(&out_fmt));
out_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
buf_size);
EXPECT_EQ(buf_size, out_frames);
for (unsigned int i = 0; i < buf_size; i++)
EXPECT_EQ(((int32_t)in_buff[i] << 8), out_buff[i]);
cras_fmt_conv_destroy(c);
free(in_buff);
free(out_buff);
}
// Test 16 to 8 bit conversion.
TEST(FormatConverterTest, ConvertS16LEToU8) {
struct cras_fmt_conv *c;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
size_t out_frames;
int16_t *in_buff;
uint8_t *out_buff;
const size_t buf_size = 4096;
unsigned int in_buf_size = 4096;
ResetStub();
in_fmt.format = SND_PCM_FORMAT_S16_LE;
out_fmt.format = SND_PCM_FORMAT_U8;
in_fmt.num_channels = 2;
out_fmt.num_channels = 2;
in_fmt.frame_rate = 48000;
out_fmt.frame_rate = 48000;
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
ASSERT_NE(c, (void *)NULL);
out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
EXPECT_EQ(buf_size, out_frames);
in_buff = (int16_t *)ralloc(buf_size * cras_get_format_bytes(&in_fmt));
out_buff = (uint8_t *)ralloc(buf_size * cras_get_format_bytes(&out_fmt));
out_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
buf_size);
EXPECT_EQ(buf_size, out_frames);
for (unsigned int i = 0; i < buf_size; i++)
EXPECT_EQ((in_buff[i] >> 8) + 128, out_buff[i]);
cras_fmt_conv_destroy(c);
free(in_buff);
free(out_buff);
}
// Test 32 bit 5.1 to 16 bit stereo conversion.
TEST(FormatConverterTest, ConvertS32LEToS16LEDownmix51ToStereo) {
struct cras_fmt_conv *c;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
size_t out_frames;
int32_t *in_buff;
int16_t *out_buff;
const size_t buf_size = 4096;
unsigned int in_buf_size = 4096;
int i;
ResetStub();
in_fmt.format = SND_PCM_FORMAT_S32_LE;
out_fmt.format = SND_PCM_FORMAT_S16_LE;
in_fmt.num_channels = 6;
out_fmt.num_channels = 2;
in_fmt.frame_rate = 48000;
out_fmt.frame_rate = 48000;
for (i = 0; i < CRAS_CH_MAX; i++)
in_fmt.channel_layout[i] = surround_channel_layout[i];
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
ASSERT_NE(c, (void *)NULL);
out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
EXPECT_EQ(buf_size, out_frames);
in_buff = (int32_t *)ralloc(buf_size * 2 * cras_get_format_bytes(&in_fmt));
out_buff = (int16_t *)ralloc(buf_size * cras_get_format_bytes(&out_fmt));
out_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
buf_size);
EXPECT_EQ(buf_size, out_frames);
cras_fmt_conv_destroy(c);
free(in_buff);
free(out_buff);
}
// Test 16 bit stereo to 5.1 conversion.
TEST(FormatConverterTest, ConvertS16LEToS16LEStereoTo51) {
struct cras_fmt_conv *c;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
size_t out_frames;
int16_t *in_buff;
int16_t *out_buff;
const size_t buf_size = 4096;
unsigned int in_buf_size = 4096;
int i;
ResetStub();
in_fmt.format = SND_PCM_FORMAT_S16_LE;
out_fmt.format = SND_PCM_FORMAT_S16_LE;
in_fmt.num_channels = 2;
out_fmt.num_channels = 6;
in_fmt.frame_rate = 48000;
out_fmt.frame_rate = 48000;
for (i = 0; i < CRAS_CH_MAX; i++)
out_fmt.channel_layout[i] = surround_channel_layout[i];
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
ASSERT_NE(c, (void *)NULL);
out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
EXPECT_EQ(buf_size, out_frames);
in_buff = (int16_t *)ralloc(buf_size * cras_get_format_bytes(&in_fmt));
out_buff = (int16_t *)ralloc(buf_size * cras_get_format_bytes(&out_fmt));
out_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
buf_size);
EXPECT_EQ(buf_size, out_frames);
for (unsigned int i = 0; i < buf_size; i++) {
/* Check mono be converted to CRAS_CH_FL and CRAS_CH_FR */
EXPECT_EQ(in_buff[2 * i], out_buff[6 * i]);
EXPECT_EQ(in_buff[2 * i + 1], out_buff[6 * i + 1]);
EXPECT_EQ(0, out_buff[6 * i + 2]);
EXPECT_EQ(0, out_buff[6 * i + 3]);
EXPECT_EQ(0, out_buff[6 * i + 4]);
EXPECT_EQ(0, out_buff[6 * i + 5]);
}
cras_fmt_conv_destroy(c);
free(in_buff);
free(out_buff);
}
// Test 16 bit mono to 5.1 conversion.
TEST(FormatConverterTest, ConvertS16LEToS16LEMonoTo51) {
struct cras_fmt_conv *c;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
size_t out_frames;
int16_t *in_buff;
int16_t *out_buff;
const size_t buf_size = 4096;
unsigned int in_buf_size = 4096;
int i;
ResetStub();
in_fmt.format = SND_PCM_FORMAT_S16_LE;
out_fmt.format = SND_PCM_FORMAT_S16_LE;
in_fmt.num_channels = 1;
out_fmt.num_channels = 6;
in_fmt.frame_rate = 48000;
out_fmt.frame_rate = 48000;
for (i = 0; i < CRAS_CH_MAX; i++)
out_fmt.channel_layout[i] = surround_channel_layout[i];
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
ASSERT_NE(c, (void *)NULL);
out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
EXPECT_EQ(buf_size, out_frames);
in_buff = (int16_t *)ralloc(buf_size * cras_get_format_bytes(&in_fmt));
out_buff = (int16_t *)ralloc(buf_size * cras_get_format_bytes(&out_fmt));
out_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
buf_size);
EXPECT_EQ(buf_size, out_frames);
for (unsigned int i = 0; i < buf_size; i++) {
/* Check mono be converted to CRAS_CH_FC */
EXPECT_EQ(in_buff[i], out_buff[6 * i + 4]);
EXPECT_EQ(0, out_buff[6 * i + 0]);
EXPECT_EQ(0, out_buff[6 * i + 1]);
EXPECT_EQ(0, out_buff[6 * i + 2]);
EXPECT_EQ(0, out_buff[6 * i + 3]);
EXPECT_EQ(0, out_buff[6 * i + 5]);
}
cras_fmt_conv_destroy(c);
free(in_buff);
free(out_buff);
}
// Test 32 bit 5.1 to 16 bit stereo conversion with SRC 1 to 2.
TEST(FormatConverterTest, ConvertS32LEToS16LEDownmix51ToStereo48To96) {
struct cras_fmt_conv *c;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
size_t out_frames;
int32_t *in_buff;
int16_t *out_buff;
const size_t buf_size = 4096;
unsigned int in_buf_size = 4096;
int i;
ResetStub();
in_fmt.format = SND_PCM_FORMAT_S32_LE;
out_fmt.format = SND_PCM_FORMAT_S16_LE;
in_fmt.num_channels = 6;
out_fmt.num_channels = 2;
in_fmt.frame_rate = 48000;
out_fmt.frame_rate = 96000;
for (i = 0; i < CRAS_CH_MAX; i++)
in_fmt.channel_layout[i] = surround_channel_layout[i];
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
ASSERT_NE(c, (void *)NULL);
out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
EXPECT_EQ(buf_size * 2, out_frames);
in_buff = (int32_t *)ralloc(buf_size * cras_get_format_bytes(&in_fmt));
out_buff = (int16_t *)ralloc(buf_size * 2 * cras_get_format_bytes(&out_fmt));
out_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
buf_size * 2);
EXPECT_EQ(buf_size * 2, out_frames);
cras_fmt_conv_destroy(c);
free(in_buff);
free(out_buff);
}
// Test 32 bit 5.1 to 16 bit stereo conversion with SRC 2 to 1.
TEST(FormatConverterTest, ConvertS32LEToS16LEDownmix51ToStereo96To48) {
struct cras_fmt_conv *c;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
size_t out_frames;
int32_t *in_buff;
int16_t *out_buff;
const size_t buf_size = 4096;
unsigned int in_buf_size = 4096;
int i;
ResetStub();
in_fmt.format = SND_PCM_FORMAT_S32_LE;
out_fmt.format = SND_PCM_FORMAT_S16_LE;
in_fmt.num_channels = 6;
out_fmt.num_channels = 2;
in_fmt.frame_rate = 96000;
out_fmt.frame_rate = 48000;
for (i = 0; i < CRAS_CH_MAX; i++)
in_fmt.channel_layout[i] = surround_channel_layout[i];
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
ASSERT_NE(c, (void *)NULL);
out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
EXPECT_EQ(buf_size / 2, out_frames);
in_buff = (int32_t *)ralloc(buf_size * cras_get_format_bytes(&in_fmt));
out_buff = (int16_t *)ralloc(buf_size / 2 * cras_get_format_bytes(&out_fmt));
out_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
buf_size / 2);
EXPECT_EQ(buf_size / 2, out_frames);
cras_fmt_conv_destroy(c);
free(in_buff);
free(out_buff);
}
// Test 32 bit 5.1 to 16 bit stereo conversion with SRC 48 to 44.1.
TEST(FormatConverterTest, ConvertS32LEToS16LEDownmix51ToStereo48To441) {
struct cras_fmt_conv *c;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
size_t out_frames;
size_t ret_frames;
int32_t *in_buff;
int16_t *out_buff;
const size_t buf_size = 4096;
unsigned int in_buf_size = 4096;
int i;
ResetStub();
in_fmt.format = SND_PCM_FORMAT_S32_LE;
out_fmt.format = SND_PCM_FORMAT_S16_LE;
in_fmt.num_channels = 6;
out_fmt.num_channels = 2;
in_fmt.frame_rate = 48000;
out_fmt.frame_rate = 44100;
for (i = 0; i < CRAS_CH_MAX; i++)
in_fmt.channel_layout[i] = surround_channel_layout[i];
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
ASSERT_NE(c, (void *)NULL);
out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
EXPECT_LT(out_frames, buf_size);
in_buff = (int32_t *)ralloc(buf_size * cras_get_format_bytes(&in_fmt));
out_buff = (int16_t *)ralloc(out_frames * cras_get_format_bytes(&out_fmt));
ret_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
out_frames);
EXPECT_EQ(out_frames, ret_frames);
cras_fmt_conv_destroy(c);
free(in_buff);
free(out_buff);
}
// Test 32 bit 5.1 to 16 bit stereo conversion with SRC 441 to 48.
TEST(FormatConverterTest, ConvertS32LEToS16LEDownmix51ToStereo441To48) {
struct cras_fmt_conv *c;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
size_t out_frames;
size_t ret_frames;
int32_t *in_buff;
int16_t *out_buff;
const size_t buf_size = 4096;
unsigned int in_buf_size = 4096;
int i;
ResetStub();
in_fmt.format = SND_PCM_FORMAT_S32_LE;
out_fmt.format = SND_PCM_FORMAT_S16_LE;
in_fmt.num_channels = 6;
out_fmt.num_channels = 2;
in_fmt.frame_rate = 44100;
out_fmt.frame_rate = 48000;
for (i = 0; i < CRAS_CH_MAX; i++)
in_fmt.channel_layout[i] = surround_channel_layout[i];
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
ASSERT_NE(c, (void *)NULL);
out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
EXPECT_GT(out_frames, buf_size);
in_buff = (int32_t *)ralloc(buf_size * cras_get_format_bytes(&in_fmt));
out_buff = (int16_t *)ralloc((out_frames - 1) *
cras_get_format_bytes(&out_fmt));
ret_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
out_frames - 1);
EXPECT_EQ(out_frames - 1, ret_frames);
cras_fmt_conv_destroy(c);
free(in_buff);
free(out_buff);
}
// Test Invalid buffer length just truncates.
TEST(FormatConverterTest, ConvertS32LEToS16LEDownmix51ToStereo96To48Short) {
struct cras_fmt_conv *c;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
size_t out_frames;
size_t ret_frames;
int32_t *in_buff;
int16_t *out_buff;
const size_t buf_size = 4096;
unsigned int in_buf_size = 4096;
int i;
ResetStub();
in_fmt.format = SND_PCM_FORMAT_S32_LE;
out_fmt.format = SND_PCM_FORMAT_S16_LE;
in_fmt.num_channels = 6;
out_fmt.num_channels = 2;
in_fmt.frame_rate = 96000;
out_fmt.frame_rate = 48000;
for (i = 0; i < CRAS_CH_MAX; i++)
in_fmt.channel_layout[i] = surround_channel_layout[i];
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
ASSERT_NE(c, (void *)NULL);
out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
EXPECT_EQ(buf_size / 2, out_frames);
in_buff = (int32_t *)ralloc(buf_size * cras_get_format_bytes(&in_fmt));
out_buff = (int16_t *)ralloc((out_frames - 2) *
cras_get_format_bytes(&out_fmt));
ret_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
out_frames - 2);
EXPECT_EQ(out_frames - 2, ret_frames);
cras_fmt_conv_destroy(c);
free(in_buff);
free(out_buff);
}
// Test format convert pre linear resample and then follows SRC from 96 to 48.
TEST(FormatConverterTest, Convert96to48PreLinearResample) {
struct cras_fmt_conv *c;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
size_t out_frames;
int32_t *in_buff;
int16_t *out_buff;
const size_t buf_size = 4096;
unsigned int in_buf_size = 4096;
unsigned int expected_fr;
int i;
ResetStub();
in_fmt.format = SND_PCM_FORMAT_S16_LE;
out_fmt.format = SND_PCM_FORMAT_S16_LE;
in_fmt.num_channels = 2;
out_fmt.num_channels = 2;
in_fmt.frame_rate = 96000;
out_fmt.frame_rate = 48000;
for (i = 0; i < CRAS_CH_MAX; i++) {
in_fmt.channel_layout[i] = surround_channel_layout[i];
out_fmt.channel_layout[i] = surround_channel_layout[i];
}
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size * 2, 1);
ASSERT_NE(c, (void *)NULL);
linear_resampler_needed_val = 1;
linear_resampler_ratio = 1.01;
expected_fr = buf_size / 2 * linear_resampler_ratio;
out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
EXPECT_EQ(expected_fr, out_frames);
in_buff = (int32_t *)ralloc(buf_size * cras_get_format_bytes(&in_fmt));
out_buff = (int16_t *)ralloc(buf_size * cras_get_format_bytes(&out_fmt));
out_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
out_frames);
EXPECT_EQ(expected_fr, out_frames);
cras_fmt_conv_destroy(c);
free(in_buff);
free(out_buff);
}
// Test format convert SRC from 96 to 48 and then post linear resample.
TEST(FormatConverterTest, Convert96to48PostLinearResample) {
struct cras_fmt_conv *c;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
size_t out_frames;
int32_t *in_buff;
int16_t *out_buff;
const size_t buf_size = 4096;
unsigned int in_buf_size = 4096;
unsigned int expected_fr;
int i;
ResetStub();
in_fmt.format = SND_PCM_FORMAT_S16_LE;
out_fmt.format = SND_PCM_FORMAT_S16_LE;
in_fmt.num_channels = 2;
out_fmt.num_channels = 2;
in_fmt.frame_rate = 96000;
out_fmt.frame_rate = 48000;
for (i = 0; i < CRAS_CH_MAX; i++) {
in_fmt.channel_layout[i] = surround_channel_layout[i];
out_fmt.channel_layout[i] = surround_channel_layout[i];
}
c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size * 2, 0);
ASSERT_NE(c, (void *)NULL);
linear_resampler_needed_val = 1;
linear_resampler_ratio = 0.99;
expected_fr = buf_size / 2 * linear_resampler_ratio;
out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
EXPECT_EQ(expected_fr, out_frames);
in_buff = (int32_t *)ralloc(buf_size * cras_get_format_bytes(&in_fmt));
out_buff = (int16_t *)ralloc(buf_size * cras_get_format_bytes(&out_fmt));
out_frames = cras_fmt_conv_convert_frames(c,
(uint8_t *)in_buff,
(uint8_t *)out_buff,
&in_buf_size,
buf_size);
EXPECT_EQ(expected_fr, out_frames);
cras_fmt_conv_destroy(c);
free(in_buff);
free(out_buff);
}
// Test format converter created in config_format_converter
TEST(FormatConverterTest, ConfigConverter) {
int i;
struct cras_fmt_conv *c = NULL;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
ResetStub();
in_fmt.format = SND_PCM_FORMAT_S16_LE;
out_fmt.format = SND_PCM_FORMAT_S16_LE;
in_fmt.num_channels = 1;
out_fmt.num_channels = 2;
in_fmt.frame_rate = 96000;
out_fmt.frame_rate = 48000;
for (i = 0; i < CRAS_CH_MAX; i++) {
in_fmt.channel_layout[i] = mono_channel_layout[i];
out_fmt.channel_layout[i] = stereo_channel_layout[i];
}
config_format_converter(&c, CRAS_STREAM_OUTPUT, &in_fmt, &out_fmt, 4096);
ASSERT_NE(c, (void *)NULL);
cras_fmt_conv_destroy(c);
}
// Test format converter not created when in/out format conversion is not
// needed.
TEST(FormatConverterTest, ConfigConverterNoNeed) {
int i;
struct cras_fmt_conv *c = NULL;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
ResetStub();
in_fmt.format = SND_PCM_FORMAT_S16_LE;
out_fmt.format = SND_PCM_FORMAT_S16_LE;
in_fmt.num_channels = 2;
out_fmt.num_channels = 2;
in_fmt.frame_rate = 48000;
out_fmt.frame_rate = 48000;
for (i = 0; i < CRAS_CH_MAX; i++) {
in_fmt.channel_layout[i] = stereo_channel_layout[i];
out_fmt.channel_layout[i] = stereo_channel_layout[i];
}
config_format_converter(&c, CRAS_STREAM_OUTPUT, &in_fmt, &out_fmt, 4096);
EXPECT_NE(c, (void *)NULL);
EXPECT_EQ(0, cras_fmt_conversion_needed(c));
}
// Test format converter not created for input when in/out format differs
// at channel count or layout.
TEST(FormatConverterTest, ConfigConverterNoNeedForInput) {
static int kmic_channel_layout[CRAS_CH_MAX] =
{0, 1, -1, -1, 2, -1, -1, -1, -1, -1, -1};
int i;
struct cras_fmt_conv *c = NULL;
struct cras_audio_format in_fmt;
struct cras_audio_format out_fmt;
ResetStub();
in_fmt.format = SND_PCM_FORMAT_S16_LE;
out_fmt.format = SND_PCM_FORMAT_S16_LE;
in_fmt.num_channels = 2;
out_fmt.num_channels = 3;
in_fmt.frame_rate = 48000;
out_fmt.frame_rate = 48000;
for (i = 0; i < CRAS_CH_MAX; i++) {
in_fmt.channel_layout[i] = stereo_channel_layout[i];
out_fmt.channel_layout[i] = kmic_channel_layout[i];
}
config_format_converter(&c, CRAS_STREAM_INPUT, &in_fmt, &out_fmt, 4096);
EXPECT_NE(c, (void *)NULL);
EXPECT_EQ(0, cras_fmt_conversion_needed(c));
}
TEST(ChannelRemixTest, ChannelRemixAppliedOrNot) {
float coeff[4] = {0.5, 0.5, 0.26, 0.73};
struct cras_fmt_conv *conv;
struct cras_audio_format fmt;
int16_t *buf, *res;
unsigned i;
fmt.num_channels = 2;
conv = cras_channel_remix_conv_create(2, coeff);
buf = (int16_t *)ralloc(50 * 4);
res = (int16_t *)malloc(50 * 4);
for (i = 0; i < 100; i += 2) {
res[i] = coeff[0] * buf[i];
res[i] += coeff[1] * buf[i + 1];
res[i + 1] = coeff[2] * buf[i];
res[i + 1] += coeff[3] * buf[i + 1];
}
cras_channel_remix_convert(conv, &fmt, (uint8_t *)buf, 50);
for (i = 0; i < 100; i++)
EXPECT_EQ(res[i], buf[i]);
/* If num_channels not match, remix conversion will not apply. */
fmt.num_channels = 6;
cras_channel_remix_convert(conv, &fmt, (uint8_t *)buf, 50);
for (i = 0; i < 100; i++)
EXPECT_EQ(res[i], buf[i]);
cras_fmt_conv_destroy(conv);
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
extern "C" {
float** cras_channel_conv_matrix_alloc(size_t in_ch, size_t out_ch)
{
int i;
float** conv_mtx;
conv_mtx = (float **)calloc(CRAS_CH_MAX, sizeof(*conv_mtx));
for (i = 0; i < CRAS_CH_MAX; i++)
conv_mtx[i] = (float *)calloc(CRAS_CH_MAX, sizeof(*conv_mtx[i]));
return conv_mtx;
}
void cras_channel_conv_matrix_destroy(float **mtx, size_t out_ch)
{
int i;
for (i = 0; i < CRAS_CH_MAX; i++)
free(mtx[i]);
free(mtx);
}
float **cras_channel_conv_matrix_create(const struct cras_audio_format *in,
const struct cras_audio_format *out)
{
return cras_channel_conv_matrix_alloc(in->num_channels,
out->num_channels);
}
struct linear_resampler *linear_resampler_create(unsigned int num_channels,
unsigned int format_bytes,
float src_rate,
float dst_rate)
{
return reinterpret_cast<struct linear_resampler*>(0x33);;
}
int linear_resampler_needed(struct linear_resampler *lr)
{
return linear_resampler_needed_val;
}
void linear_resampler_set_rates(struct linear_resampler *lr,
unsigned int from,
unsigned int to)
{
}
unsigned int linear_resampler_out_frames_to_in(struct linear_resampler *lr,
unsigned int frames)
{
return (double)frames / linear_resampler_ratio;
}
/* Converts the frames count from input rate to output rate. */
unsigned int linear_resampler_in_frames_to_out(struct linear_resampler *lr,
unsigned int frames)
{
return (double)frames * linear_resampler_ratio;
}
unsigned int linear_resampler_resample(struct linear_resampler *lr,
uint8_t *src,
unsigned int *src_frames,
uint8_t *dst,
unsigned dst_frames)
{
unsigned int resampled_fr = *src_frames * linear_resampler_ratio;
if (resampled_fr > dst_frames) {
resampled_fr = dst_frames;
*src_frames = dst_frames / linear_resampler_ratio;
}
return resampled_fr;
}
void linear_resampler_destroy(struct linear_resampler *lr)
{
}
} // extern "C"