📄 hermite.c
字号:
/* ***** BEGIN LICENSE BLOCK *****
* Version: RCSL 1.0/RPSL 1.0
*
* Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
*
* The contents of this file, and the files included with this file, are
* subject to the current version of the RealNetworks Public Source License
* Version 1.0 (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the RealNetworks Community Source License Version 1.0
* (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
* in which case the RCSL will apply. You may also obtain the license terms
* directly from RealNetworks. You may not use this file except in
* compliance with the RPSL or, if you have a valid RCSL with RealNetworks
* applicable to this file, the RCSL. Please see the applicable RPSL or
* RCSL for the rights, obligations and limitations governing use of the
* contents of the file.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the portions
* it created.
*
* This file, and the files included with this file, is distributed and made
* available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
/*
* Sampling rate conversion, by polynomial interpolation.
* Ken Cooke (kenc@real.com)
*/
#include "hlxclib/stdlib.h"
#include "hxtypes.h"
#include "allresamplers.h"
#include "math64.h"
#define MAXRATE ((1<<23) - 1) /* sampling rates cannot exceed MAXRATE */
#define MAXSAMPS ((1<<23) - 1) /* max outsamps for GetMinInput() */
#define MAXCHANS 2
/* interpolator state */
typedef struct {
int inrate;
int outrate;
int nchans;
int time_i;
UINT time_f;
UINT step_i;
UINT step_f;
short hist[3*MAXCHANS]; /* input history */
} STATE;
/* Initialize Hermite resampler
*
* Parameters
* ----------
* int inrate sample rate of input (Hz)
* int outrate desired sample rate of output (Hz)
* int nchans number of channels
*
* return value instance pointer which will be passed in all future RAXXXHermite() function calls, 0 if error
*
* Notes
* -----
* - inrate, outrate, nchans must be within valid ranges (see below)
* - inrate < outrate (i.e. upsampling only!)
*/
void *
RAInitResamplerHermite(int inrate, int outrate, int nchans)
{
STATE *s;
UINT step_i, step_f, ratio, rem;
int i;
/* validate params */
if ((inrate <= 0) || (inrate > MAXRATE) ||
(outrate <= 0) || (outrate > MAXRATE))
return 0;
/* only allow downsampling on certain platforms
* until we have a fixed point resampler that can
* downsample properly. */
#ifndef _SYMBIAN
/* XXXgfw remove this when the new resampler is available. */
if( inrate > outrate )
{
return 0;
}
#endif
if ((nchans < 1) || (nchans > MAXCHANS))
return 0;
/* create interpolator state */
s = (STATE *) malloc(sizeof(STATE));
if (!s)
return 0;
/* Compute 64-bit timestep, as a signed integer and 32-bit fraction */
step_i = inrate / outrate; /* integer part */
rem = inrate;
step_f = 0 ;
for (i = 0; i < 4; i++) {
rem <<= 8;
ratio = rem / outrate;
rem -= ratio * outrate;
step_f = (step_f << 8) | (ratio & 0xff); /* 8 more fraction bits */
}
ASSERT(step_i == (UINT)((double)inrate/outrate));
ASSERT(step_f == (UINT)(65536.*65536.*((double)inrate/outrate - step_i)));
s->inrate = inrate;
s->outrate = outrate;
s->nchans = nchans;
s->time_i = 0;
s->time_f = 0;
s->step_i = step_i;
s->step_f = step_f;
for (i = 0; i < (3*MAXCHANS); i++)
s->hist[i] = 0;
return (void *)s;
}
/* Initialize Hermite resampler from a copy, using its parameters.
*
* Parameters
* ----------
* inst instance pointer to a resampler to be used as template
*
* return value instance pointer which will be passed in all future RAXXXHermite() function calls, 0 if error
*/
void *
RAInitResamplerCopyHermite(int nchans, const void *inst)
{
STATE *s_in = (STATE *)inst;
STATE *s_out = (STATE *)malloc(sizeof(STATE));
if (s_in == 0 || s_out == 0)
return 0;
*s_out = *s_in ;
s_out->nchans = nchans;
return s_out;
}
/* Free memory associated with Hermite resampler
*
* Parameters
* ----------
* void *inst instance pointer
*
* return value none
*
* Notes
* -----
*/
void
RAFreeResamplerHermite(void *inst)
{
STATE *s = (STATE *)inst;
free(s);
}
/* Get max possible outsamps given insamps input
*
* Parameters
* ----------
* int insamps number of input samples
* void *inst instance pointer
*
* return value maximum number of output samples generated by resampling insamps samples, -1 if error
*
* Notes
* -----
* - some alternate implementations are included as comments
* these might be useful, depending on the target platform
* - insamps must be even for stereo, function will exit with error if not
*/
int RAGetMaxOutputHermite(int insamps, void *inst)
{
/* do an empty (null) resample of insamps samples */
int inframes, outframes;
UINT i, f;
STATE *s = (STATE *)inst;
if (s->nchans == 2 && insamps & 0x01)
return -1;
inframes = (s->nchans == 2 ? insamps >> 1 : insamps);
for (i = f = outframes = 0; i < (UINT)inframes; outframes++) {
f += s->step_f;
i += s->step_i + (f < s->step_f); /* add with carry */
}
return (int)(outframes * s->nchans);
/* equivalent method using __int64
*
* inframes = (s->nchans == 2 ? insamps >> 1 : insamps);
* step64 = ((__int64)s->step_i << 32) + (__int64)s->step_f;
* outframes = ( ((__int64)inframes << 32) + step64 - 1) / step64; COMMENT: ceiling
* return (int)(outframes * s->nchans);
*/
/* equivalent method using double-precision floats
*
* double step;
* inframes = (s->nchans == 2 ? insamps >> 1 : insamps);
* step = s->step_i + (s->step_f / 4294967296.0);
* outframes = (int) ceil((double)inframes / step);
* return (outframes * s->nchans);
*/
}
/* Get minimum number of input samples required to generate outsamps output samples
*
* Parameters
* ----------
* int outsamps number of desired output samples
* void *inst instance pointer
*
* return value minimum number of input samples required to generate outsamps output samples, -1 if error
*
* Notes
* -----
* - some alternate implementations are included as comments
* these might be useful, depending on the target platform
* - outsamps must be even for stereo, function will exit with error if not
*/
int
RAGetMinInputHermite(int outsamps, void *inst)
{
UINT outframes;
STATE *s = (STATE *)inst;
UINT inframes, f, i;
/* to ensure no overflow in multiply */
if (outsamps > MAXSAMPS)
return -1;
if (s->nchans == 2 && outsamps & 0x01)
return -1;
outframes = (UINT)(s->nchans == 2 ? outsamps >> 1 : outsamps);
inframes = 0;
/* fractional part */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -