RS-tracker/rs_module/rs_demod.c

174 wiersze
4.4 KiB
C

#include <stdio.h>
#include <string.h>
#include "rs_data.h"
#include "rs_demod.h"
static int sample_rate = 0,
bits_sample = 0,
channels = 0;
static float samples_per_bit = 0.0;
static 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_wav_header(FILE *fp, rs_data_t *rs_data) {
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;
if (strncmp(txt, "RIFF", 4)) return -1;
if (fread(txt, 1, 4, fp) < 4) return -1;
// pos_WAVE = 8L
if (fread(txt, 1, 4, fp) < 4) return -1;
if (strncmp(txt, "WAVE", 4)) return -1;
// pos_fmt = 12L
for ( ; ; ) {
if ( (byte=fgetc(fp)) == EOF ) return -1;
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;
if (fread(dat, 1, 2, fp) < 2) return -1;
if (fread(dat, 1, 2, fp) < 2) return -1;
channels = dat[0] + (dat[1] << 8);
if (fread(dat, 1, 4, fp) < 4) return -1;
// memcpy(&sample_rate, dat, 4); // string.h
sample_rate = dat[0]|(dat[1]<<8)|(dat[2]<<16)|(dat[3]<<24);
if (fread(dat, 1, 4, fp) < 4) return -1;
if (fread(dat, 1, 2, fp) < 2) return -1;
//byte = dat[0] + (dat[1] << 8);
if (fread(dat, 1, 2, fp) < 2) return -1;
bits_sample = dat[0] + (dat[1] << 8);
// pos_dat = 36L + info
for ( ; ; ) {
if ( (byte=fgetc(fp)) == EOF ) return -1;
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;
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 -1;
samples_per_bit = sample_rate/rs_data->baud;
fprintf(stderr, "samples/bit: %.2f\n", samples_per_bit);
rs_data->samples_per_bit = samples_per_bit;
return 0;
}
#define EOF_INT 0x1000000
static unsigned long sample_count = 0;
static int read_signed_sample(FILE *fp) { // int = i32_t
int byte, i, sample, s=0; // EOF -> 0x1000000
for (i = 0; i < channels; i++) {
// i = 0: left/mono
byte = fgetc(fp);
if (byte == EOF) return EOF_INT;
if (i == 0) sample = byte;
if (bits_sample == 16) {
byte = fgetc(fp);
if (byte == EOF) return EOF_INT;
if (i == 0) sample += byte << 8;
}
}
if (bits_sample == 8) s = sample-128; // 8bit: 00..FF, centerpoint 0x80=128
if (bits_sample == 16) s = (short)sample;
sample_count++;
return s;
}
static int par=1, par_alt=1;
int read_bits_fsk(FILE *fp, int *bit, int *len, int inv) {
int option_res = 0;
static int sample;
int n, y0;
float l, x1;
static float x0;
n = 0;
do{
y0 = sample;
sample = read_signed_sample(fp);
if (sample == EOF_INT) return EOF;
//sample_count++; // in read_signed_sample()
par_alt = par;
par = (sample >= 0) ? 1 : -1; // 8bit: 0..127,128..255 (-128..-1,0..127)
n++;
} while (par*par_alt > 0);
if (!option_res) l = (float)n / samples_per_bit;
else { // genauere Bitlaengen-Messung
x1 = sample/(float)(sample-y0); // hilft bei niedriger sample rate
l = (n+x0-x1) / samples_per_bit; // meist mehr frames (nicht immer)
x0 = x1;
}
*len = (int)(l+0.5);
if (!inv) *bit = (1+par_alt)/2; // oben 1, unten -1
else *bit = (1-par_alt)/2; // sdr#<rev1381?, invers: unten 1, oben -1
/* Y-offset ? */
return 0;
}
/* ------------------------------------------------------------------------------------ */
void inc_bufpos(rs_data_t *rs_data) {
rs_data->bufpos = (rs_data->bufpos+1) % rs_data->header_len;
}
int compare(rs_data_t *rs_data) {
int i=0, j = rs_data->bufpos;
while (i < rs_data->header_len) {
if (j < 0) j = rs_data->header_len-1;
if (rs_data->buf[j] != rs_data->header[rs_data->header_ofs+rs_data->header_len-1-i]) break;
j--;
i++;
}
return i;
}
/* ------------------------------------------------------------------------------------ */