音频波没有负值

时间:2013-10-25 18:00:19

标签: c raspberry-pi

长话短说,我在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。

1 个答案:

答案 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 进行预测分析)。话虽如此,它也可以保持非常简单,例如简单的运行平均值。