From 458414c7b2ab93fa1a6d130fa64d907dd9fca5f0 Mon Sep 17 00:00:00 2001
From: ghostop14 <ghostop14@gmail.com>
Date: Sat, 15 Feb 2020 18:07:35 -0500
Subject: gr-blocks: Add scaling option to Complex to/from ishort and ichar

The existing block combinations of complex-to-ichar/ichar-to-complex
and complex-to-ishort/ishort-to-complex was not exposing a scale
factor to the UI (it was hard-coded at 1.0) which prevented the blocks
from being used with voltage-based inputs and outputs, for example
a -127 to 127 byte input would be mapped directly to the same value
as a float.  The same was true in reverse and there were notes in
the code about FIX clipping.  Adding the scale factor provides a
mechanism for the user to appropriately fix the clipping and scale
the conversion correctly.  Additional documentation was added to
the block yml to provide guidance to users on how to appropriately
select the scale factor for their use case, and the default value
was set to 1.0 for backward compatibility.
---
 gr-blocks/lib/interleaved_short_to_complex_impl.cc | 24 ++++++++++++++--------
 1 file changed, 15 insertions(+), 9 deletions(-)

(limited to 'gr-blocks/lib/interleaved_short_to_complex_impl.cc')

diff --git a/gr-blocks/lib/interleaved_short_to_complex_impl.cc b/gr-blocks/lib/interleaved_short_to_complex_impl.cc
index 654eb1573a..f32bf28fcb 100644
--- a/gr-blocks/lib/interleaved_short_to_complex_impl.cc
+++ b/gr-blocks/lib/interleaved_short_to_complex_impl.cc
@@ -12,28 +12,33 @@
 #include "config.h"
 #endif
 
-#include "interleaved_short_array_to_complex.h"
 #include "interleaved_short_to_complex_impl.h"
 #include <gnuradio/io_signature.h>
+#include <volk/volk.h>
 
 namespace gr {
 namespace blocks {
 
-interleaved_short_to_complex::sptr interleaved_short_to_complex::make(bool vector_input,
-                                                                      bool swap)
+interleaved_short_to_complex::sptr
+interleaved_short_to_complex::make(bool vector_input, bool swap, float scale_factor)
 {
     return gnuradio::get_initial_sptr(
-        new interleaved_short_to_complex_impl(vector_input, swap));
+        new interleaved_short_to_complex_impl(vector_input, swap, scale_factor));
 }
 
 interleaved_short_to_complex_impl::interleaved_short_to_complex_impl(bool vector_input,
-                                                                     bool swap)
+                                                                     bool swap,
+                                                                     float scale_factor)
     : sync_decimator("interleaved_short_to_complex",
                      gr::io_signature::make(1, 1, (vector_input ? 2 : 1) * sizeof(short)),
                      gr::io_signature::make(1, 1, sizeof(gr_complex)),
                      vector_input ? 1 : 2),
+      d_scalar(scale_factor),
+      d_vector(vector_input),
       d_swap(swap)
 {
+    const int alignment_multiple = volk_get_alignment() / sizeof(gr_complex);
+    set_alignment(std::max(1, alignment_multiple));
 }
 
 void interleaved_short_to_complex_impl::set_swap(bool swap) { d_swap = swap; }
@@ -43,16 +48,17 @@ int interleaved_short_to_complex_impl::work(int noutput_items,
                                             gr_vector_void_star& output_items)
 {
     const short* in = (const short*)input_items[0];
-    gr_complex* out = (gr_complex*)output_items[0];
+    float* out = (float*)output_items[0];
 
-    interleaved_short_array_to_complex(in, out, 2 * noutput_items);
+    // This calculates in[] * 1.0 / d_scalar
+    volk_16i_s32f_convert_32f(out, in, d_scalar, 2 * noutput_items);
 
     if (d_swap) {
         float* p = (float*)output_items[0];
         for (int i = 0; i < noutput_items; ++i) {
             float f = p[2 * i + 1];
-            p[2 * i + 1] = p[2 * i + 0];
-            p[2 * i + 0] = f;
+            p[2 * i + 1] = p[2 * i];
+            p[2 * i] = f;
         }
     }
 
-- 
cgit v1.2.3