diff options
| -rw-r--r-- | src/DabMod.cpp | 12 | ||||
| -rw-r--r-- | src/OutputUHD.cpp | 80 | ||||
| -rw-r--r-- | src/OutputUHD.h | 3 | 
3 files changed, 53 insertions, 42 deletions
| diff --git a/src/DabMod.cpp b/src/DabMod.cpp index f9bc3c9..24dfe4f 100644 --- a/src/DabMod.cpp +++ b/src/DabMod.cpp @@ -95,8 +95,11 @@ void printUsage(char* progName, FILE* out = stderr)      fprintf(out, "-F frequency:  Set the transmit frequency when using UHD output. (mandatory option when using UHD)\n");      fprintf(out, "-G txgain:     Set the transmit gain for the UHD driver (default: 0)\n");      fprintf(out, "-o:            (UHD only) Set the timestamp offset added to the timestamp in the ETI. The offset is a double.\n"); -    fprintf(out, "-O:            (UHD only) Set the file containing the timestamp offset added to the timestamp in the ETI. The file is read every six seconds, and must contain a double value.\n"); -    fprintf(out, "                  Specifying either -o or -O make DABMOD mute frames that do not contain a valid timestamp.\n"); +    fprintf(out, "-O:            (UHD only) Set the file containing the timestamp offset added to the timestamp in the ETI.\n" +                                 "The file is read every six seconds, and must contain a double value.\n"); +    fprintf(out, "                  Specifying either -o or -O has two implications: It enables synchronous transmission,\n" +                 "                  requiring an external REFCLK and PPS signal and frames that do not contain a valid timestamp\n" +                 "                  get muted.\n\n");      fprintf(out, "-T taps_file:  Enable filtering before the output, using the specified file containing the filter taps.\n");      fprintf(out, "-a gain:       Apply digital amplitude gain.\n");      fprintf(out, "-c rate:       Set the DAC clock rate and enable Cic Equalisation.\n"); @@ -147,6 +150,7 @@ int main(int argc, char* argv[])      double uhdFrequency = 0.0;      int uhdTxGain = 0;      bool uhd_mute_no_timestamps = false; +    bool uhd_enable_sync = false;      FILE* inputFile = NULL;      uint32_t sync = 0; @@ -218,6 +222,7 @@ int main(int argc, char* argv[])              }              modconf.use_offset_fixed = true;              modconf.offset_fixed = strtod(optarg, NULL); +            uhd_enable_sync = true;              break;          case 'O':              if (modconf.use_offset_fixed) @@ -227,6 +232,7 @@ int main(int argc, char* argv[])              }              modconf.use_offset_file = true;              modconf.offset_filename = optarg; +            uhd_enable_sync = true;              break;          case 'm':              dabMode = strtol(optarg, NULL, 0); @@ -333,7 +339,7 @@ int main(int argc, char* argv[])      else if (useUHDOutput) {          fprintf(stderr, "Using UHD output\n");          amplitude /= 32000.0f; -        output = new OutputUHD(outputDevice, outputRate, uhdFrequency, uhdTxGain, uhd_mute_no_timestamps); +        output = new OutputUHD(outputDevice, outputRate, uhdFrequency, uhdTxGain, uhd_enable_sync, uhd_mute_no_timestamps);      }      flowgraph = new Flowgraph(); diff --git a/src/OutputUHD.cpp b/src/OutputUHD.cpp index 9e14a4f..f7825e3 100644 --- a/src/OutputUHD.cpp +++ b/src/OutputUHD.cpp @@ -38,9 +38,10 @@  typedef std::complex<float> complexf;  OutputUHD::OutputUHD(char* device, unsigned sampleRate, -        double frequency, int txgain, bool muteNoTimestamps) : +        double frequency, int txgain, bool enableSync, bool muteNoTimestamps) :      ModOutput(ModFormat(1), ModFormat(0)),      mySampleRate(sampleRate), myTxGain(txgain), +    enable_sync(enableSync),      myFrequency(frequency), mute_no_timestamps(muteNoTimestamps)  {      MDEBUG("OutputUHD::OutputUHD(device: %s) @ %p\n", @@ -57,12 +58,14 @@ OutputUHD::OutputUHD(char* device, unsigned sampleRate,      myUsrp = uhd::usrp::multi_usrp::make(myDevice);      MDEBUG("OutputUHD:Using device: %s...\n", myUsrp->get_pp_string().c_str()); -    MDEBUG("OutputUHD:Setting REFCLK and PPS input...\n"); -    uhd::clock_config_t clock_config; -    clock_config.ref_source = uhd::clock_config_t::REF_SMA; -    clock_config.pps_source = uhd::clock_config_t::PPS_SMA; -    clock_config.pps_polarity = uhd::clock_config_t::PPS_POS; -    myUsrp->set_clock_config(clock_config, uhd::usrp::multi_usrp::ALL_MBOARDS); +    if (enable_sync) { +        MDEBUG("OutputUHD:Setting REFCLK and PPS input...\n"); +        uhd::clock_config_t clock_config; +        clock_config.ref_source = uhd::clock_config_t::REF_SMA; +        clock_config.pps_source = uhd::clock_config_t::PPS_SMA; +        clock_config.pps_polarity = uhd::clock_config_t::PPS_POS; +        myUsrp->set_clock_config(clock_config, uhd::usrp::multi_usrp::ALL_MBOARDS); +    }      std::cerr << "UHD clock source is " <<               myUsrp->get_clock_source(0) << std::endl; @@ -84,39 +87,40 @@ OutputUHD::OutputUHD(char* device, unsigned sampleRate,      MDEBUG("OutputUHD:Actual TX Gain: %f ...\n", myUsrp->get_tx_gain()); -    /* handling time for synchronisation: wait until the next full -     * second, and set the USRP time at next PPS */ -    struct timespec now; -    time_t seconds; -    if (clock_gettime(CLOCK_REALTIME, &now)) { -        fprintf(stderr, "errno: %d\n", errno); -        perror("OutputUHD:Error: could not get time: "); -    } -    else { -        seconds = now.tv_sec; - -        MDEBUG("OutputUHD:sec+1: %ld ; now: %ld ...\n", seconds+1, now.tv_sec); -        while (seconds + 1 > now.tv_sec) { -            usleep(1); -            if (clock_gettime(CLOCK_REALTIME, &now)) { -                fprintf(stderr, "errno: %d\n", errno); -                perror("OutputUHD:Error: could not get time: "); -                break; +    if (enable_sync) { +        /* handling time for synchronisation: wait until the next full +         * second, and set the USRP time at next PPS */ +        struct timespec now; +        time_t seconds; +        if (clock_gettime(CLOCK_REALTIME, &now)) { +            fprintf(stderr, "errno: %d\n", errno); +            perror("OutputUHD:Error: could not get time: "); +        } +        else { +            seconds = now.tv_sec; + +            MDEBUG("OutputUHD:sec+1: %ld ; now: %ld ...\n", seconds+1, now.tv_sec); +            while (seconds + 1 > now.tv_sec) { +                usleep(1); +                if (clock_gettime(CLOCK_REALTIME, &now)) { +                    fprintf(stderr, "errno: %d\n", errno); +                    perror("OutputUHD:Error: could not get time: "); +                    break; +                }              } +            MDEBUG("OutputUHD:sec+1: %ld ; now: %ld ...\n", seconds+1, now.tv_sec); +            /* We are now shortly after the second change. */ + +            usleep(200000); // 200ms, we want the PPS to be later +            myUsrp->set_time_unknown_pps(uhd::time_spec_t(seconds + 2)); +            fprintf(stderr, "OutputUHD: Setting USRP time next pps to %f\n", +                    uhd::time_spec_t(seconds + 2).get_real_secs());          } -        MDEBUG("OutputUHD:sec+1: %ld ; now: %ld ...\n", seconds+1, now.tv_sec); -        /* We are now shortly after the second change. */ - -#warning "TODO usleep for USRP time setting !" -        //usleep(200000); // 200ms, we want the PPS to be later -        myUsrp->set_time_unknown_pps(uhd::time_spec_t(seconds + 2)); -        fprintf(stderr, "OutputUHD: Setting USRP time next pps to %f\n", -                uhd::time_spec_t(seconds + 2).get_real_secs()); -    } -    usleep(1e6); -    fprintf(stderr, "OutputUHD: USRP time %f\n", -            myUsrp->get_time_now().get_real_secs()); +        usleep(1e6); +        fprintf(stderr, "OutputUHD: USRP time %f\n", +                myUsrp->get_time_now().get_real_secs()); +    }      // preparing output thread worker data @@ -166,7 +170,7 @@ int OutputUHD::process(Buffer* dataIn, Buffer* dataOut)          uwd.frame0.buf = malloc(uwd.bufsize);          uwd.frame1.buf = malloc(uwd.bufsize); -        uwd.sourceContainsTimestamp = myEtiReader->sourceContainsTimestamp(); +        uwd.sourceContainsTimestamp = enable_sync && myEtiReader->sourceContainsTimestamp();          // The worker begins by transmitting buf0          memcpy(uwd.frame0.buf, dataIn->getData(), uwd.bufsize); diff --git a/src/OutputUHD.h b/src/OutputUHD.h index eea594f..953675d 100644 --- a/src/OutputUHD.h +++ b/src/OutputUHD.h @@ -135,7 +135,7 @@ class UHDWorker {  class OutputUHD: public ModOutput {      public:          OutputUHD(char* device, unsigned sampleRate, double frequency, int txgain, -                bool muteNoTimestamps); +                bool enableSync, bool muteNoTimestamps);          ~OutputUHD();          int process(Buffer* dataIn, Buffer* dataOut); @@ -159,6 +159,7 @@ class OutputUHD: public ModOutput {          struct UHDWorkerData uwd;          int activebuffer;          bool mute_no_timestamps; +        bool enable_sync;          size_t lastLen;  }; | 
