gnuplot - 轴上的物理尺寸
Posted
技术标签:
【中文标题】gnuplot - 轴上的物理尺寸【英文标题】:gnuplot - physical dimension on axis 【发布时间】:2017-08-09 15:46:33 【问题描述】:我编写了一个代码,它应该读取一个音频文件作为输入,以便编写一个包含每个样本的 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 轴上表示的是哪个物理维度。
我在其他帖子上读到,y 轴上的值代表麦克风中膜的变形。有谁知道数学关系以便从这些值中提取我需要的物理尺寸?
【问题讨论】:
PCM audio amplitude values?的可能重复 【参考方案1】:问题:
那不是 CSV 文件,它只是一个文本文件。
您的代码看起来不像那样。它远非可编译,并且您将“相关部分”复制到此问题时出错了。
特别是,您使用n
作为循环变量,但cont
用于访问缓冲区。如果您的代码实际上是这样,您只会在输出中看到一对重复的值。
您没有定义采样率。
考虑以下反例:
#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)在第二列中。
在物理意义上,第一列反映了样品的时间维度,第二列反映了传感器中那一刻的相对压力变化——然而,压力变化的符号或线性度都不是真正已知的当然可以,因为这取决于所使用的确切麦克风、放大器和 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
。)
【讨论】:
好奇#define NO_SAMPLE -65536
中的-65536
与#define NO_SAMPLE INT_MIN
的任何特殊原因?
@chux:没有理由。好建议;应用。谢谢!以上是关于gnuplot - 轴上的物理尺寸的主要内容,如果未能解决你的问题,请参考以下文章
Raspberry Pi 上的 Gnuplot,绘图到 X11 终端,我怎样才能重用同一个 X 窗口?