⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rate.c

📁 由HawK提供的语音压缩软件
💻 C
字号:
/*
  HawkVoice Direct Interface (HVDI) cross platform network voice library
  Copyright (C) 2001-2004 Phil Frisbie, Jr. (phil@hawksoft.com)

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public
  License along with this library; if not, write to the
  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  Boston, MA  02111-1307, USA.

  Or go to http://www.gnu.org/copyleft/lgpl.html
*/

#ifndef MACOSX
#include <malloc.h>
#endif
#include <string.h>
#include <limits.h>
#include "hvdint.h"

/*
 * July 5, 1991
 * Copyright 1991 Lance Norskog And Sundry Contributors
 * This source code is freely redistributable and may be used for
 * any purpose.  This copyright notice must be maintained. 
 * Lance Norskog And Sundry Contributors are not responsible for 
 * the consequences of using this software.
 */

/*
 * Modified for use in HawkVoiceDI by Phil Frisbie, Jr.
 */

/*
 * Least Common Multiple Linear Interpolation 
 *
 * Find least common multiple of the two sample rates.
 * Construct the signal at the LCM by interpolating successive
 * input samples as straight lines.  Pull output samples from
 * this line at output rate.
 *
 * Of course, actually calculate only the output samples.
 *
 * LCM must be 32 bits or less.  Two prime number sample rates
 * between 32768 and 65535 will yield a 32-bit LCM, so this is 
 * stretching it.
 */

/*
 * Algorithm:
 *	
 *	Generate a master sample clock from the LCM of the two rates.
 *	Interpolate linearly along it.	Count up input and output skips.
 *
 *	Input:	 |inskip |		 |		 |		 |		 |
 *																		
 *																		
 *																		
 *	LCM:	 |	 |	 |	 |	 |	 |	 |	 |	 |	 |	 |
 *																		
 *																		
 *																		
 *	Output:  |	outskip  |			 |			 | 
 *
 *																		
 */

typedef struct hvdi_rate_st {
    long    lcmrate;		    /* least common multiple of rates */
    long    inskip, outskip;    /* LCM increments for I & O rates */
    long    total;
    long    intot, outtot;      /* total samples in terms of LCM rate */
    long    lastsamp;
} hvdi_rate_t;

/* here for linear interp.	might be useful for other things */

static long gcd(long a, long b) 
{
		if (b == 0)
				return a;
		else
				return gcd(b, a % b);
}

static long lcm(long a, long b) 
{
		return (a * b) / gcd(a, b);
}

/*
 * Prepare processing.
 */
HL_EXP hvdi_rate* HL_APIENTRY hvdiNewRate(int inrate, int outrate)
{
    hvdi_rate *rate;
    
    rate = malloc(sizeof(hvdi_rate));
    if(rate == NULL)
    {
        return NULL;
    }
    rate->lcmrate = lcm((long) inrate, (long) outrate);
    /* Cursory check for LCM overflow.	
    * If both rate are below 65k, there should be no problem.
    * 16 bits x 16 bits = 32 bits, which we can handle.
    */
    rate->inskip = rate->lcmrate / inrate;
    rate->outskip = rate->lcmrate / outrate; 
    rate->total = rate->intot = rate->outtot = 0;
    rate->lastsamp = 0;
    return rate;
}

/*
 * Processed signed short samples from ibuf to obuf.
 * Return number of samples processed.
 */

HL_EXP void HL_APIENTRY hvdiRateFlow(hvdi_rate *rate, short *ibuf, short *obuf, int *inlen, int *outlen)
{
	int len, done;
	short *istart = ibuf;
	long last;
		

		done = 0;

		if (rate->total == 0) {
				/* Emit first sample.  We know the fence posts meet. */
				*obuf = *ibuf++;
				/* Count up until have right input samples */
				rate->lastsamp = *obuf++;
				done = 1;
				rate->total = 1;
				/* advance to second output */
				rate->outtot += rate->outskip;
				/* advance input range to span next output */
				while ((rate->intot + rate->inskip) <= rate->outtot){
						rate->lastsamp = *ibuf++;
						rate->intot += rate->inskip;
				}
		}

		/* number of output samples the input can feed */

		len = (*inlen * rate->inskip) / rate->outskip;
		if (len > *outlen)
				len = *outlen;
		last = rate->lastsamp;
		for(; done < len; done++) {
				long osl;

				osl = last + ((long) ((long)(*ibuf) - last) *
						(rate->outtot - rate->intot)) / rate->inskip;
                if(osl > SHRT_MAX)
                {
                    osl = SHRT_MAX;
                }
                else if(osl < SHRT_MIN)
                {
                    osl = SHRT_MIN;
                }
				*obuf++ = (short)osl;
				/* advance to next output */
				rate->outtot += rate->outskip;
				/* advance input range to span next output */
				while ((rate->intot + rate->inskip) <= rate->outtot){
						last = *ibuf++;
						rate->intot += rate->inskip;
						if (ibuf - istart == *inlen)
								goto out;
				}
                /* long samples with high LCM's overrun counters! */
				if (rate->outtot == rate->intot)
						rate->outtot = rate->intot = 0;
		}
out:
		*inlen = ibuf - istart;
		*outlen = done;
		rate->lastsamp = last;
}

HL_EXP void HL_APIENTRY hvdiDeleteRate(hvdi_rate *rate)
{
    free(rate);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -