aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/fl2k_ampliphase.c141
1 files changed, 80 insertions, 61 deletions
diff --git a/src/fl2k_ampliphase.c b/src/fl2k_ampliphase.c
index e40a5e8..1b92a5c 100644
--- a/src/fl2k_ampliphase.c
+++ b/src/fl2k_ampliphase.c
@@ -62,7 +62,7 @@ enum inputType_E { INP_REAL, INP_COMPLEX };
#define BASEBAND_BUF_SIZE 2048
fl2k_dev_t *dev = NULL;
-volatile int do_exit = 0;
+sig_atomic_t do_exit = 0;
pthread_t iq_thread;
pthread_mutex_t cb_mutex;
@@ -77,8 +77,8 @@ int swap_iq = 0;
// main thread reads from file and writes into pdbuf and pdslopebuf, if full it waits on iq_cond.
// iq_worker thread reads from pdbuf and pdslopebuf at readpos (protected by
// mutex because both threads read its value)
-long int * pdbuf;
-long int * pdslopebuf;
+int32_t * pdbuf;
+int32_t * pdslopebuf;
int writepos = 0;
pthread_mutex_t readpos_mutex;
int readpos = 0;
@@ -136,6 +136,7 @@ sighandler(int signum)
fl2k_stop_tx(dev);
do_exit = 1;
pthread_cond_signal(&iq_cond);
+ pthread_cond_signal(&cb_cond);
return TRUE;
}
return FALSE;
@@ -147,6 +148,7 @@ static void sighandler(int signum)
fl2k_stop_tx(dev);
do_exit = 1;
pthread_cond_signal(&iq_cond);
+ pthread_cond_signal(&cb_cond);
}
#endif
@@ -165,9 +167,9 @@ static void sighandler(int signum)
#define TRIG_TABLE_ORDER 8
#define TRIG_TABLE_SHIFT (32 - TRIG_TABLE_ORDER)
#define TRIG_TABLE_LEN (1 << TRIG_TABLE_ORDER)
-//#define ANG_INCR (0xffffffff / DDS_2PI)
-#define INT_2PI (0x100000000)
-#define ANG_INCR ((float)INT_2PI) / DDS_2PI
+
+#define INT32_MAX_AS_FLOAT ((float)(0x100000000))
+#define ANG_INCR (INT32_MAX_AS_FLOAT / DDS_2PI)
enum waveform_E { WF_SINE, WF_RECT };
@@ -183,13 +185,13 @@ typedef struct {
float sample_freq;
float freq;
/* instantaneous phase */
- unsigned long int phase;
+ uint32_t phase;
/* phase increment */
- unsigned long int phase_step;
+ uint32_t phase_step;
/* for phase modulation */
- long int phase_delta;
- long int phase_slope;
+ int32_t phase_delta;
+ int32_t phase_slope;
/* for amplitude modulation */
complex float amplitude;
@@ -210,7 +212,7 @@ static inline void dds_set_amp(dds_t *dds, complex float amplitude, complex floa
dds->ampslope = ampslope;
}
-static inline void dds_set_phase(dds_t *dds, long int phase_delta, long int phase_slope)
+static inline void dds_set_phase(dds_t *dds, int32_t phase_delta, int32_t phase_slope)
{
dds->phase_delta = phase_delta;
dds->phase_slope = phase_slope;
@@ -250,34 +252,32 @@ dds_t dds_init(float sample_freq, float freq, float phase, float amp, enum wavef
static inline void dds_complex(dds_t *dds, int8_t * i, int8_t * q)
{
- int phase_idx_i, phase_idx_q;
+ uint32_t phase_idx_i, phase_idx_q;
int32_t amp_i, amp_q;
- // get current carrier phase, add phase mod, calculate table index
+ // get current carrier phase, add phase mod, calculate table index
phase_idx_i = (dds->phase - dds->phase_delta) >> TRIG_TABLE_SHIFT;
phase_idx_q = (dds->phase + dds->phase_delta) >> TRIG_TABLE_SHIFT;
- // advance dds generator
+ if (phase_idx_q > 255 || phase_idx_i > 255) {
+ fprintf(stderr, "phase_idx_q %d\n", phase_idx_q);
+ fprintf(stderr, "phase_idx_i %d\n", phase_idx_i);
+ fprintf(stderr, " dds->phase %u\n", dds->phase);
+ fprintf(stderr, " dds->phase_delta %d\n", dds->phase_delta);
+ fprintf(stderr, " sum %d\n", dds->phase + dds->phase_delta);
+ fprintf(stderr, " shift by %d\n", TRIG_TABLE_SHIFT);
+ abort();
+ }
+
+ // advance dds generator, wraparound on overflow
dds->phase += dds->phase_step;
- // wrap around properly
- dds->phase &= 0xffffffff;
//amp = 255;
amp_i = (int32_t) (creal(dds->amplitude) * 32767.0); // 0..15
amp_q = (int32_t) (cimag(dds->amplitude) * 32767.0);
- if (phase_idx_i < 0 || phase_idx_i > 255) {
- fprintf(stderr, "phase_idx_i wrong: %d\n", phase_idx_i);
- fprintf(stderr, " dds->phase %ld\n", dds->phase);
- fprintf(stderr, " dds->phase_delta %ld\n", dds->phase_delta);
- abort();
- }
amp_i = amp_i * trig_table.inphase[phase_idx_i]; // 0..31
//
- if (phase_idx_q < 0 || phase_idx_q > 255) {
- fprintf(stderr, "phase_idx_q wrong: %d\n", phase_idx_q);
- abort();
- }
amp_q = amp_q * trig_table.quadrature[phase_idx_q]; // 0..31
*i = (int8_t) (amp_i >> 24); // 0..31 >> 24 => 0..8
@@ -338,9 +338,13 @@ static void *iq_worker(void *arg)
qambuf = qtxbuf;
qtxbuf = tmp_ptr;
+ fprintf(stderr, ".");
pthread_mutex_lock(&cb_mutex);
pthread_cond_wait(&cb_cond, &cb_mutex);
pthread_mutex_unlock(&cb_mutex);
+ if (do_exit) {
+ break;
+ }
}
dds_complex_buf(&base_signal, iambuf, qambuf, remaining);
@@ -363,16 +367,18 @@ static void *iq_worker(void *arg)
static inline int writelen(int maxlen)
{
+ int rp, len, r;
+
pthread_mutex_lock(&readpos_mutex);
- int rp = readpos;
+ rp = readpos;
pthread_mutex_unlock(&readpos_mutex);
if (rp < writepos)
rp += BUFFER_SAMPLES;
- int len = rp - writepos;
+ len = rp - writepos;
- int r = len > maxlen ? maxlen : len;
+ r = len > maxlen ? maxlen : len;
return r;
}
@@ -381,8 +387,7 @@ static inline int writelen(int maxlen)
static inline float modulate_sample_ampliphase(const int lastwritepos, const float lastamp, const float sample, float modulationIndex)
{
- float amp;
- float slope;
+ float amp, slope, pd, pdslope;
/* Calculate modulator amplitudes at this point to lessen
* the calculations needed in the signal generator */
@@ -401,15 +406,28 @@ static inline float modulate_sample_ampliphase(const int lastwritepos, const flo
/* -1 .. 1 * 45° */
/* -1 .. 1 * 0.25 * 2 Pi */
/* -1 .. 1 * 0.25 * 2 Pi */
- pdbuf[writepos] = (long int) (lastamp * modulationIndex * (float) INT_2PI);
- pdslopebuf[writepos] = (long int) (slope * modulationIndex * (float) INT_2PI);
+
+ pd = lastamp * modulationIndex * INT32_MAX_AS_FLOAT;
+ if (pd < (float)INT32_MIN || pd > (float)INT32_MAX) {
+ fprintf(stderr, "pd out of bounds %f\n", pd);
+ abort();
+ }
+
+ pdslope = slope * modulationIndex * INT32_MAX_AS_FLOAT;
+ if (pdslope < (float)INT32_MIN || pdslope > (float)INT32_MAX) {
+ fprintf(stderr, "pdslope out of bounds %f\n", pdslope);
+ abort();
+ }
+
+ pdbuf[writepos] = pd;
+ pdslopebuf[writepos] = pdslope;
return amp;
}
-void ampliphase_modulator(enum inputType_E inputType, const float modIndex)
+void ampliphase_modulator(enum inputType_E input_type, const float modulation_index)
{
/*
* upper path: +45° Carrier -> Phase-Mod +/-45° * Audio In -> Squarer -> Drive
@@ -435,9 +453,9 @@ void ampliphase_modulator(enum inputType_E inputType, const float modIndex)
int swap = swap_iq;
len = writelen(BASEBAND_BUF_SIZE);
if (len > /* for efficiency, do not read 1 sample at a time */ BASEBAND_BUF_SIZE/4) {
- if (inputType == INP_REAL) {
+ if (input_type == INP_REAL) {
len = fread(baseband_buf_real, 1, len, file);
- for(i = 0 ; i < len; i++){
+ for (i = 0 ; i < len; i++) {
/* input is -1.0 .. +1.0 (-32768 .. 32767)
* transform to 0.0 .. +1.0 (0 .. 32767)
* put into I part of BB
@@ -454,11 +472,11 @@ void ampliphase_modulator(enum inputType_E inputType, const float modIndex)
len = fread(baseband_buf_cplx, 2, len, file);
}
- if (len == 0){
- if(ferror(file)){
+ if (len == 0) {
+ if (ferror(file)) {
do_exit = 1;
}
- if(!ignore_eof && feof(file)){
+ if (!ignore_eof && feof(file)) {
do_exit = 1;
}
}
@@ -470,7 +488,7 @@ void ampliphase_modulator(enum inputType_E inputType, const float modIndex)
sample = (float) baseband_buf_cplx[i][0+swap] / 32768.0;
/* Modulate and buffer the sample */
- lastamp = modulate_sample_ampliphase(lastwritepos, lastamp, sample, modIndex);
+ lastamp = modulate_sample_ampliphase(lastwritepos, lastamp, sample, modulation_index);
lastwritepos = writepos++;
writepos %= BUFFER_SAMPLES;
}
@@ -488,9 +506,7 @@ void fl2k_callback(fl2k_data_info_t *data_info)
if (data_info->device_error) {
fprintf(stderr, "Device error, exiting.\n");
do_exit = 1;
- pthread_mutex_lock(&iq_mutex);
pthread_cond_signal(&iq_cond);
- pthread_mutex_unlock(&iq_mutex);
}
pthread_cond_signal(&cb_cond);
@@ -501,25 +517,24 @@ void fl2k_callback(fl2k_data_info_t *data_info)
}
-
-static void *file_worker(void *arg){
+static void *file_worker(void *arg) {
FILE * f;
- uint32_t * filebuf;
+ uint16_t * filebuf;
int i;
const size_t len = sizeof(*filebuf) * FL2K_BUF_LEN;
size_t wrote;
f = arg;
filebuf = malloc(len);
- if(filebuf == NULL){
+ if (filebuf == NULL) {
fprintf(stderr, "Error allocating debug file buffer.\n");
}
else {
while (!do_exit){
- for(i=0;i<FL2K_BUF_LEN;i++){
- filebuf[i] = (itxbuf[i] & 0xff) | ((uint32_t) qtxbuf[i]) << 8;
+ for (i = 0; i < FL2K_BUF_LEN; i++){
+ filebuf[i] = ((uint16_t)itxbuf[i]) | (((uint16_t)qtxbuf[i]) << 8);
}
- wrote = fwrite(filebuf, sizeof(len), 1, f);
+ wrote = fwrite(filebuf, len, 1, f);
if (wrote != 1){
perror("Error writing to debug file");
break;
@@ -528,9 +543,8 @@ static void *file_worker(void *arg){
}
}
do_exit = 1;
- pthread_mutex_lock(&iq_mutex);
+ fclose(f);
pthread_cond_signal(&iq_cond);
- pthread_mutex_unlock(&iq_mutex);
if (filebuf) free(filebuf);
return NULL;
}
@@ -653,15 +667,15 @@ int main(int argc, char **argv)
/* Baseband buffer */
- pdbuf = malloc(BUFFER_SAMPLES * sizeof(long int));
- pdslopebuf = malloc(BUFFER_SAMPLES * sizeof(long int));
+ pdbuf = malloc(BUFFER_SAMPLES * sizeof(*pdbuf));
+ pdslopebuf = malloc(BUFFER_SAMPLES * sizeof(*pdbuf));
if (!pdbuf || !pdslopebuf) {
fprintf(stderr, "malloc error!\n");
exit(1);
}
- memset(pdbuf, 0, BUFFER_SAMPLES * sizeof(long int));
- memset(pdslopebuf, 0, BUFFER_SAMPLES * sizeof(long int));
+ memset(pdbuf, 0, BUFFER_SAMPLES * sizeof(*pdbuf));
+ memset(pdslopebuf, 0, BUFFER_SAMPLES * sizeof(*pdbuf));
fprintf(stdout, "Samplerate: %3.2f MHz\n", (float)samp_rate/1000000);
fprintf(stdout, "Center frequency: %5.0f kHz\n", (float)base_freq/1000);
@@ -677,7 +691,7 @@ int main(int argc, char **argv)
pthread_cond_init(&iq_cond, NULL);
pthread_attr_init(&attr);
- if(debug_to_file){
+ if (debug_to_file) {
fDbg = fopen("debug.out","wb");
if(fDbg == NULL){
fprintf(stderr, "Failed to open 'debug.out' file.\n");
@@ -690,8 +704,7 @@ int main(int argc, char **argv)
goto out;
}
}
- else
- {
+ else {
fl2k_open(&dev, (uint32_t)dev_index);
if (NULL == dev) {
fprintf(stderr, "Failed to open fl2k device #%d.\n", dev_index);
@@ -706,7 +719,7 @@ int main(int argc, char **argv)
}
pthread_attr_destroy(&attr);
- if(!debug_to_file){
+ if (!debug_to_file){
r = fl2k_start_tx(dev, fl2k_callback, NULL, 0);
/* Set the sample rate */
@@ -736,12 +749,18 @@ int main(int argc, char **argv)
ampliphase_modulator(input_type, modulation_index);
out:
- if(!debug_to_file){
+ if (!debug_to_file){
fl2k_close(dev);
}
- if (file != stdin)
+ if (file != stdin) {
fclose(file);
+ }
+
+ pthread_join(iq_thread, NULL);
+ if (debug_to_file) {
+ pthread_join(dbg_thread, NULL);
+ }
free(pdbuf);
free(pdslopebuf);