c - 音频波没有负值

标签 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,以避免出现负值。

最佳答案

我认为关键问题是你试图把 将大量的数据放入一个狭小的空间中。也就是说,没有第一 将原始数字缩小到适合的大小 轻松地放入 char 存储中,您正在截断一些 int 数据中的信息导致大量 负值被解释为零。顺便说一句,如果 你的任何负值都> -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);

(我不知道你在第二次调用中做了什么,但如果需要,你可以执行shift和&操作,然后调用ScaleToChar())

[编辑]

我认为您要做的是过滤波形,而不是我最初建议的缩放方法。也就是说,递增数据数组,当波形接近极限(负极限或正极限)时,使用最近 10 到 15 个数组值中的一些历史记录来确定应如何趋势化潜在错误值这样他们就不会违反限制。这样,您的大部分数据将永远不需要被触及。这将允许保持保真度(与缩放方法不同),同时,对任何修改数据的更改将仅限于落在波形违规部分中心周围的某个预定区域内的数据,并且修改将仅限于接近非错误值周围邻域中的值。

我想到了 FIR 滤波器方法,但像运行平均值这样简单的方法也可以。没有违反限制危险的数据值永远不会被过滤器触及。从概念上讲,这种方法听起来并不太复杂。然而,当我开始思考如何解决它时,我意识到你可能会变得非常复杂(例如,应用 Kalman filter 进行预测分析)。话虽如此,它也可以保持非常简单,即简单的运行平均值。

关于c - 音频波没有负值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19596564/

相关文章:

c - 迭代具有非标准字符的 char 数组

c - 将 rsyslogd 输出转储到某个文件

python - 如何将十六进制字符串转换为整数?

python - 字符串和整数之间的转换。 Python

可以通过 bash 添加磁力链接的 Linux torrent 客户端

c - dup2() 正在阻止输出

Android 重启命令 - 谁调用reboot_main()?

MySQL C API mysql_query

python - Raspberry pi python mysql代码在一段时间后停止保存数据

python - 通过网络在多个 RaspPis 之间实现完全通信的最佳方式是什么?