/*
- tlininterp.c
+ tdec.c
David Rowe
Jan 2017
- Linear interpolator, CPU effecient way of getting large oversample
- ratios, if the input is already limited to a fraction of the
- input sampling rate.
+ Trivial non filtered decimator for high ration sample rate conversion.
build: gcc tdec.c -o tdec -Wall -O2
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
+#include <stdint.h>
+
+#define SIGNED_16BIT 0
+#define SIGNED_8BIT 1
void display_help(void) {
fprintf(stderr, "\nusage: tdec inputRawFile OutputRawFile DecimationRatio [-c]\n");
fprintf(stderr, "\nUse - for stdin/stdout\n\n");
- fprintf(stderr, "-c complex (two channel) resampling\n\n");
+ fprintf(stderr, "-c complex signed 16 bit input and output\n");
+ fprintf(stderr, "-d complex signed 8 bit input, complex signed 16 bit output\n\n");
}
int main(int argc, char *argv[]) {
int channels = 1;
int opt;
- while ((opt = getopt(argc, argv, "c")) != -1) {
+ int format = SIGNED_16BIT;
+ while ((opt = getopt(argc, argv, "cd")) != -1) {
switch (opt) {
case 'c': channels = 2; break;
+ case 'd': channels = 2; format = SIGNED_8BIT; break;
default:
display_help();
exit(1);
}
}
- short buf[dec*channels];
- fprintf(stderr, "dec: %d\n", dec);
- while(fread(buf, sizeof(short)*channels, dec, fin) == dec) {
- fwrite(buf, sizeof(short), channels, fout);
+ if (format == SIGNED_16BIT) {
+ short buf[dec*channels];
+ while(fread(buf, sizeof(short)*channels, dec, fin) == dec) {
+ fwrite(buf, sizeof(short), channels, fout);
+ }
+ }
+ else {
+ uint8_t inbuf[dec*channels];
+ short outbuf[channels];
+ short sam, i;
+
+ while(fread(inbuf, sizeof(uint8_t)*channels, dec, fin) == dec) {
+ for (i=0; i<channels; i++) {
+ sam = (short)inbuf[i];
+ sam <<= 8;
+ outbuf[i] = sam;
+ }
+ fwrite(outbuf, sizeof(short), channels, fout);
+ }
+
}
fclose(fout);
David Rowe
Jan 2017
- Linear interpolator, CPU effecient way of getting large oversample
- ratios, if the input is already limited to a fraction of the
- input sampling rate.
+ Fast linear interpolator for high oversam[pling rates. Upsample
+ with a decent filter first such that the signal is "low pass" wrt
+ to the input sample rate.
build: gcc tlininterp.c -o tlininterp -Wall -O2
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
+#include <stdint.h>
-#define N 10000 /* processing buffer size */
+#define SIGNED_16BIT 0
+#define SIGNED_8BIT 1
void display_help(void) {
fprintf(stderr, "\nusage: tlininterp inputRawFile OutputRawFile OverSampleRatio [-c]\n");
fprintf(stderr, "\nUse - for stdin/stdout\n\n");
- fprintf(stderr, "-c complex (two channel) resampling\n\n");
+ fprintf(stderr, "-c complex signed 16 bit input and output\n");
+ fprintf(stderr, "-d complex signed 16 bit input, complex signed 8 bit output\n\n");
}
int main(int argc, char *argv[]) {
FILE *fin, *fout;
- short left, right, out;
+ short left[2], right[2], out[2], i;
float oversample, t;
+ int8_t out_s8[2];
if (argc < 3) {
display_help();
oversample = atof(argv[3]);
int channels = 1;
+ int format = SIGNED_16BIT;
int opt;
- while ((opt = getopt(argc, argv, "c")) != -1) {
+ while ((opt = getopt(argc, argv, "cd")) != -1) {
switch (opt) {
case 'c': channels = 2; break;
+ case 'd': channels = 2; format = SIGNED_8BIT; break;
default:
display_help();
exit(1);
}
}
- left = 0;
+ for (i=0; i<channels; i++)
+ left[i] = 0;
t = 0.0;
- while(fread(&right, sizeof(short), 1, fin) == 1) {
+ while(fread(&right, sizeof(short)*channels, 1, fin) == 1) {
while (t < 1.0) {
- out = (1.0 - t)*left + t*right;
- fwrite(&out, sizeof(short), 1, fout);
+
+ for (i=0; i<channels; i++) {
+ out[i] = (1.0 - t)*left[i] + t*right[i];
+ }
+
+ if (format == SIGNED_16BIT) {
+ fwrite(&out, sizeof(short), channels, fout);
+ } else {
+ //fprintf(stderr,"8 bit out\n");
+ for (i=0; i<channels; i++) {
+ out_s8[i] = out[i] >> 8;
+ }
+ fwrite(&out_s8, sizeof(int8_t), channels, fout);
+ }
+
t += 1.0/oversample;
}
t -= 1.0;
- left = right;
+ for (i=0; i<channels; i++)
+ left[i] = right[i];
}
fclose(fout);