长话短说,我在int r中输出了一个音频信号,即r的值介于32768和-32768之间。
我尝试创建一个规范化例程但由于某种原因,下面的代码产生一个半波,只有上半部分是可见的,换句话说,超过0,没有负值。
这里是(dif是一个int,dif_vorher)
if (r * 8 > 32768)
dif = dif_vorher;
else if (r * 8 < -32768)
dif = dif_vorher;
else
dif = r * 8;
dif_vorher = dif;
然后它准备写入原始文件:
if (dif != 0)
{
putc((char) ( (unsigned)dif & 0xff),ausgabe);
putc((char) (((unsigned)dif >> 8) & 0xff),ausgabe);
}
此原始文件只有较高的值。我也试过
if (r * 8 > 32768)
dif = 32768;
else if (r * 8 < -32768)
dif = -32768;
else
dif = r * 8;
和
if (r * 8 > 32768 || r * 8 < -32768)
dif = -32768;
else
dif = r * 8;
相同的结果,除非我使用
if (r * 8 > 32768)
dif = 32768;
else if (r * 8 < -32768)
dif = -32768;
else
dif = r * 8;
它在上半部分也是扭曲的。
为什么消极的部分被遗漏了?
编辑:我发现r * 8的最大值为524272,最小值为0.所以r_max = 524272/8 = 65534; 65534/2 = 32767.所以似乎该值被移动以避免负值32768。
答案 0 :(得分:0)
我认为关键问题是你试图放
大数字进入一个小空间。也就是说,没有第一个
将原始数字缩放到适合的大小
舒适地进入char
存储,你正在截断一些
int数据中的信息导致大
负值被解释为零。顺便说一句,如果
你的任何负面价值都是&gt; -128,我认为表达方式:
(char) ( (unsigned)dif & 0xff)
会返回负值。
我仍然不确定你到底在做什么 表达首先,即如果你已经有 标准化函数的缩放数据值 (假设它有效),那么你不会把它放进你的 文件?
在任何情况下,我都可以告诉你,你正在努力完成
两件事,规范化(在这里,我假设你的意思是规模,让我知道我是不是错了)
一组积极和消极的数据
它可以存储在char
中,然后使用
putc()
到文件中。如果我们解决了缩放问题,
然后将正面和负面结果写入文件中
没有问题。
缩放输入范围为+/- 32768 下到char会持有的东西,即127到-128, 您可以将数据中的每个值相乘 这两个值的比率。类似的东西:
char ScaleToChar(int x); //prototype
char ScaleToChar(int x)
{
int a = x;
float ratio;
//bound a: -32768 to 32768
if (abs(x) > 32768)
{
a = (x >= 0) ? (32768) : (-32768);
}
//scale x: -128 to 127
ratio = (a <= 0) ? (128.0/32768.0) : (127.0/32768);
return (char)(a * ratio);
}
使用它,你的行:
putc((char) ( (unsigned)dif & 0xff),ausgabe);
putc((char) (((unsigned)dif >> 8) & 0xff),ausgabe);
会变成
putc(ScaleToChar(dif),ausgabe);
(我不知道你在第二次通话时做了什么,但如果需要,你可以进行转移和&amp; op,然后拨打ScaleToChar()
)
[编辑]
与我最初建议的缩放方法不同,我认为您将要做的是过滤波形。也就是说,通过您的数据数组递增,并且当波形接近极限(负极限或正极限)时,使用一些历史记录,比如最后10到15个数组值,来确定如何趋势化潜在的错误值这样他们从不违反限制。这样,您的大部分数据将永远不会被触及。这将允许保持保真度(与缩放方法不同),同时,对任何修改数据的改变将限于落入某些预定的区域内的数据,该区域围绕波形的违反部分的中心延伸,并且修改将限于近似于非错误值的周围邻域中的值。
我想到了一种FIR滤波器方法,但是像运行平均值那样简单的东西也可以工作。过滤器不会触及您的数据值,这些数据没有违反限制的危险。从概念上讲,这种方法听起来并不复杂。然而,当我开始思考如何解决它时,我意识到你可能会变得非常复杂(例如,应用 Kalman filter 进行预测分析)。话虽如此,它也可以保持非常简单,例如简单的运行平均值。