gpt4 book ai didi

c - gnuplot - 轴上的物理尺寸

转载 作者:太空宇宙 更新时间:2023-11-04 06:16:01 27 4
gpt4 key购买 nike

我写了一个代码,据说应该读取一个音频文件作为输入,以便编写一个包含每个样本的 csv 文件。这是代码:

FILE *pipein;
pipein = popen("ffmpeg -i test1.wav -f s16le -ac 1 -", "r");
fread(buf, 2, sample_number, pipein);
pclose(pipein);

// Print the sample values in the buffer to a CSV file
FILE *csvfile;
csvfile = fopen("samples.csv", "w");

while (n<=sample_number) {

//if (buf[n]!=0) {

fprintf(csvfile, "%d %f\n", buf[cont], Sam_freq*cont);
cont++;

// }

n++;

}

fclose(csvfile);

这是运行代码后 csv 文件的样子:

10 43.150544
-36 43.150567
11 43.150590
30 43.150612
-29 43.150635
61 43.150658
13 43.150680
46 43.150703
121 43.150726
61 43.150748
144 43.150771
128 43.150794
130 43.150816
131 43.150839

我尝试使用 gnuplot 绘制 samples.csv 的数据,但我不明白 y 轴上表示哪个物理维度。

waveform plot我在其他帖子中读到,y 轴上的值表示麦克风中薄膜的变形。有谁知道数学关系以便从这些值中提取我需要的物理尺寸?

最佳答案

问题:

  1. 这不是 CSV 文件,它只是一个文本文件。

  2. 您的代码看起来不像那样。它远非可编译的,你在将“相关部分”复制到这个问题时犯了错误。

    特别是,您使用 n 作为循环变量,但在访问缓冲区时使用 cont。如果您的代码确实如此,您只会在输出中看到一对重复的值。

  3. 您没有定义采样率。

考虑以下反例:

#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
#include <string.h>
#include <endian.h>
#include <stdio.h>

#ifndef SAMPLE_RATE
#define SAMPLE_RATE 48000
#endif

#define NO_SAMPLE INT_MIN

#if (__BYTE_ORDER-0 == __BIG_ENDIAN-0)

/* Use big-endian samples */

#define SAMPLE_FORMAT "s16be"
static inline int read_sample(FILE *source)
{
int16_t sample;

if (fread(&sample, sizeof sample, 1, source) == 1)
return (int)sample;
else
return NO_SAMPLE;
}

#elif (__BYTE_ORDER-0 == __LITTLE_ENDIAN-0) || (__BYTE_ORDER-0 == __PDP_ENDIAN-0)

/* Use little-endian samples */

#define SAMPLE_FORMAT "s16le"
static inline int read_sample(FILE *source)
{
int16_t sample;

if (fread(&sample, sizeof sample, 1, source) == 1)
return (int)sample;
else
return NO_SAMPLE;
}

#else

/* Use little-endian (two's complement) samples, but
read them byte-by-byte. */

#define SAMPLE_FORMAT "s16le"
static inline int16_t read_sample(FILE *source)
{
unsigned char bytes[2];
int sample;
if (fread(bytes, 2, 1, source) != 2)
return NO_SAMPLE;

sample = bytes[0] + 256*bytes[1];
if (sample > 32767)
return sample - 65536;
else
return sample;
}
#endif

int main(void)
{
const double sample_rate = SAMPLE_RATE;
FILE *in;
unsigned long i;
int sample;

in = popen("ffmpeg -i test1.wav -v -8 -nostats -f " SAMPLE_FORMAT " -ac 1 -", "r");
if (!in)
return EXIT_FAILURE;

i = 0u;
while ((sample = read_sample(in)) != NO_SAMPLE) {
printf("%.6f %9.6f\n", (double)i / sample_rate, (double)sample / 32768.0);
i++;
}

pclose(in);

return EXIT_SUCCESS;
}

它假设采样率是每秒 48,000 个样本(你可以使用 ffmpeg 先找出采样率),然后打印出每个样本,每行一个样本,时间在第一行列,以及第二列中的样本值(-1.0 到 +1.0 以下)。

在物理意义上,第一列反射(reflect)了样本的时间维度,第二列反射(reflect)了传感器中那一刻的相对压力变化——然而,压力变化的符号和线性度都不是真正已知的当然可以,因为这取决于所使用的确切麦克风、放大器和 ADC。

假设您编译并运行上面的代码,将输出重定向到 test1.out:

gcc -Wall -O2 example.c -o example
./example > test1.out

您可以在 Gnuplot 中轻松绘制它。启动gnuplot,并告诉它

set xlabel "Time [seconds]"
set ylabel "Relative pressure change [f((P-P0)/Pmax)]"
plot "test1.out" u 1:2 notitle w lines

对于纵轴,P是横轴所指示时刻的压力,P0是环境压力,Pmax是麦克风可以检测到的最大压力变化,f() 是麦克风、麦克风放大器和所用模数转换器电路的非线性度的倒数。 (f()Pmax 也可能取决于环境压力 P0。)

关于c - gnuplot - 轴上的物理尺寸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45595274/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com