Skip to content

Instantly share code, notes, and snippets.

@xdsopl
Created December 29, 2021 13:05
Show Gist options
  • Select an option

  • Save xdsopl/ecb4324d7904333244916a613129d8a9 to your computer and use it in GitHub Desktop.

Select an option

Save xdsopl/ecb4324d7904333244916a613129d8a9 to your computer and use it in GitHub Desktop.
PDM MEMS microphone to 16 bit at 16 kHz PCM using a 2 MHz crystal oscillator and a logic analyzer
/*
2 MHz clock goes to the PDM MEMS microphone and channel 0 of the logic analyzer.
The logic analyzer needs at least a 6 MHz sample rate or three times the clock rate.
Data signal from the microphone goes to channel 4 of the logic analyzer.
Tested using a MP34DT01-M with select connected to ground.
compile:
gcc -Ofast -Wall -o pdm pdm.c
stream to speakers:
sigrok-cli -d fx2lafw --continuous --config samplerate=8MHz -O binary | ./pdm | aplay -t raw -f S16_LE -r 16000 -c 1 -
record to wav file:
sigrok-cli -d fx2lafw --continuous --config samplerate=8MHz -O binary | ./pdm | sox -t raw -r 16000 -b 16 -c 1 -L -e signed-integer - record.wav
*/
#include <stdio.h>
#include <limits.h>
int integrator_cascade(int x)
{
static int sum0, sum1, sum2;
return sum2 += (sum1 += (sum0 += x));
}
int comb_cascade(int x)
{
static int prv2, prv1, prv0;
int tmp = x;
tmp -= prv0; prv0 = x; x = tmp;
tmp -= prv1; prv1 = x; x = tmp;
tmp -= prv2; prv2 = x; x = tmp;
return x;
}
int block_dc(int x)
{
static int avg;
avg = (15 * avg + x) / 16;
return x - avg;
}
int clamp(int x)
{
return x < SHRT_MIN ? SHRT_MIN : x > SHRT_MAX ? SHRT_MAX : x;
}
int main()
{
for (int chr = 0, pclk = 0, pdat = 0, num = 0; chr >= 0; chr = getchar()) {
int sel = 0;
int clk = (chr & 1) ^ sel;
int dat = (chr >> 4) & 1;
if (!pclk && clk) {
int intp = integrator_cascade(pdat);
if (++num == 125) {
num = 0;
int norm = clamp(block_dc(comb_cascade(intp)));
putchar(norm & 255);
putchar((norm >> 8) & 255);
}
}
pclk = clk;
pdat = dat;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment