From fbfdee9d8e0522dcc98b3f1a3f49309f864d2108 Mon Sep 17 00:00:00 2001 From: Zilog80 Date: Mon, 16 Nov 2015 17:54:41 +0100 Subject: [PATCH] Translation von IQ-Signalen --- iq/shift_IQ.c | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 iq/shift_IQ.c diff --git a/iq/shift_IQ.c b/iq/shift_IQ.c new file mode 100644 index 0000000..30e2c62 --- /dev/null +++ b/iq/shift_IQ.c @@ -0,0 +1,163 @@ + +/* + * ./shift [freq] [> IQ_translated.wav] + */ + +/* + sdrsharpIQ.wav = conj(rtlsdrIQ.wav) -> rtlsdrIQ.wav: swapIQ +*/ +/* + time domain frequency domain + w(t) = exp(t*i*2pi*f0)*z(t) <-> W(f) = Z(f-f0) + + z = x + iy + w = u + iv = exp(ia)*z + u = x*cos(a) - y*sin(a); + v = x*sin(a) + y*cos(a); + +*/ + +#include +#include +#include +#include + + +#define PI (3.1415926535897932384626433832795) + +int sample_rate, bits_sample; + + +int findstr(char *buff, char *str, int pos) { + int i; + for (i = 0; i < 4; i++) { + if (buff[(pos+i)%4] != str[i]) break; + } + return i; +} +int read_IQwavheader(FILE *fp, int *sample_rate, int *bits_sample, FILE *fout) { + int channels = 0; + char txt[4+1] = "\0\0\0\0"; + unsigned char dat[4]; + int byte, p=0; + + if (fread(txt, 1, 4, fp) < 4) return -1; else fwrite(txt, 1, 4, fout); + if (strncmp(txt, "RIFF", 4)) return -1; + + // pos_WAVE = 8L + if (fread(txt, 1, 4, fp) < 4) return -1; else fwrite(txt, 1, 4, fout); + if (fread(txt, 1, 4, fp) < 4) return -1; else fwrite(txt, 1, 4, fout); + if (strncmp(txt, "WAVE", 4)) return -1; + + // pos_fmt = 12L + for ( ; ; ) { + if ( (byte=fgetc(fp)) == EOF ) return -1; else fprintf(fout, "%c", byte & 0xFF); + txt[p % 4] = byte; + p++; if (p==4) p=0; + if (findstr(txt, "fmt ", p) == 4) break; + } + + if (fread(dat, 1, 4, fp) < 4) return -1; else fwrite(dat, 1, 4, fout); + if (fread(dat, 1, 2, fp) < 2) return -1; else fwrite(dat, 1, 2, fout); + + if (fread(dat, 1, 2, fp) < 2) return -1; else fwrite(dat, 1, 2, fout); + channels = dat[0] + (dat[1] << 8); + + if (fread(dat, 1, 4, fp) < 4) return -1; else fwrite(dat, 1, 4, fout); + *sample_rate = dat[0] | (dat[1] << 8) | (dat[2] << 16) | (dat[3] << 24); //memcpy(&sr, dat, 4); + + if (fread(dat, 1, 4, fp) < 4) return -1; else fwrite(dat, 1, 4, fout); + if (fread(dat, 1, 2, fp) < 2) return -1; else fwrite(dat, 1, 2, fout); + + if (fread(dat, 1, 2, fp) < 2) return -1; else fwrite(dat, 1, 2, fout); + *bits_sample = dat[0] + (dat[1] << 8); + + // pos_dat = 36L + info + for ( ; ; ) { + if ( (byte=fgetc(fp)) == EOF ) return -1; else fprintf(fout, "%c", byte & 0xFF); + txt[p % 4] = byte; + p++; if (p==4) p=0; + if (findstr(txt, "data", p) == 4) break; + } + if (fread(dat, 1, 4, fp) < 4) return -1; else fwrite(dat, 1, 4, fout); + + + fprintf(stderr, "sample_rate: %d\n", *sample_rate); + fprintf(stderr, "bits : %d\n", *bits_sample); + fprintf(stderr, "channels : %d\n", channels); + + if ((*bits_sample != 8) && (*bits_sample != 16)) return -2; + if (channels != 2) return -3; + + return 0; +} + +int read_csample(FILE *fp, double complex *z) { + short x, y; + + if (fread( &x, bits_sample/8, 1, fp) != 1) return EOF; + if (fread( &y, bits_sample/8, 1, fp) != 1) return EOF; + + *z = x + I*y; + + if (bits_sample == 8) { + *z -= 128 + I*128; + } + + return 0; +} + +int write_csample(FILE *fp, double complex w) { + int u, v; + + if (bits_sample == 8) { + w += 128 + I*128; + } + + u = creal(w); + v = cimag(w); + // 16 bit (short) -> (int) + fwrite( &u, bits_sample/8, 1, fp); // + 0000 .. 7FFF -> 0000 0000 .. 0000 7FFF + fwrite( &v, bits_sample/8, 1, fp); // - 8000 .. FFFF -> FFFF 8000 .. FFFF FFFF + + return 0; + +} + + +int main(int argc, char *argv[]) { + FILE *fp, *fout; + int sample = 0; + double t, f = 0; + double complex z, w; + + if (argv[1]) { + + fp = fopen(argv[1], "rb"); + if (fp == NULL) return -1; + + fout = stdout; //fopen("tmp_out.wav", "wb"); + read_IQwavheader(fp, &sample_rate, &bits_sample, fout); + + if (argv[2]) f = (double)atoi(argv[2]); // f0 + + sample = 0; + for ( ; ; ) { + + if (read_csample(fp, &z) == EOF) break; + + t = (double)sample / sample_rate; + w = cexp(t*2*PI*f*I) * z; + + write_csample(fout, w); + sample++; + + } + + fclose(fp); + fclose(fout); + } + + return 0; +} +