Make get_raw_samples() use provided mem instead of allocating
[pulseview.git] / pv / data / signalbase.cpp
index 09e4400e20a9d1584ca88dc6caa7d8974ddd3bb4..0f3c8f1be1d32b6beb316488c2067d77b70011f4 100644 (file)
@@ -181,10 +181,18 @@ void SignalBase::set_conversion_type(ConversionType t)
 
                // Discard converted data
                converted_data_.reset();
+               samples_cleared();
        }
 
        conversion_type_ = t;
 
+       // Re-create an empty container
+       // so that the signal is recognized as providing logic data
+       // and thus can be assigned to a decoder
+       if (conversion_is_a2l())
+               if (!converted_data_)
+                       converted_data_ = make_shared<Logic>(1);  // Contains only one channel
+
        start_conversion();
 
        conversion_type_changed(t);
@@ -229,6 +237,13 @@ uint8_t SignalBase::convert_a2l_schmitt_trigger(float lo_thr, float hi_thr,
        return state;
 }
 
+bool SignalBase::conversion_is_a2l() const
+{
+       return ((channel_type_ == AnalogChannel) &&
+               ((conversion_type_ == A2LConversionByTreshold) ||
+               (conversion_type_ == A2LConversionBySchmittTrigger)));
+}
+
 void SignalBase::conversion_thread_proc(QObject* segment)
 {
        // TODO Support for multiple segments is missing
@@ -237,19 +252,11 @@ void SignalBase::conversion_thread_proc(QObject* segment)
        start_sample = end_sample = 0;
 
        do {
-               if ((channel_type_ == AnalogChannel) &&
-                       ((conversion_type_ == A2LConversionByTreshold) ||
-                       (conversion_type_ == A2LConversionBySchmittTrigger))) {
+               if (conversion_is_a2l()) {
 
                        AnalogSegment *asegment = qobject_cast<AnalogSegment*>(segment);
 
-                       // Create the logic data container if needed
-                       shared_ptr<Logic> logic_data;
-                       if (!converted_data_) {
-                               logic_data = make_shared<Logic>(1);  // Contains only one channel
-                               converted_data_ = logic_data;
-                       } else
-                                logic_data = dynamic_pointer_cast<Logic>(converted_data_);
+                       const shared_ptr<Logic> logic_data = dynamic_pointer_cast<Logic>(converted_data_);
 
                        // Create the initial logic data segment if needed
                        if (logic_data->segments().size() == 0) {
@@ -267,6 +274,7 @@ void SignalBase::conversion_thread_proc(QObject* segment)
                                float min_v, max_v;
                                tie(min_v, max_v) = asegment->get_min_max();
 
+                               float* asamples = new float[ConversionBlockSize];
                                vector<uint8_t> lsamples;
                                lsamples.reserve(ConversionBlockSize);
 
@@ -277,23 +285,21 @@ void SignalBase::conversion_thread_proc(QObject* segment)
 
                                        // Convert as many sample blocks as we can
                                        while ((end_sample - i) > ConversionBlockSize) {
-                                               const float* asamples = asegment->get_samples(i, i + ConversionBlockSize);
+                                               asegment->get_samples(i, i + ConversionBlockSize, asamples);
                                                for (uint32_t j = 0; j < ConversionBlockSize; j++)
                                                        lsamples.push_back(convert_a2l_threshold(threshold, asamples[j]));
                                                lsegment->append_payload(lsamples.data(), lsamples.size());
                                                samples_added(lsegment, i, i + ConversionBlockSize);
                                                i += ConversionBlockSize;
                                                lsamples.clear();
-                                               delete[] asamples;
                                        }
 
                                        // Convert remaining samples
-                                       const float* asamples = asegment->get_samples(i, end_sample);
+                                       asegment->get_samples(i, end_sample, asamples);
                                        for (uint32_t j = 0; j < (end_sample - i); j++)
                                                lsamples.push_back(convert_a2l_threshold(threshold, asamples[j]));
                                        lsegment->append_payload(lsamples.data(), lsamples.size());
                                        samples_added(lsegment, i, end_sample);
-                                       delete[] asamples;
                                }
 
                                if (conversion_type_ == A2LConversionBySchmittTrigger) {
@@ -304,27 +310,27 @@ void SignalBase::conversion_thread_proc(QObject* segment)
 
                                        // Convert as many sample blocks as we can
                                        while ((end_sample - i) > ConversionBlockSize) {
-                                               const float* asamples = asegment->get_samples(i, i + ConversionBlockSize);
+                                               asegment->get_samples(i, i + ConversionBlockSize, asamples);
                                                for (uint32_t j = 0; j < ConversionBlockSize; j++)
                                                        lsamples.push_back(convert_a2l_schmitt_trigger(lo_thr, hi_thr, asamples[j], state));
                                                lsegment->append_payload(lsamples.data(), lsamples.size());
                                                samples_added(lsegment, i, i + ConversionBlockSize);
                                                i += ConversionBlockSize;
                                                lsamples.clear();
-                                               delete[] asamples;
                                        }
 
                                        // Convert remaining samples
-                                       const float* asamples = asegment->get_samples(i, end_sample);
+                                       asegment->get_samples(i, end_sample, asamples);
                                        for (uint32_t j = 0; j < (end_sample - i); j++)
                                                lsamples.push_back(convert_a2l_schmitt_trigger(lo_thr, hi_thr, asamples[j], state));
                                        lsegment->append_payload(lsamples.data(), lsamples.size());
                                        samples_added(lsegment, i, end_sample);
-                                       delete[] asamples;
                                }
 
                                // If acquisition is ongoing, start-/endsample may have changed
                                end_sample = asegment->get_sample_count();
+
+                               delete[] asamples;
                        }
                }
 
@@ -339,10 +345,7 @@ void SignalBase::start_conversion()
 {
        stop_conversion();
 
-       if ((channel_type_ == AnalogChannel) &&
-               ((conversion_type_ == A2LConversionByTreshold) ||
-               (conversion_type_ == A2LConversionBySchmittTrigger))) {
-
+       if (conversion_is_a2l()) {
                shared_ptr<Analog> analog_data = dynamic_pointer_cast<Analog>(data_);
 
                if (analog_data->analog_segments().size() > 0) {