/*
* CVSD (Continuously Variable Slope Delta modulation)
* conversion routines
*
* The CVSD format is described in the MIL Std 188 113, which is
* available from http://bbs.itsi.disa.mil:5580/T3564
*
* Copyright (C) 1996
* Thomas Sailer (sailer@ife.ee.ethz.ch) (HB9JNX/AE4WA)
* Swiss Federal Institute of Technology, Electronics Lab
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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
*
* Change History:
*
* June 1, 1998 - Chris Bagwell (cbagwell@sprynet.com)
* Fixed compile warnings reported by Kjetil Torgrim Homme
* <kjetilho@ifi.uio.no>
*
*
*/
/* ---------------------------------------------------------------------- */
#include "st_i.h"
#include <math.h>
#include <string.h>
#include <time.h>
#include <stdio.h>
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h> /* For SEEK_* defines if not found in stdio */
#endif
#include "cvsdfilt.h"
/* ---------------------------------------------------------------------- */
#ifndef HAVE_MEMMOVE
#define memmove(dest,src,len) (bcopy((src),(dest),(len)))
#endif
/* ---------------------------------------------------------------------- */
/*
* private data structures
*/
struct cvsd_common_state {
unsigned overload;
float mla_int;
float mla_tc0;
float mla_tc1;
unsigned phase;
unsigned phase_inc;
float v_min, v_max;
};
struct cvsd_decode_state {
float output_filter[DEC_FILTERLEN];
};
struct cvsd_encode_state {
float recon_int;
float input_filter[ENC_FILTERLEN];
};
struct cvsdpriv {
struct cvsd_common_state com;
union {
struct cvsd_decode_state dec;
struct cvsd_encode_state enc;
} c;
struct {
unsigned char shreg;
unsigned mask;
unsigned cnt;
} bit;
unsigned bytes_written;
unsigned cvsd_rate;
char swapbits;
};
/* ---------------------------------------------------------------------- */
static float float_conv(float *fp1, float *fp2,int n)
{
float res = 0;
for(; n > 0; n--)
res += (*fp1++) * (*fp2++);
return res;
}
/* ---------------------------------------------------------------------- */
/*
* some remarks about the implementation of the CVSD decoder
* the principal integrator is integrated into the output filter
* to achieve this, the coefficients of the output filter are multiplied
* with (1/(1-1/z)) in the initialisation code.
* the output filter must have a sharp zero at f=0 (i.e. the sum of the
* filter parameters must be zero). This prevents an accumulation of
* DC voltage at the principal integration.
*/
/* ---------------------------------------------------------------------- */
static void cvsdstartcommon(ft_t ft)
{
struct cvsdpriv *p = (struct cvsdpriv *) ft->priv;
p->cvsd_rate = (ft->info.rate <= 24000) ? 16000 : 32000;
ft->info.rate = 8000;
ft->info.channels = 1;
ft->info.size = ST_SIZE_WORD; /* make output format default to words */
ft->info.encoding = ST_ENCODING_SIGN2;
p->swapbits = ft->swap;
ft->swap = 0;
/*
* initialize the decoder
*/
p->com.overload = 0x5;
p->com.mla_int = 0;
/*
* timeconst = (1/e)^(200 / SR) = exp(-200/SR)
* SR is the sampling rate
*/
p->com.mla_tc0 = exp((-200.0)/((float)(p->cvsd_rate)));
/*
* phase_inc = 32000 / SR
*/
p->com.phase_inc = 32000 / p->cvsd_rate;
/*
* initialize bit shift register
*/
p->bit.shreg = p->bit.cnt = 0;
p->bit.mask = p->swapbits ? 0x80 : 1;
/*
* count the bytes written
*/
p->bytes_written = 0;
p->com.v_min = 1;
p->com.v_max = -1;
st_report("cvsd: bit rate %dbit/s, bits from %s\n", p->cvsd_rate,
p->swapbits ? "msb to lsb" : "lsb to msb");
}
/* ---------------------------------------------------------------------- */
int st_cvsdstartread(ft_t ft)
{
struct cvsdpriv *p = (struct cvsdpriv *) ft->priv;
float *fp1;
int i;
cvsdstartcommon(ft);
p->com.mla_tc1 = 0.1 * (1 - p->com.mla_tc0);
p->com.phase = 0;
/*
* initialize the output filter coeffs (i.e. multiply
* the coeffs with (1/(1-1/z)) to achieve integration
* this is now done in the filter parameter generation utility
*/
/*
* zero the filter
*/
for(fp1 = p->c.dec.output_filter, i = DEC_FILTERLEN; i > 0; i--)
*fp1++ = 0;
return (ST_SUCCESS);
}
/* ---------------------------------------------------------------------- */
int st_cvsdstartwrite(ft_t ft)
{
struct cvsdpriv *p = (struct cvsdpriv *) ft->priv;
float *fp1;
int i;
cvsdstartcommon(ft);
p->com.mla_tc1 = 0.1 * (1 - p->com.mla_tc0);
p->com.phase = 4;
/*
* zero the filter
*/
for(fp1 = p->c.enc.input_filter, i = ENC_FILTERLEN; i > 0; i--)
*fp1++ = 0;
p->c.enc.recon_int = 0;
return(ST_SUCCESS);
}
/* ---------------------------------------------------------------------- */
int st_cvsdstopwrite(ft_t ft)
{
struct cvsdpriv *p = (struct cvsdpriv *) ft->priv;
if (p->bit.cnt) {
st_writeb(ft, p->bit.shreg);
p->bytes_written++;
}
st_report("cvsd: min slope %f, max slope %f\n",
p->com.v_min, p->com.v_max);
return (ST_SUCCESS);
}
/* ---------------------------------------------------------------------- */
int st_cvsdstopread(ft_t ft)
{
struct cvsdpriv *p = (struct cvsdpriv *) ft->priv;
st_report("cvsd: min value %f, max value %f\n",
p->com.v_min, p->com.v_max);
return(ST_SUCCESS);
}
/* ---------------------------------------------------------------------- */
#undef DEBUG
#ifdef DEBUG
static struct {
FILE *f1;
FILE *f2;
int cnt
} dbg = { NULL, NULL, 0 };
#endif
st_ssize_t st_cvsdread(ft_t ft, st_sample_t *buf, st_ssize_t nsamp)
{
struct cvsdpriv *p = (struct cvsdpriv *) ft->priv;
int done = 0;
float oval;
#ifdef DEBUG
if (!dbg.f1) {
if (!(dbg.f1 = fopen("dbg1", "w")))
{
st_fail_errno(ft,errno,"debugging");
return (0);
}
fprintf(dbg.f1, "\"input\"\n");
}
if (!dbg.f2) {
if (!(dbg.f2 = fopen("dbg2", "w")))
{
st_fail_errno(ft,errno,"debugging");
return (0);
}
fprintf(dbg.f2, "\"recon\"\n");
}
#endif
while (done
周楷雯
- 粉丝: 98
- 资源: 1万+
最新资源
- diboot-demo前后端代码自动生成+菜单左右布局
- C# winform 批量重命名文件、去掉小括号等.zip
- 通用人工智能行业发展趋势:预计2031年全球通用人工智能市场销售额将达到946.8亿美元
- C#-WinForm演示最小二乘法拟合一次函数.zip
- winform-人事管理系统-C# + SQLServer
- winfrom 虚拟键盘码表.zip
- Linux IO编程课件资料.zip
- C# Winform 窗体程序 websocket客户端测试连接工具.zip
- 超低温漂带隙基准电路设计,高电源抑制比,低功耗 ppm:2.4 psrr:90dB 电流:14.47uA 1.带设计文档PDF,有推导过程和调试过程,以及仿真设置 2.带工艺库打包,可以提供机和cad
- freeswitch asr中实现静音检测
- 利用VC#开发一个媒体播放器,VC6,很老的资源
- 永磁同步电机(pmsm,全速度切无位置传感器控制(高速可以是超螺旋滑模) 低速可以是脉振高频方波注入,量产方案,仿真模型 切有加权切和双坐标切 高速反电动势无感 量产方案
- 基于tc275 aurix 1g 2g,tc387,tc377,tc397,以及s32k144的xcp uds bootloader与ccp标定的程序以及canape使用教程,a2l文件生成文档说明程
- 最优化方法(全英文课程)xmind思维导图
- 高分辨率下的小麦、水稻、玉米早期秧苗图像分类数据集【已标注,约900张数据】
- MMC模块化多电平流器,MMC-HVDC直流输电系统,单个桥臂N=10个子模块,采用载波移相调制 simulink仿真模型 为了测试控制性能良好,在1s时,额定有功功率10e6增加到15e6 子模
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈