I'm pretty sure about the parity bit, but knowing that the parity is incorrect doesn't do you much good!
The B block start certainly looks to be correct, but there is no sign of a "G" end marker.
I tried baud rate 561, and that clearly helped.
The baud rate and frequencies are in these four lines, with the assumed baud rate being the last constant (561). Also, the number of bits per baud NPERBAUD = sample rate/ baud rate, currently 78.
coeffloi[i] = 100*cos(2*PI*i/NPERBAUD*2200/561);
coeffloq[i] = 100*sin(2*PI*i/NPERBAUD*2200/561);
coeffhii[i] = 100*cos(2*PI*i/NPERBAUD*4400/561);
coeffhiq[i] = 100*sin(2*PI*i/NPERBAUD*4400/561);
I've attached what I was able to decode without getting fancy. It appears that there are two copies of Editor/Assembler in the successfully decoded portion of that file. I used an editor to add two newlines at the beginning of each block.
The current code, slightly cleaned up:
//KCS tape decode, fourier transform version.
// works perfectly with example file good-example.wav (resampled to 8 bits and 9600 bps)
// modified for Nick Gammon's tape
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <math.h>
//for Code::Blocks
// project->build options->search directories, add (lib,include)
// linker settings: link libraries, add path to libsndfil\lib\libsndfile.lib
// copy bin\libsndfile-1.dll to source directory
#include <sndfile.h>
// number of sample bits per baud. 44100/561 = 78
#define NPERBAUD 78
#define PI 3.1415926536
// uart variables
#define IDLE 1
#define START 2
#define RUN 4
#define RXFLAG 8
#define FRAMERR 16
#define STOP 32
#define PARITY 64
int coeffloi[NPERBAUD],coeffloq[NPERBAUD],coeffhii[NPERBAUD],coeffhiq[NPERBAUD];
void initFSK(void)
{
int i;
for (i=0; i<NPERBAUD; i++)
{
coeffloi[i] = 100*cos(2*PI*i/NPERBAUD*2200/561);
coeffloq[i] = 100*sin(2*PI*i/NPERBAUD*2200/561);
coeffhii[i] = 100*cos(2*PI*i/NPERBAUD*4400/561);
coeffhiq[i] = 100*sin(2*PI*i/NPERBAUD*4400/561);
// printf("%2d %5d %5d %5d %5d\n",i,coeffloi[i],coeffloq[i],coeffhii[i],coeffhiq[i]);
}
}
/*
https://sites.google.com/site/wayneholder/attiny-4-5-9-10-assembly-ide-and-programmer/bell-202-1200-baud-demodulator-in-an-attiny10
Modified for Kansas City Standard, 300 baud, 1200/2400
Sample the incoming FSK signal at 9600 samples/second (8 times the 1200 Hz frequency used in Bell 202 modulation)
Pass this through two digital filters, one tuned to 1200 Hz and the other to 2400 Hz.
The function is called for index = 0 through length(data) - 8
After stepping though at least 8 samples, the value returned from demodulate() will be >0 if it has
demodulated a 2400 Hz tone, or < 0 for a 1200 Hz tone.
*/
int demodulate (signed char data[]) {
int outloi = 0, outloq = 0, outhii = 0, outhiq = 0;
int ii;
int sample;
for (ii = 0; ii < NPERBAUD; ii++) {
sample = data[ii];
outloi += sample * coeffloi[ii];
outloq += sample * coeffloq[ii];
outhii += sample * coeffhii[ii];
outhiq += sample * coeffhiq[ii];
}
return (outhii >> 8) * (outhii >> 8) + (outhiq >> 8) * (outhiq >> 8) -
(outloi >> 8) * (outloi >> 8) - (outloq >> 8) * (outloq >> 8);
}
int main()
{
// file handling
SNDFILE *sf;
SF_INFO info;
int num_channels;
int num, num_items;
int *buf;
int f,sr,c;
int i,j;
FILE *out;
// decode and uart
static char rx,ch;
static short status = IDLE;
static int clock = 0; // counter for sample
static int bit = 0; // bit counter
static char parity=0;
signed char buf2[NPERBAUD]={0}; //signal samples
int k,spb=NPERBAUD; //samples per bit
int result,output,count=0;
initFSK();
/* Open the WAV file. */
info.format = 0;
sf = sf_open("AE44k.wav",SFM_READ,&info);
// sf = sf_open("CID-test.wav",SFM_READ,&info);
if (sf == NULL)
{
printf("Failed to open input file.\n");
exit(-1);
}
/* Print some of the info, and figure out how much data to read. */
f = info.frames;
sr = info.samplerate;
c = info.channels;
printf("frames = %d\n",f);
printf("sample rate = %d\n",sr);
printf("channels = %d\n",c);
printf("format = %X\n",info.format);
num_items = f*c;
printf("num_items = %d\n",num_items);
/* Allocate space for the data to be read, then read it. */
buf = (int *) malloc(num_items*sizeof(int));
num = sf_read_int(sf,buf,num_items);
sf_close(sf);
printf("Read %d items\n",num);
//Write data and demodulator output to filedata.out.
out = fopen("filedata.txt","w");
k=0;
for (i = 0; i < num_items - NPERBAUD; i += c)
{
for(k=0; k<NPERBAUD-1; k++) buf2[k]=buf2[k+1]; //shuffle to the left
buf2[NPERBAUD-1] = (signed char) ((unsigned int)buf[i]>>24);
result = demodulate(buf2);
if(result>0) result=1; else result=0;
// now we can build a uart
// the byte is delivered in 11 bit chunks...
// in order,
// start bit (0)
// bit 0
// ...
// bit 7
// parity
// stop bit (1)
// see what our state is
if (status & IDLE) // we're idling
{
status &= ~RXFLAG;
status &= ~PARITY; //clear parity flag
if (!result) // falling edge of start bit
{
status &= ~IDLE; // so we idle no longer
status |= START; // we're started
bit = 0; // reset bit counter
clock = 0; // and the clock count
parity = 0;
}
// else we're still waiting for end of stop bit
}
else
{
if (status & START) // aha, we got the falling edge
{
if ((clock <= spb/2) && (result)) // oops, false trigger...noise perhaps
{
status &= ~START;
status |= IDLE; // so drop back to idle mode
}
else
clock++; // otherwise, one more clock
if (clock == spb/2) // or are we now in mid start-bit
{
status &= ~START;
status &= ~IDLE;
status |= RUN; // so now we're hot to trot
clock = 0; // reset counter
}
}
else
{
if (status & RUN) // we're reading data (allegedly)
{
if (clock < spb-1) // time for a sample?
clock++; // not yet
else
{
if (bit < 9) // normal read
{
if (bit < 8) { //skip parity bit
rx = rx>>1;
if (result) {
rx |= 0x80;
parity++; //count 1 bits
}
else rx &= 0x7f;
}
clock = 0;
bit ++;
}
else
{
if (! result) // frame error?
{
status |= FRAMERR; //if stop==0
}
else
{
status &= ~FRAMERR;
}
status |= IDLE;
status |= RXFLAG;
if (parity&1) status |= PARITY; //1 if # of 1 bits is odd
status &= ~RUN;
status &= ~START;
}
}
}
}
}
if (status & RXFLAG) { //added for debug, sjr
ch=rx&0x7f;
if(ch<32 || ch>126) {
fprintf(out,"<%02X>",(unsigned char)rx);
count += 4;
}
else {
fprintf(out,"%c",ch);
count++;
}
if(count > 79) {fprintf(out,"\n"); count=0;} //shorten long lines in output
} // end if (status & RXFLAG)
} //end for i to num_items
fclose(out);
return 0;
}
filedata_nl.txt (24 KB)