Issues:
That is not a CSV file, it is just a text file.
Your code does not look like that. It is far from being compilable, and you made mistakes copying the "relevant parts" to this question.
In particular, you used n
as the loop variable, but cont
in accessing the buffer. If your code was actually that, you'd only see a single pair of values, duplicated, in the output.
You do not define the sample rate.
Consider the following counter-example:
#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;
}
It assumes the sample rate is 48,000 samples per second (you could use ffmpeg
to find out the sample rate first), then prints out each sample, one sample per line, with time in the first column, and sample value (-1.0 to just under +1.0) in the second column.
In the physics sense, the first column reflects the time dimension of the sample, and the second column the relative pressure change at that moment in the sensor -- however, neither the sign or the linearity of the pressure change is really known for sure, as it depends on the exact microphone, amplification, and ADC used.
Let's say you compile and run the above, redirecting the output to test1.out
:
gcc -Wall -O2 example.c -o example
./example > test1.out
You can draw this in Gnuplot easily. Start gnuplot
, and tell it
set xlabel "Time [seconds]"
set ylabel "Relative pressure change [f((P-P0)/Pmax)]"
plot "test1.out" u 1:2 notitle w lines
For the vertical axis, P
is the pressure at the moment indicated on the horizontal axis, P0
is the ambient pressure, Pmax
is the maximum pressure change the microphone can detect, and f()
is the inverse of the nonlinearity of the microphone, microphone amplifier, and analog-to-digital converter circuitry used. (Both f()
and Pmax
likely depend on the ambient pressure P0
, too.)