Skip to content

Instantly share code, notes, and snippets.

@xdsopl
Last active April 8, 2021 09:57
Show Gist options
  • Select an option

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

Select an option

Save xdsopl/e7139f6c13c5fd40078c655462393e18 to your computer and use it in GitHub Desktop.
Playing PCM sound over RS232, RS422, RS485 or UART TX pin using pulse width modulation with noise shaping
#! /bin/bash
# FT232RL:
# baud=500000 idle=0
baud=1000000 idle=0
# baud=2000000 idle=0
# baud=3000000 idle=0
# CP210X:
# baud=500000 idle=1
# baud=1000000 idle=2
# baud=2000000 idle=4
# PL2303:
# baud=500000 idle=0
# baud=1000000 idle=0
# baud=1000000 idle=1
# baud=2000000 idle=1
# baud=3000000 idle=1
# baud=4000000 idle=1
order=2
device=/dev/ttyUSB0
stty -F $device raw $baud
sox blah.ogg -t s16 -c 1 -r $((baud/(1+8+1+idle))) - | ./pwm $order > $device
#include <stdio.h>
#include <stdlib.h>
int sigma_delta_modulation(int x, int order)
{
static int sum;
if (!order)
sum = x;
int y = sum >> 13;
if (y < 0)
y = 0;
if (y > 8)
y = 8;
int e = y << 13;
if (order >= 2) {
static int sum2;
sum2 += x - e;
x = sum2;
}
sum += x - e;
return y;
}
int main(int argc, char **argv)
{
int order = 1;
if (argc == 2)
order = atoi(argv[1]);
for (short input; fread_unlocked(&input, 2, 1, stdin) == 1;)
if (EOF == putchar_unlocked(-256 >> sigma_delta_modulation(input+32768, order)))
return 1;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment