88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore/*
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * CDDL HEADER START
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore *
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * The contents of this file are subject to the terms of the
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * Common Development and Distribution License (the "License").
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * You may not use this file except in compliance with the License.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore *
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * or http://www.opensolaris.org/os/licensing.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * See the License for the specific language governing permissions
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * and limitations under the License.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore *
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * When distributing Covered Code, include this CDDL HEADER in each
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * If applicable, add the following below this CDDL HEADER, with the
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * fields enclosed by brackets "[]" replaced with your own identifying
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * information: Portions Copyright [yyyy] [name of copyright owner]
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore *
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * CDDL HEADER END
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore/*
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * Copyright (C) 4Front Technologies 1996-2008.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore *
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * Use is subject to license terms.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore/*
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * Purpose: GRC3 Sample Rate Converter
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore *
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * GRC library version 3.1
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#include <sys/types.h>
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#include "audio_grc3.h"
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoreextern const int32_t filter_data_L[];
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoreextern const int32_t filter_data_M[];
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoreextern const int32_t filter_data_H[];
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoreextern const int32_t filter_data_P[];
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define filter_data_HX filter_data_H
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define filter_data_PX filter_data_P
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorestatic int32_t
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore_muldivu64(uint32_t a, uint32_t val1, uint32_t val2)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore uint64_t v = ((uint64_t)a) * val1 / val2;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore return ((uint32_t)(v));
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore}
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorestatic int32_t
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore_grc_sat6(int32_t a, int32_t b)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int64_t v = ((int64_t)a) * b + (1 << 5);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore return ((int32_t)(v >> 6));
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore}
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorestatic int32_t
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore_grc_sat31(int32_t a, int32_t b)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int64_t v = ((int64_t)a) * b + (1 << 30);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore return ((int32_t)(v >> 31));
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore}
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define DEFINE_FILTER(T) \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorestatic int32_t \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore_filt31_##T(int32_t a, int32_t idx) \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{ \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int64_t v = ((int64_t)a) * filter_data_##T[idx >> 15]; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore return ((int32_t)(v >> 31)); \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore}
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define DEFINE_FILTER_HQ(T) \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorestatic int32_t \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore_filt31_##T(int32_t a, int32_t idx) \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{ \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int32_t idx2 = idx>>15; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int64_t v = ((int64_t)a) * \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (filter_data_##T[idx2] + \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore (((int64_t)(idx & 32767)) * (filter_data_##T[idx2 + 1] - \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore filter_data_##T[idx2]) >> 15)); \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore return ((int32_t)(v>>31)); \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore}
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'AmoreDEFINE_FILTER(L)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'AmoreDEFINE_FILTER(M)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'AmoreDEFINE_FILTER(H)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'AmoreDEFINE_FILTER_HQ(HX)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'AmoreDEFINE_FILTER(P)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'AmoreDEFINE_FILTER_HQ(PX)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define DEFINE_CONVD(T, SZ) \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorestatic int32_t \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore_conv31d_##T(int32_t *history, uint32_t filter, uint32_t incv) \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{ \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int32_t accum = 0; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore filter = (1024 << 15) - filter; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore while (filter < ((uint32_t)(SZ << 15))) { \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore accum += _filt31_##T(*history, filter); \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore filter += incv; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore history--; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore } \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore return (accum); \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore}
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'AmoreDEFINE_CONVD(L, 4096)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'AmoreDEFINE_CONVD(M, 8192)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'AmoreDEFINE_CONVD(H, 16384)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'AmoreDEFINE_CONVD(HX, 16384)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'AmoreDEFINE_CONVD(P, 32768)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'AmoreDEFINE_CONVD(PX, 32768)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorestatic int32_t
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore_conv31_L(int32_t *history, uint32_t filter)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int32_t accum = 0;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define ITERATION(p) \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore accum += _filt31_##p(*history, filter); \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore filter += (1024 << 15); \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore history--
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(L); ITERATION(L); ITERATION(L); ITERATION(L);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore return (accum);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore}
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorestatic int32_t
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore_conv31_M(int32_t *history, uint32_t filter)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int32_t accum = 0;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(M); ITERATION(M); ITERATION(M); ITERATION(M);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(M); ITERATION(M); ITERATION(M); ITERATION(M);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore return (accum);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore}
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorestatic int32_t
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore_conv31_H(int32_t *history, uint32_t filter)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int32_t accum = 0;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(H); ITERATION(H); ITERATION(H); ITERATION(H);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(H); ITERATION(H); ITERATION(H); ITERATION(H);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(H); ITERATION(H); ITERATION(H); ITERATION(H);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(H); ITERATION(H); ITERATION(H); ITERATION(H);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore return (accum);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore}
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorestatic int32_t
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore_conv31_HX(int32_t *history, uint32_t filter)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int32_t accum = 0;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(HX); ITERATION(HX); ITERATION(HX); ITERATION(HX);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(HX); ITERATION(HX); ITERATION(HX); ITERATION(HX);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(HX); ITERATION(HX); ITERATION(HX); ITERATION(HX);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(HX); ITERATION(HX); ITERATION(HX); ITERATION(HX);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore return (accum);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore}
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorestatic int32_t
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore_conv31_P(int32_t *history, uint32_t filter)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int32_t accum = 0;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(P); ITERATION(P); ITERATION(P); ITERATION(P);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(P); ITERATION(P); ITERATION(P); ITERATION(P);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(P); ITERATION(P); ITERATION(P); ITERATION(P);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(P); ITERATION(P); ITERATION(P); ITERATION(P);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(P); ITERATION(P); ITERATION(P); ITERATION(P);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(P); ITERATION(P); ITERATION(P); ITERATION(P);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(P); ITERATION(P); ITERATION(P); ITERATION(P);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(P); ITERATION(P); ITERATION(P); ITERATION(P);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore return (accum);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore}
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorestatic int32_t
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore_conv31_PX(int32_t *history, uint32_t filter)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int32_t accum = 0;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(PX); ITERATION(PX); ITERATION(PX); ITERATION(PX);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(PX); ITERATION(PX); ITERATION(PX); ITERATION(PX);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(PX); ITERATION(PX); ITERATION(PX); ITERATION(PX);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(PX); ITERATION(PX); ITERATION(PX); ITERATION(PX);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(PX); ITERATION(PX); ITERATION(PX); ITERATION(PX);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(PX); ITERATION(PX); ITERATION(PX); ITERATION(PX);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(PX); ITERATION(PX); ITERATION(PX); ITERATION(PX);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ITERATION(PX); ITERATION(PX); ITERATION(PX); ITERATION(PX);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore return (accum);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore}
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore#define GRC3_RESAMPLE(QUAL) \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorestatic void \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoregrc3_upsample_##QUAL(grc3state_t *grc, const int32_t *src, \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int32_t *dst, uint32_t sz, uint32_t bufsz, int inc, int offset) \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{ \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int32_t ptr = grc->ptr; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int32_t srcrate = grc->srcrate; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int32_t dstrate = grc->dstrate; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int32_t *history = grc->historyptr; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int32_t filtfactor = grc->filtfactor; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore uint32_t dstsz = 0; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore src += offset; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore dst += offset; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore while (sz > 0) { \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore while (ptr < dstrate) { \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if (dstsz >= bufsz) \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore goto endloop; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore dst[0] = (_conv31_##QUAL(history, \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore _grc_sat6(ptr, filtfactor))); \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ptr += srcrate; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore dst += inc; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore dstsz++; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore } \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore history++; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if (history >= (grc->history + GRC3_MAXHISTORY * 2)) \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore history -= GRC3_MAXHISTORY; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore history[0] = history[-GRC3_MAXHISTORY] = (*src); \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ptr -= dstrate; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore sz--; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore src += inc; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore } \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoreendloop: \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc->ptr = ptr; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc->historyptr = history; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc->outsz = dstsz; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore} \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorestatic void \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoregrc3_dnsample_##QUAL(grc3state_t *grc, const int32_t *src, \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int32_t *dst, uint32_t sz, uint32_t bufsz, int inc, int offset) \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{ \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int32_t ptr = grc->ptr; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int32_t srcrate = grc->srcrate; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int32_t dstrate = grc->dstrate; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int32_t sat = grc->sat; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int32_t *history = grc->historyptr; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int32_t filtfactor = grc->filtfactor; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore uint32_t dstsz = 0; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore src += offset; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore dst += offset; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore while (sz > 0) { \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore while (ptr >= srcrate) { \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if (dstsz >= bufsz) \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore goto endloop; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ptr -= srcrate; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore dst[0] = (_conv31d_##QUAL(history, \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore _grc_sat6(ptr, filtfactor), \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc->ptr_incv)); \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore dst += inc; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore dstsz++; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore } \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore history++; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if (history >= (grc->history + GRC3_MAXHISTORY * 2)) \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore history -= GRC3_MAXHISTORY; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore /* \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * TODO: for better quality multiplier is worth moving \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * to output cascade \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore */ \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore history[0] = history[-GRC3_MAXHISTORY] = \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore _grc_sat31((*src), sat); \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore ptr += dstrate; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore sz--; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore src += inc; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore } \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoreendloop: \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc->ptr = ptr; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc->historyptr = history; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc->outsz = dstsz; \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore} \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorestatic void \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoregrc3_resample_##QUAL(grc3state_t *grc, const void *src, void *dst, \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore uint32_t sz, uint32_t bufsz, int inc, int offset) \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{ \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if (grc->srcrate <= grc->dstrate) \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc3_upsample_##QUAL(grc, src, dst, sz, \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore bufsz, inc, offset); \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore else \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc3_dnsample_##QUAL(grc, src, dst, sz, \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore bufsz, inc, offset); \
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore}
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'AmoreGRC3_RESAMPLE(L)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'AmoreGRC3_RESAMPLE(M)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'AmoreGRC3_RESAMPLE(H)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'AmoreGRC3_RESAMPLE(HX)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'AmoreGRC3_RESAMPLE(P)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'AmoreGRC3_RESAMPLE(PX)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore/*
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore * For performance reasons, we only support 24-bit SRC.
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore */
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorevoid
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoregrc3_convert(grc3state_t *grc, int quality, const void *src,
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore void *dst, int sz, int bufsz, int inc, int offset)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore switch (quality) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore default:
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore case 0:
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore case 1:
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc3_resample_L(grc, src, dst, sz, bufsz, inc, offset);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore break;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore case 2:
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc3_resample_M(grc, src, dst, sz, bufsz, inc, offset);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore break;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore case 3:
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc3_resample_H(grc, src, dst, sz, bufsz, inc, offset);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore break;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore case 4:
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc3_resample_HX(grc, src, dst, sz, bufsz, inc, offset);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore break;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore case 5:
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc3_resample_P(grc, src, dst, sz, bufsz, inc, offset);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore break;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore case 6:
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc3_resample_PX(grc, src, dst, sz, bufsz, inc, offset);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore break;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore}
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorevoid
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoregrc3_reset(grc3state_t *grc)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore int32_t t;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc->ptr = 0;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc->historyptr = grc->history + GRC3_MAXHISTORY;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore for (t = 0; t < GRC3_MAXHISTORY * 2; t++)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc->history[t] = 0;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore}
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorestatic void
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoregrc3_setup_up(grc3state_t *grc, uint32_t fromRate, uint32_t toRate)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc->srcrate = fromRate;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc->dstrate = toRate;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc->filtfactor = 0x80000000U / toRate;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore}
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorestatic void
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoregrc3_setup_dn(grc3state_t *grc, uint32_t fromRate, uint32_t toRate)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc->srcrate = fromRate;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc->dstrate = toRate;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc->filtfactor = 0x80000000U / fromRate;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc->ptr_incv = _muldivu64(1024 << 15, toRate, fromRate);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc->sat = _muldivu64(0x80000000U, toRate, fromRate);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore}
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amorevoid
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amoregrc3_setup(grc3state_t *grc, uint32_t fromRate, uint32_t toRate)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore{
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore while ((!(fromRate & 1)) && (!(toRate & 1)) && (fromRate > 0)) {
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore fromRate >>= 1;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore toRate >>= 1;
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore }
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore if (fromRate <= toRate)
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc3_setup_up(grc, fromRate, toRate);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore else
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore grc3_setup_dn(grc, fromRate, toRate);
88447a05f537aabe9a1bc3d5313f22581ec992a7Garrett D'Amore}