The fl2k_file command line tool needs a file with 8 bit signed samples. These are clocked out at 100M samples per second by default.
To get started I've written some pretty inefficient c to write out suitable files.
First here's a function that writes a suitable simple sine wave carrier. (I use 80 samples per cycle to get RF on 1.25MHz).
#include
#include
#include
const char *outFileName = "samples.dat";
void makeCarrier(int samplesPerCycle) {
FILE *outfile = fopen(outFileName, "wb");
int8_t byte;
for(int sample = 0; sample < samplesPerCycle; sample++) {
double current_radian = M_PI * sample * 2 / samplesPerCycle;
double carrier_sin_value = sin(current_radian);
byte = (int8_t)(carrier_sin_value * 127.0);
printf("%f, val = %f, byte = %d\n", current_radian, carrier_sin_value, (int)byte);
fwrite(&byte, sizeof(byte), 1, outfile);
}
fclose(outfile);
}
Double sideband can be generated by simply multiplying samples of a modulating sine wave by the samples of the carrier.
// Produces an double sideband signal suitable for fl2k_file
void makeDsb(int samplesPerCycle) {
// ratio of the carrier to the modulating sine wave
int ratio = 3000;
FILE *outfile = fopen(outFileName, "wb");
// make sure we get enough samples for a full wave of the modulation
int totalSamples = samplesPerCycle * ratio;
for(int sample = 0; sample < totalSamples; sample++) {
double carrier_radian = fmod((M_PI * sample * 2 / samplesPerCycle),(M_PI * 2));
double mod_radian = fmod((M_PI * sample * 2 / samplesPerCycle) / ratio,(M_PI * 2));
//printf("%03d carrier r = %f, mod r = %f\n", sample, carrier_radian, mod_radian);
double carrier_sin_value = sin(carrier_radian);
double mod_sin_value = sin(mod_radian);
double am_sample = carrier_sin_value * mod_sin_value;
//printf("%f\t%f\t%f\n", carrier_sin_value, mod_sin_value, am_sample);
int8_t byte = (int8_t)(am_sample * 127.0);
//printf("byte = %d\n", byte);
fwrite(&byte, sizeof(byte), 1, outfile);
}
fclose(outfile);
}
AM requires the modulating audio (ranging from -1 to +1) to have 1 added to it and the result divided by 2 before again multiplying by samples in the carrier sine wave.
// Produces an AM'd signal suitable for fl2k_file
void makeAm(int samplesPerCycle) {
// ratio of the carrier to the modulating sine wave
int ratio = 3000;
FILE *outfile = fopen(outFileName, "wb");
// make sure we get enough samples for a full wave of the modulation
int totalSamples = samplesPerCycle * ratio;
for(int sample = 0; sample < totalSamples; sample++) {
double carrier_radian = fmod((M_PI * sample * 2 / samplesPerCycle),(M_PI * 2));
double mod_radian = fmod((M_PI * sample * 2 / samplesPerCycle) / ratio,(M_PI * 2));
//printf("%03d carrier r = %f, mod r = %f\n", sample, carrier_radian, mod_radian);
double carrier_sin_value = sin(carrier_radian);
double mod_sin_value = (sin(mod_radian) + 1.0) / 2.0;
double am_sample = carrier_sin_value * mod_sin_value;
//printf("%f\t%f\t%f\n", carrier_sin_value, mod_sin_value, am_sample);
int8_t byte = (int8_t)(am_sample * 127.0);
//printf("byte = %d\n", byte);
fwrite(&byte, sizeof(byte), 1, outfile);
}
fclose(outfile);
}
Here's how AM looks:
The file is transmitted with fl2k_file simply as:
fl2k_file samples.dat
The output AM can view viewed on a CRO.
And shown on an SDR, here it is in SDR#. You can see the carrier and two nice sidebands.
On an AM radio, I hear a strong carrier with nice sounding tone.
I realise this is all very basic stuff but it's been great to learn a bit about it. The real power tool in all this is GRC (GNU Radio Companion).
Here's how I generate an amplitude modulated carrier suitable for sending to the fl2k dongle. (Click to enlarge it so you can read it).
The GNU Radio flow document is here.
Note that GRC always defaults to complex and in this case we want floats. This will run indefinitely and fill up your disk so just run for a few seconds and then open the file in Audacity to have a look at the waveform.
To avoid local AM stations I've been sending it with "fl2k_file -s 80e6 am_out.dat" which puts it on about 900kHz on the broadcast band.
Here's a GRC flow graph that shows how I read a WAV file with audio (ELO don't bring me down), resample it up and produce AM'd carrier to transmit. (Again click to read it).
Here's how it sounds on an AM radio.
Anyone know how to do this but with single side band?
Update: Ross transmits decodable WSPR
Transmitting a captured audio output from WSJT-X on AM, Ross has been able to decode the transmission.