/* 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 <stdint.h>

#include "cras_system_state.h"
#include "cras_mix_ops.h"

#define MAX_VOLUME_TO_SCALE 0.9999999
#define MIN_VOLUME_TO_SCALE 0.0000001

/* function suffixes for SIMD ops */
#ifdef OPS_SSE42
#define OPS(a) a##_sse42
#elif OPS_AVX
#define OPS(a) a##_avx
#elif OPS_AVX2
#define OPS(a) a##_avx2
#elif OPS_FMA
#define OPS(a) a##_fma
#else
#define OPS(a) a
#endif

/* Checks if the scaler needs a scaling operation.
 * We skip scaling for scaler too close to 1.0.
 * Note that this is not subjected to MAX_VOLUME_TO_SCALE
 * and MIN_VOLUME_TO_SCALE. */
static inline int need_to_scale(float scaler)
{
	return (scaler < 0.99 || scaler > 1.01);
}

/*
 * Signed 16 bit little endian functions.
 */

static void cras_mix_add_clip_s16_le(int16_t *dst, const int16_t *src,
				     size_t count)
{
	int32_t sum;
	size_t i;

	for (i = 0; i < count; i++) {
		sum = dst[i] + src[i];
		if (sum > INT16_MAX)
			sum = INT16_MAX;
		else if (sum < INT16_MIN)
			sum = INT16_MIN;
		dst[i] = sum;
	}
}

/* Adds src into dst, after scaling by vol.
 * Just hard limits to the min and max S16 value, can be improved later. */
static void scale_add_clip_s16_le(int16_t *dst, const int16_t *src,
				  size_t count, float vol)
{
	int32_t sum;
	size_t i;

	if (vol > MAX_VOLUME_TO_SCALE)
		return cras_mix_add_clip_s16_le(dst, src, count);

	for (i = 0; i < count; i++) {
		sum = dst[i] + (int16_t)(src[i] * vol);
		if (sum > INT16_MAX)
			sum = INT16_MAX;
		else if (sum < INT16_MIN)
			sum = INT16_MIN;
		dst[i] = sum;
	}
}

/* Adds the first stream to the mix.  Don't need to mix, just setup to the new
 * values. If volume is 1.0, just memcpy. */
static void copy_scaled_s16_le(int16_t *dst, const int16_t *src, size_t count,
			       float volume_scaler)
{
	int i;

	if (volume_scaler > MAX_VOLUME_TO_SCALE) {
		memcpy(dst, src, count * sizeof(*src));
		return;
	}

	for (i = 0; i < count; i++)
		dst[i] = src[i] * volume_scaler;
}

static void cras_scale_buffer_inc_s16_le(uint8_t *buffer, unsigned int count,
					 float scaler, float increment,
					 float target, int step)
{
	int i = 0, j;
	int16_t *out = (int16_t *)buffer;

	if (scaler < MIN_VOLUME_TO_SCALE && increment < 0) {
		memset(out, 0, count * sizeof(*out));
		return;
	}

	while (i + step <= count) {
		for (j = 0; j < step; j++) {
			float applied_scaler = scaler;

			if ((applied_scaler > target && increment > 0) ||
			    (applied_scaler < target && increment < 0))
				applied_scaler = target;

			if (applied_scaler > MAX_VOLUME_TO_SCALE) {
			} else if (applied_scaler < MIN_VOLUME_TO_SCALE) {
				out[i] = 0;
			} else {
				out[i] *= applied_scaler;
			}
			i++;
		}
		scaler += increment;
	}
}

static void cras_scale_buffer_s16_le(uint8_t *buffer, unsigned int count,
				     float scaler)
{
	int i;
	int16_t *out = (int16_t *)buffer;

	if (scaler > MAX_VOLUME_TO_SCALE)
		return;

	if (scaler < MIN_VOLUME_TO_SCALE) {
		memset(out, 0, count * sizeof(*out));
		return;
	}

	for (i = 0; i < count; i++)
		out[i] *= scaler;
}

static void cras_mix_add_s16_le(uint8_t *dst, uint8_t *src, unsigned int count,
				unsigned int index, int mute, float mix_vol)
{
	int16_t *out = (int16_t *)dst;
	int16_t *in = (int16_t *)src;

	if (mute || (mix_vol < MIN_VOLUME_TO_SCALE)) {
		if (index == 0)
			memset(out, 0, count * sizeof(*out));
		return;
	}

	if (index == 0)
		return copy_scaled_s16_le(out, in, count, mix_vol);

	scale_add_clip_s16_le(out, in, count, mix_vol);
}

static void cras_mix_add_scale_stride_s16_le(uint8_t *dst, uint8_t *src,
					     unsigned int dst_stride,
					     unsigned int src_stride,
					     unsigned int count, float scaler)
{
	unsigned int i;

	/* optimise the loops for vectorization */
	if (dst_stride == src_stride && dst_stride == 2) {
		for (i = 0; i < count; i++) {
			int32_t sum;
			if (need_to_scale(scaler))
				sum = *(int16_t *)dst +
				      *(int16_t *)src * scaler;
			else
				sum = *(int16_t *)dst + *(int16_t *)src;
			if (sum > INT16_MAX)
				sum = INT16_MAX;
			else if (sum < INT16_MIN)
				sum = INT16_MIN;
			*(int16_t *)dst = sum;
			dst += 2;
			src += 2;
		}
	} else if (dst_stride == src_stride && dst_stride == 4) {
		for (i = 0; i < count; i++) {
			int32_t sum;
			if (need_to_scale(scaler))
				sum = *(int16_t *)dst +
				      *(int16_t *)src * scaler;
			else
				sum = *(int16_t *)dst + *(int16_t *)src;
			if (sum > INT16_MAX)
				sum = INT16_MAX;
			else if (sum < INT16_MIN)
				sum = INT16_MIN;
			*(int16_t *)dst = sum;
			dst += 4;
			src += 4;
		}
	} else {
		for (i = 0; i < count; i++) {
			int32_t sum;
			if (need_to_scale(scaler))
				sum = *(int16_t *)dst +
				      *(int16_t *)src * scaler;
			else
				sum = *(int16_t *)dst + *(int16_t *)src;
			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;
		}
	}
}

/*
 * Signed 24 bit little endian functions.
 */

static int32_t scale_s24_le(int32_t value, float scaler)
{
	value = ((uint32_t)(value & 0x00ffffff)) << 8;
	value *= scaler;
	return (value >> 8) & 0x00ffffff;
}

static void cras_mix_add_clip_s24_le(int32_t *dst, const int32_t *src,
				     size_t count)
{
	int32_t sum;
	size_t i;

	for (i = 0; i < count; i++) {
		sum = dst[i] + src[i];
		if (sum > 0x007fffff)
			sum = 0x007fffff;
		else if (sum < (int32_t)0xff800000)
			sum = (int32_t)0xff800000;
		dst[i] = sum;
	}
}

/* Adds src into dst, after scaling by vol.
 * Just hard limits to the min and max S24 value, can be improved later. */
static void scale_add_clip_s24_le(int32_t *dst, const int32_t *src,
				  size_t count, float vol)
{
	int32_t sum;
	size_t i;

	if (vol > MAX_VOLUME_TO_SCALE)
		return cras_mix_add_clip_s24_le(dst, src, count);

	for (i = 0; i < count; i++) {
		sum = dst[i] + (int32_t)(src[i] * vol);
		if (sum > 0x007fffff)
			sum = 0x007fffff;
		else if (sum < (int32_t)0xff800000)
			sum = (int32_t)0xff800000;
		dst[i] = sum;
	}
}

/* Adds the first stream to the mix.  Don't need to mix, just setup to the new
 * values. If volume is 1.0, just memcpy. */
static void copy_scaled_s24_le(int32_t *dst, const int32_t *src, size_t count,
			       float volume_scaler)
{
	int i;

	if (volume_scaler > MAX_VOLUME_TO_SCALE) {
		memcpy(dst, src, count * sizeof(*src));
		return;
	}

	for (i = 0; i < count; i++)
		dst[i] = scale_s24_le(src[i], volume_scaler);
}

static void cras_scale_buffer_inc_s24_le(uint8_t *buffer, unsigned int count,
					 float scaler, float increment,
					 float target, int step)
{
	int i = 0, j;
	int32_t *out = (int32_t *)buffer;

	if (scaler < MIN_VOLUME_TO_SCALE && increment < 0) {
		memset(out, 0, count * sizeof(*out));
		return;
	}

	while (i + step <= count) {
		for (j = 0; j < step; j++) {
			float applied_scaler = scaler;

			if ((applied_scaler > target && increment > 0) ||
			    (applied_scaler < target && increment < 0))
				applied_scaler = target;

			if (applied_scaler > MAX_VOLUME_TO_SCALE) {
			} else if (applied_scaler < MIN_VOLUME_TO_SCALE) {
				out[i] = 0;
			} else {
				out[i] = scale_s24_le(out[i], applied_scaler);
			}
			i++;
		}
		scaler += increment;
	}
}

static void cras_scale_buffer_s24_le(uint8_t *buffer, unsigned int count,
				     float scaler)
{
	int i;
	int32_t *out = (int32_t *)buffer;

	if (scaler > MAX_VOLUME_TO_SCALE)
		return;

	if (scaler < MIN_VOLUME_TO_SCALE) {
		memset(out, 0, count * sizeof(*out));
		return;
	}

	for (i = 0; i < count; i++)
		out[i] = scale_s24_le(out[i], scaler);
}

static void cras_mix_add_s24_le(uint8_t *dst, uint8_t *src, unsigned int count,
				unsigned int index, int mute, float mix_vol)
{
	int32_t *out = (int32_t *)dst;
	int32_t *in = (int32_t *)src;

	if (mute || (mix_vol < MIN_VOLUME_TO_SCALE)) {
		if (index == 0)
			memset(out, 0, count * sizeof(*out));
		return;
	}

	if (index == 0)
		return copy_scaled_s24_le(out, in, count, mix_vol);

	scale_add_clip_s24_le(out, in, count, mix_vol);
}

static void cras_mix_add_scale_stride_s24_le(uint8_t *dst, uint8_t *src,
					     unsigned int dst_stride,
					     unsigned int src_stride,
					     unsigned int count, float scaler)
{
	unsigned int i;

	/* optimise the loops for vectorization */
	if (dst_stride == src_stride && dst_stride == 4) {
		for (i = 0; i < count; i++) {
			int32_t sum;
			if (need_to_scale(scaler))
				sum = *(int32_t *)dst +
				      scale_s24_le(*(int32_t *)src, scaler);
			else
				sum = *(int32_t *)dst + *(int32_t *)src;
			if (sum > 0x007fffff)
				sum = 0x007fffff;
			else if (sum < (int32_t)0xff800000)
				sum = (int32_t)0xff800000;
			*(int32_t *)dst = sum;
			dst += 4;
			src += 4;
		}
	} else {
		for (i = 0; i < count; i++) {
			int32_t sum;
			if (need_to_scale(scaler))
				sum = *(int32_t *)dst +
				      scale_s24_le(*(int32_t *)src, scaler);
			else
				sum = *(int32_t *)dst + *(int32_t *)src;
			if (sum > 0x007fffff)
				sum = 0x007fffff;
			else if (sum < (int32_t)0xff800000)
				sum = (int32_t)0xff800000;
			*(int32_t *)dst = sum;
			dst += dst_stride;
			src += src_stride;
		}
	}
}

/*
 * Signed 32 bit little endian functions.
 */

static void cras_mix_add_clip_s32_le(int32_t *dst, const int32_t *src,
				     size_t count)
{
	int64_t sum;
	size_t i;

	for (i = 0; i < count; i++) {
		sum = (int64_t)dst[i] + (int64_t)src[i];
		if (sum > INT32_MAX)
			sum = INT32_MAX;
		else if (sum < INT32_MIN)
			sum = INT32_MIN;
		dst[i] = sum;
	}
}

/* Adds src into dst, after scaling by vol.
 * Just hard limits to the min and max S32 value, can be improved later. */
static void scale_add_clip_s32_le(int32_t *dst, const int32_t *src,
				  size_t count, float vol)
{
	int64_t sum;
	size_t i;

	if (vol > MAX_VOLUME_TO_SCALE)
		return cras_mix_add_clip_s32_le(dst, src, count);

	for (i = 0; i < count; i++) {
		sum = (int64_t)dst[i] + (int64_t)(src[i] * vol);
		if (sum > INT32_MAX)
			sum = INT32_MAX;
		else if (sum < INT32_MIN)
			sum = INT32_MIN;
		dst[i] = sum;
	}
}

/* Adds the first stream to the mix.  Don't need to mix, just setup to the new
 * values. If volume is 1.0, just memcpy. */
static void copy_scaled_s32_le(int32_t *dst, const int32_t *src, size_t count,
			       float volume_scaler)
{
	int i;

	if (volume_scaler > MAX_VOLUME_TO_SCALE) {
		memcpy(dst, src, count * sizeof(*src));
		return;
	}

	for (i = 0; i < count; i++)
		dst[i] = src[i] * volume_scaler;
}

static void cras_scale_buffer_inc_s32_le(uint8_t *buffer, unsigned int count,
					 float scaler, float increment,
					 float target, int step)
{
	int i = 0, j;
	int32_t *out = (int32_t *)buffer;

	if (scaler < MIN_VOLUME_TO_SCALE && increment < 0) {
		memset(out, 0, count * sizeof(*out));
		return;
	}

	while (i + step <= count) {
		for (j = 0; j < step; j++) {
			float applied_scaler = scaler;

			if ((applied_scaler > target && increment > 0) ||
			    (applied_scaler < target && increment < 0))
				applied_scaler = target;

			if (applied_scaler > MAX_VOLUME_TO_SCALE) {
			} else if (applied_scaler < MIN_VOLUME_TO_SCALE) {
				out[i] = 0;
			} else {
				out[i] *= applied_scaler;
			}
			i++;
		}
		scaler += increment;
	}
}

static void cras_scale_buffer_s32_le(uint8_t *buffer, unsigned int count,
				     float scaler)
{
	int i;
	int32_t *out = (int32_t *)buffer;

	if (scaler > MAX_VOLUME_TO_SCALE)
		return;

	if (scaler < MIN_VOLUME_TO_SCALE) {
		memset(out, 0, count * sizeof(*out));
		return;
	}

	for (i = 0; i < count; i++)
		out[i] *= scaler;
}

static void cras_mix_add_s32_le(uint8_t *dst, uint8_t *src, unsigned int count,
				unsigned int index, int mute, float mix_vol)
{
	int32_t *out = (int32_t *)dst;
	int32_t *in = (int32_t *)src;

	if (mute || (mix_vol < MIN_VOLUME_TO_SCALE)) {
		if (index == 0)
			memset(out, 0, count * sizeof(*out));
		return;
	}

	if (index == 0)
		return copy_scaled_s32_le(out, in, count, mix_vol);

	scale_add_clip_s32_le(out, in, count, mix_vol);
}

static void cras_mix_add_scale_stride_s32_le(uint8_t *dst, uint8_t *src,
					     unsigned int dst_stride,
					     unsigned int src_stride,
					     unsigned int count, float scaler)
{
	unsigned int i;

	/* optimise the loops for vectorization */
	if (dst_stride == src_stride && dst_stride == 4) {
		for (i = 0; i < count; i++) {
			int64_t sum;
			if (need_to_scale(scaler))
				sum = *(int32_t *)dst +
				      *(int32_t *)src * scaler;
			else
				sum = *(int32_t *)dst + *(int32_t *)src;
			if (sum > INT32_MAX)
				sum = INT32_MAX;
			else if (sum < INT32_MIN)
				sum = INT32_MIN;
			*(int32_t *)dst = sum;
			dst += 4;
			src += 4;
		}
	} else {
		for (i = 0; i < count; i++) {
			int64_t sum;
			if (need_to_scale(scaler))
				sum = *(int32_t *)dst +
				      *(int32_t *)src * scaler;
			else
				sum = *(int32_t *)dst + *(int32_t *)src;
			if (sum > INT32_MAX)
				sum = INT32_MAX;
			else if (sum < INT32_MIN)
				sum = INT32_MIN;
			*(int32_t *)dst = sum;
			dst += dst_stride;
			src += src_stride;
		}
	}
}

/*
 * Signed 24 bit little endian in three bytes functions.
 */

/* Convert 3bytes Signed 24bit integer to a Signed 32bit integer.
 * Just a helper function. */
static inline void convert_single_s243le_to_s32le(int32_t *dst,
						  const uint8_t *src)
{
	*dst = 0;
	memcpy((uint8_t *)dst + 1, src, 3);
}

static inline void convert_single_s32le_to_s243le(uint8_t *dst,
						  const int32_t *src)
{
	memcpy(dst, (uint8_t *)src + 1, 3);
}

static void cras_mix_add_clip_s24_3le(uint8_t *dst, const uint8_t *src,
				      size_t count)
{
	int64_t sum;
	int32_t dst_frame;
	int32_t src_frame;
	size_t i;

	for (i = 0; i < count; i++, dst += 3, src += 3) {
		convert_single_s243le_to_s32le(&dst_frame, dst);
		convert_single_s243le_to_s32le(&src_frame, src);
		sum = (int64_t)dst_frame + (int64_t)src_frame;
		if (sum > INT32_MAX)
			sum = INT32_MAX;
		else if (sum < INT32_MIN)
			sum = INT32_MIN;
		dst_frame = (int32_t)sum;
		convert_single_s32le_to_s243le(dst, &dst_frame);
	}
}

/* Adds src into dst, after scaling by vol.
 * Just hard limits to the min and max S24 value, can be improved later. */
static void scale_add_clip_s24_3le(uint8_t *dst, const uint8_t *src,
				   size_t count, float vol)
{
	int64_t sum;
	int32_t dst_frame;
	int32_t src_frame;
	size_t i;

	if (vol > MAX_VOLUME_TO_SCALE)
		return cras_mix_add_clip_s24_3le(dst, src, count);

	for (i = 0; i < count; i++, dst += 3, src += 3) {
		convert_single_s243le_to_s32le(&dst_frame, dst);
		convert_single_s243le_to_s32le(&src_frame, src);
		sum = (int64_t)dst_frame + (int64_t)(src_frame * vol);
		if (sum > INT32_MAX)
			sum = INT32_MAX;
		else if (sum < INT32_MIN)
			sum = INT32_MIN;
		dst_frame = (int32_t)sum;
		convert_single_s32le_to_s243le(dst, &dst_frame);
	}
}

/* Adds the first stream to the mix.  Don't need to mix, just setup to the new
 * values. If volume is 1.0, just memcpy. */
static void copy_scaled_s24_3le(uint8_t *dst, const uint8_t *src, size_t count,
				float volume_scaler)
{
	int32_t frame;
	size_t i;

	if (volume_scaler > MAX_VOLUME_TO_SCALE) {
		memcpy(dst, src, 3 * count * sizeof(*src));
		return;
	}

	for (i = 0; i < count; i++, dst += 3, src += 3) {
		convert_single_s243le_to_s32le(&frame, src);
		frame *= volume_scaler;
		convert_single_s32le_to_s243le(dst, &frame);
	}
}

static void cras_scale_buffer_inc_s24_3le(uint8_t *buffer, unsigned int count,
					  float scaler, float increment,
					  float target, int step)
{
	int32_t frame;
	int i = 0, j;

	if (scaler < MIN_VOLUME_TO_SCALE && increment < 0) {
		memset(buffer, 0, 3 * count * sizeof(*buffer));
		return;
	}

	while (i + step <= count) {
		for (j = 0; j < step; j++) {
			float applied_scaler = scaler;

			if ((applied_scaler > target && increment > 0) ||
			    (applied_scaler < target && increment < 0))
				applied_scaler = target;

			convert_single_s243le_to_s32le(&frame, buffer);

			if (applied_scaler > MAX_VOLUME_TO_SCALE) {
			} else if (applied_scaler < MIN_VOLUME_TO_SCALE) {
				frame = 0;
			} else {
				frame *= applied_scaler;
			}

			convert_single_s32le_to_s243le(buffer, &frame);

			i++;
			buffer += 3;
		}
		scaler += increment;
	}
}

static void cras_scale_buffer_s24_3le(uint8_t *buffer, unsigned int count,
				      float scaler)
{
	int32_t frame;
	int i;

	if (scaler > MAX_VOLUME_TO_SCALE)
		return;

	if (scaler < MIN_VOLUME_TO_SCALE) {
		memset(buffer, 0, 3 * count * sizeof(*buffer));
		return;
	}

	for (i = 0; i < count; i++, buffer += 3) {
		convert_single_s243le_to_s32le(&frame, buffer);
		frame *= scaler;
		convert_single_s32le_to_s243le(buffer, &frame);
	}
}

static void cras_mix_add_s24_3le(uint8_t *dst, uint8_t *src, unsigned int count,
				 unsigned int index, int mute, float mix_vol)
{
	uint8_t *out = dst;
	uint8_t *in = src;

	if (mute || (mix_vol < MIN_VOLUME_TO_SCALE)) {
		if (index == 0)
			memset(out, 0, 3 * count * sizeof(*out));
		return;
	}

	if (index == 0)
		return copy_scaled_s24_3le(out, in, count, mix_vol);

	scale_add_clip_s24_3le(out, in, count, mix_vol);
}

static void cras_mix_add_scale_stride_s24_3le(uint8_t *dst, uint8_t *src,
					      unsigned int dst_stride,
					      unsigned int src_stride,
					      unsigned int count, float scaler)
{
	unsigned int i;
	int64_t sum;
	int32_t dst_frame;
	int32_t src_frame;

	for (i = 0; i < count; i++) {
		convert_single_s243le_to_s32le(&dst_frame, dst);
		convert_single_s243le_to_s32le(&src_frame, src);
		if (need_to_scale(scaler))
			sum = (int64_t)dst_frame + (int64_t)src_frame * scaler;
		else
			sum = (int64_t)dst_frame + (int64_t)src_frame;
		if (sum > INT32_MAX)
			sum = INT32_MAX;
		else if (sum < INT32_MIN)
			sum = INT32_MIN;
		dst_frame = (int32_t)sum;
		convert_single_s32le_to_s243le(dst, &dst_frame);
		dst += dst_stride;
		src += src_stride;
	}
}

static void scale_buffer_increment(snd_pcm_format_t fmt, uint8_t *buff,
				   unsigned int count, float scaler,
				   float increment, float target, int step)
{
	switch (fmt) {
	case SND_PCM_FORMAT_S16_LE:
		return cras_scale_buffer_inc_s16_le(buff, count, scaler,
						    increment, target, step);
	case SND_PCM_FORMAT_S24_LE:
		return cras_scale_buffer_inc_s24_le(buff, count, scaler,
						    increment, target, step);
	case SND_PCM_FORMAT_S32_LE:
		return cras_scale_buffer_inc_s32_le(buff, count, scaler,
						    increment, target, step);
	case SND_PCM_FORMAT_S24_3LE:
		return cras_scale_buffer_inc_s24_3le(buff, count, scaler,
						     increment, target, step);
	default:
		break;
	}
}

static void scale_buffer(snd_pcm_format_t fmt, uint8_t *buff,
			 unsigned int count, float scaler)
{
	switch (fmt) {
	case SND_PCM_FORMAT_S16_LE:
		return cras_scale_buffer_s16_le(buff, count, scaler);
	case SND_PCM_FORMAT_S24_LE:
		return cras_scale_buffer_s24_le(buff, count, scaler);
	case SND_PCM_FORMAT_S32_LE:
		return cras_scale_buffer_s32_le(buff, count, scaler);
	case SND_PCM_FORMAT_S24_3LE:
		return cras_scale_buffer_s24_3le(buff, count, scaler);
	default:
		break;
	}
}

static void mix_add(snd_pcm_format_t fmt, uint8_t *dst, uint8_t *src,
		    unsigned int count, unsigned int index, int mute,
		    float mix_vol)
{
	switch (fmt) {
	case SND_PCM_FORMAT_S16_LE:
		return cras_mix_add_s16_le(dst, src, count, index, mute,
					   mix_vol);
	case SND_PCM_FORMAT_S24_LE:
		return cras_mix_add_s24_le(dst, src, count, index, mute,
					   mix_vol);
	case SND_PCM_FORMAT_S32_LE:
		return cras_mix_add_s32_le(dst, src, count, index, mute,
					   mix_vol);
	case SND_PCM_FORMAT_S24_3LE:
		return cras_mix_add_s24_3le(dst, src, count, index, mute,
					    mix_vol);
	default:
		break;
	}
}

static void mix_add_scale_stride(snd_pcm_format_t fmt, uint8_t *dst,
				 uint8_t *src, unsigned int count,
				 unsigned int dst_stride,
				 unsigned int src_stride, float scaler)
{
	switch (fmt) {
	case SND_PCM_FORMAT_S16_LE:
		return cras_mix_add_scale_stride_s16_le(
			dst, src, dst_stride, src_stride, count, scaler);
	case SND_PCM_FORMAT_S24_LE:
		return cras_mix_add_scale_stride_s24_le(
			dst, src, dst_stride, src_stride, count, scaler);
	case SND_PCM_FORMAT_S32_LE:
		return cras_mix_add_scale_stride_s32_le(
			dst, src, dst_stride, src_stride, count, scaler);
	case SND_PCM_FORMAT_S24_3LE:
		return cras_mix_add_scale_stride_s24_3le(
			dst, src, dst_stride, src_stride, count, scaler);
	default:
		break;
	}
}

static size_t mix_mute_buffer(uint8_t *dst, size_t frame_bytes, size_t count)
{
	memset(dst, 0, count * frame_bytes);
	return count;
}

const struct cras_mix_ops OPS(mixer_ops) = {
	.scale_buffer = scale_buffer,
	.scale_buffer_increment = scale_buffer_increment,
	.add = mix_add,
	.add_scale_stride = mix_add_scale_stride,
	.mute_buffer = mix_mute_buffer,
};
