]> sigrok.org Git - pulseview.git/commitdiff
DecodeSignal: Rework samplerate handling
authorSoeren Apel <redacted>
Wed, 17 May 2017 06:31:07 +0000 (08:31 +0200)
committerUwe Hermann <redacted>
Wed, 5 Jul 2017 22:37:08 +0000 (00:37 +0200)
Before, running an acquisition, then changing the
samplerate and then running the acquisition again
would result in the wrong (i.e. previous) samplerate
to be used for SRD. This patch fixes this.

pv/data/decodesignal.cpp
pv/data/decodesignal.hpp

index a7bcee59c78185c9cd0d0540ac299ed4143505d4..339c85dd01dd0305879bce1dc88d3fde6d8ec6e3 100644 (file)
@@ -221,13 +221,6 @@ void DecodeSignal::begin_decode()
                }
        }
 
-       // TODO Currently we assume all channels have the same sample rate
-       auto any_channel = find_if(channels_.begin(), channels_.end(),
-               [](data::DecodeChannel ch) { return ch.assigned_signal; });
-       shared_ptr<LogicSegment> first_segment =
-                       any_channel->assigned_signal->logic_data()->logic_segments().front();
-       samplerate_ = first_segment->samplerate();
-
        // Free the logic data and its segment(s) if it needs to be updated
        if (logic_mux_data_invalid_)
                logic_mux_data_.reset();
@@ -240,12 +233,6 @@ void DecodeSignal::begin_decode()
                logic_mux_data_->push_segment(segment_);
        }
 
-       // Update the samplerate and start time
-       start_time_ = segment_->start_time();
-       samplerate_ = segment_->samplerate();
-       if (samplerate_ == 0.0)
-               samplerate_ = 1.0;
-
        // Make sure the logic output data is complete and up-to-date
        logic_mux_interrupt_ = false;
        logic_mux_thread_ = std::thread(&DecodeSignal::logic_mux_proc, this);
@@ -626,6 +613,37 @@ void DecodeSignal::logic_mux_proc()
        decode_input_cond_.notify_one();
 }
 
+void DecodeSignal::query_input_metadata()
+{
+       // Update the samplerate and start time because we cannot start
+       // the libsrd session without the current samplerate
+
+       // TODO Currently we assume all channels have the same sample rate
+       // and start time
+       bool samplerate_valid = false;
+
+       auto any_channel = find_if(channels_.begin(), channels_.end(),
+               [](data::DecodeChannel ch) { return ch.assigned_signal; });
+
+       shared_ptr<Logic> logic_data =
+               any_channel->assigned_signal->logic_data();
+
+       do {
+               if (!logic_data->logic_segments().empty()) {
+                       shared_ptr<LogicSegment> first_segment =
+                               any_channel->assigned_signal->logic_data()->logic_segments().front();
+                       start_time_ = first_segment->start_time();
+                       samplerate_ = first_segment->samplerate();
+                       if (samplerate_ > 0)
+                               samplerate_valid = true;
+               }
+
+               // Wait until input data is available or an interrupt was requested
+               unique_lock<mutex> input_wait_lock(input_mutex_);
+               decode_input_cond_.wait(input_wait_lock);
+       } while (!samplerate_valid && !decode_interrupt_);
+}
+
 void DecodeSignal::decode_data(
        const int64_t abs_start_samplenum, const int64_t sample_count)
 {
@@ -647,6 +665,7 @@ void DecodeSignal::decode_data(
                        delete[] chunk;
                        break;
                }
+
                delete[] chunk;
 
                {
@@ -658,6 +677,11 @@ void DecodeSignal::decode_data(
 
 void DecodeSignal::decode_proc()
 {
+       query_input_metadata();
+
+       if (decode_interrupt_)
+               return;
+
        start_srd_session();
 
        uint64_t sample_count;
@@ -683,7 +707,7 @@ void DecodeSignal::decode_proc()
                        // Make sure all annotations are known to the frontend
                        new_annotations();
 
-                       // Wait for new input data or an interrupt request
+                       // Wait for new input data or an interrupt was requested
                        unique_lock<mutex> input_wait_lock(input_mutex_);
                        decode_input_cond_.wait(input_wait_lock);
                }
@@ -692,37 +716,38 @@ void DecodeSignal::decode_proc()
 
 void DecodeSignal::start_srd_session()
 {
-       if (!srd_session_) {
-               // Create the session
-               srd_session_new(&srd_session_);
-               assert(srd_session_);
+       if (srd_session_)
+               stop_srd_session();
 
-               // Create the decoders
-               srd_decoder_inst *prev_di = nullptr;
-               for (const shared_ptr<decode::Decoder> &dec : stack_) {
-                       srd_decoder_inst *const di = dec->create_decoder_inst(srd_session_);
+       // Create the session
+       srd_session_new(&srd_session_);
+       assert(srd_session_);
 
-                       if (!di) {
-                               error_message_ = tr("Failed to create decoder instance");
-                               srd_session_destroy(srd_session_);
-                               return;
-                       }
-
-                       if (prev_di)
-                               srd_inst_stack(srd_session_, prev_di, di);
+       // Create the decoders
+       srd_decoder_inst *prev_di = nullptr;
+       for (const shared_ptr<decode::Decoder> &dec : stack_) {
+               srd_decoder_inst *const di = dec->create_decoder_inst(srd_session_);
 
-                       prev_di = di;
+               if (!di) {
+                       error_message_ = tr("Failed to create decoder instance");
+                       srd_session_destroy(srd_session_);
+                       return;
                }
 
-               // Start the session
-               srd_session_metadata_set(srd_session_, SRD_CONF_SAMPLERATE,
-                       g_variant_new_uint64(samplerate_));
-
-               srd_pd_output_callback_add(srd_session_, SRD_OUTPUT_ANN,
-                       DecodeSignal::annotation_callback, this);
+               if (prev_di)
+                       srd_inst_stack(srd_session_, prev_di, di);
 
-               srd_session_start(srd_session_);
+               prev_di = di;
        }
+
+       // Start the session
+       srd_session_metadata_set(srd_session_, SRD_CONF_SAMPLERATE,
+               g_variant_new_uint64(samplerate_));
+
+       srd_pd_output_callback_add(srd_session_, SRD_OUTPUT_ANN,
+               DecodeSignal::annotation_callback, this);
+
+       srd_session_start(srd_session_);
 }
 
 void DecodeSignal::stop_srd_session()
index 2d4d4e0c768a8a959e6bf25e3a0e97a7ad8603c0..57887f1ec7609c5f66702db71481991f13c77644 100644 (file)
@@ -145,6 +145,8 @@ private:
 
        void logic_mux_proc();
 
+       void query_input_metadata();
+
        void decode_data(const int64_t abs_start_samplenum, const int64_t sample_count);
 
        void decode_proc();