diff options
-rw-r--r-- | src/fl2k_ampliphase.c | 141 |
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); |