mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-11-13 05:20:04 +00:00
Fixed sample count error & refactored
This commit is contained in:
parent
469eaf76e5
commit
00fd1821b1
@ -53,7 +53,7 @@ IONGSMSSignalSource::IONGSMSSignalSource(const ConfigurationInterface* configura
|
|||||||
unsigned int in_streams,
|
unsigned int in_streams,
|
||||||
unsigned int out_streams,
|
unsigned int out_streams,
|
||||||
Concurrent_Queue<pmt::pmt_t>* queue)
|
Concurrent_Queue<pmt::pmt_t>* queue)
|
||||||
: SignalSourceBase(configuration, role, "ION_Metadata_Standard_Signal_Source"s),
|
: SignalSourceBase(configuration, role, "ION_GSMS_Signal_Source"s),
|
||||||
metadata_file_(configuration->property(role + ".metadata_filename"s, "../data/example_capture_metadata.sdrx"s)),
|
metadata_file_(configuration->property(role + ".metadata_filename"s, "../data/example_capture_metadata.sdrx"s)),
|
||||||
stream_ids_(parse_comma_list(configuration->property(role + ".streams"s, ""s))),
|
stream_ids_(parse_comma_list(configuration->property(role + ".streams"s, ""s))),
|
||||||
metadata_(metadata_file_),
|
metadata_(metadata_file_),
|
||||||
|
@ -52,6 +52,8 @@ if(ENABLE_ION)
|
|||||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms_chunk_data.h)
|
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms_chunk_data.h)
|
||||||
set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ion_gsms_metadata_handler.cc)
|
set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ion_gsms_metadata_handler.cc)
|
||||||
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms_metadata_handler.h)
|
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms_metadata_handler.h)
|
||||||
|
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms_stream_encodings.h)
|
||||||
|
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms_chunk_unpacking_ctx.h)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ IONGSMSFileSource::IONGSMSFileSource(
|
|||||||
const GnssMetadata::Block& block,
|
const GnssMetadata::Block& block,
|
||||||
const std::vector<std::string>& stream_ids)
|
const std::vector<std::string>& stream_ids)
|
||||||
: gr::sync_block(
|
: gr::sync_block(
|
||||||
"ion_metadata_standard_source",
|
"ion_gsms_file_source",
|
||||||
gr::io_signature::make(0, 0, 0),
|
gr::io_signature::make(0, 0, 0),
|
||||||
make_output_signature(block, stream_ids)),
|
make_output_signature(block, stream_ids)),
|
||||||
file_metadata_(file),
|
file_metadata_(file),
|
||||||
@ -107,7 +107,12 @@ gr::io_signature::sptr IONGSMSFileSource::make_output_signature(const GnssMetada
|
|||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
++nstreams;
|
++nstreams;
|
||||||
const std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor();
|
std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor();
|
||||||
|
if (stream.Packedbits() >= 2 * stream.RateFactor() * stream.Quantization())
|
||||||
|
{
|
||||||
|
// Samples have 'Complex' format
|
||||||
|
sample_bitsize /= 2;
|
||||||
|
}
|
||||||
item_sizes.push_back(bits_to_item_size(sample_bitsize));
|
item_sizes.push_back(bits_to_item_size(sample_bitsize));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,12 @@ IONGSMSChunkData::IONGSMSChunkData(const GnssMetadata::Chunk& chunk, const std::
|
|||||||
{
|
{
|
||||||
streams_.emplace_back(lump, stream, GnssMetadata::encoding_from_string(stream.Encoding()),output_streams + output_stream_offset);
|
streams_.emplace_back(lump, stream, GnssMetadata::encoding_from_string(stream.Encoding()),output_streams + output_stream_offset);
|
||||||
++output_streams;
|
++output_streams;
|
||||||
const std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor();
|
std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor();
|
||||||
|
if (stream.Packedbits() >= 2 * stream.RateFactor() * stream.Quantization())
|
||||||
|
{
|
||||||
|
// Samples have 'Complex' format
|
||||||
|
sample_bitsize /= 2;
|
||||||
|
}
|
||||||
output_stream_item_size_.push_back(bits_to_item_size(sample_bitsize));
|
output_stream_item_size_.push_back(bits_to_item_size(sample_bitsize));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -95,6 +100,137 @@ std::size_t IONGSMSChunkData::output_stream_item_size(std::size_t stream_index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename WT>
|
||||||
|
void IONGSMSChunkData::unpack_words(gr_vector_void_star& outputs, const std::function<void(int output, int nitems)>& produce)
|
||||||
|
{
|
||||||
|
WT* data = static_cast<WT*>(buffer_);
|
||||||
|
// TODO - Swap endiannes if needed
|
||||||
|
|
||||||
|
IONGSMSChunkUnpackingCtx<WT> ctx{
|
||||||
|
chunk_.Shift(),
|
||||||
|
data,
|
||||||
|
countwords_,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Head padding
|
||||||
|
if (padding_bitsize_ > 0 && chunk_.Padding() == GnssMetadata::Chunk::Head)
|
||||||
|
{
|
||||||
|
ctx.shift_padding(padding_bitsize_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Samples
|
||||||
|
for (const auto& [lump, stream, encoding, output_index] : streams_)
|
||||||
|
{
|
||||||
|
if (output_index == -1)
|
||||||
|
{
|
||||||
|
// skip stream
|
||||||
|
ctx.shift_padding(stream.Packedbits());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
produce(output_index, write_stream_samples(ctx, lump, stream, encoding, outputs[output_index]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename WT>
|
||||||
|
std::size_t IONGSMSChunkData::write_stream_samples(
|
||||||
|
IONGSMSChunkUnpackingCtx<WT>& ctx,
|
||||||
|
const GnssMetadata::Lump& lump,
|
||||||
|
const GnssMetadata::IonStream& stream,
|
||||||
|
const GnssMetadata::StreamEncoding stream_encoding,
|
||||||
|
void*& out)
|
||||||
|
{
|
||||||
|
std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor();
|
||||||
|
std::size_t sample_count = stream.RateFactor();
|
||||||
|
|
||||||
|
if (stream.Packedbits() >= 2 * stream.RateFactor() * stream.Quantization())
|
||||||
|
{
|
||||||
|
// Samples have 'Complex' format
|
||||||
|
sample_bitsize /= 2;
|
||||||
|
sample_count *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sample_bitsize <= 8)
|
||||||
|
{
|
||||||
|
write_n_samples<WT, int8_t>(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, out);
|
||||||
|
}
|
||||||
|
else if (sample_bitsize <= 16)
|
||||||
|
{
|
||||||
|
write_n_samples<WT, int16_t>(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, out);
|
||||||
|
}
|
||||||
|
else if (sample_bitsize <= 32)
|
||||||
|
{
|
||||||
|
write_n_samples<WT, int32_t>(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, out);
|
||||||
|
}
|
||||||
|
else if (sample_bitsize <= 64)
|
||||||
|
{
|
||||||
|
write_n_samples<WT, int64_t>(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sample_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename WT, typename OT>
|
||||||
|
void IONGSMSChunkData::write_n_samples(
|
||||||
|
IONGSMSChunkUnpackingCtx<WT>& ctx,
|
||||||
|
GnssMetadata::Lump::LumpShift lump_shift,
|
||||||
|
uint8_t sample_bitsize,
|
||||||
|
std::size_t sample_count,
|
||||||
|
GnssMetadata::StreamEncoding stream_encoding,
|
||||||
|
void*& out)
|
||||||
|
{
|
||||||
|
if (lump_shift == GnssMetadata::Lump::shiftRight)
|
||||||
|
{
|
||||||
|
auto* sample = static_cast<OT*>(out);
|
||||||
|
sample += sample_count;
|
||||||
|
for (std::size_t i = 0; i < sample_count; ++i)
|
||||||
|
{
|
||||||
|
ctx.shift_sample(sample_bitsize, sample);
|
||||||
|
dump_sample(*sample);
|
||||||
|
decode_sample(sample_bitsize, sample, stream_encoding);
|
||||||
|
--sample;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // if (lump_shift == GnssMetadata::Lump::shiftLeft || lump_shift == GnssMetadata::Lump::shiftUndefined)
|
||||||
|
{
|
||||||
|
auto* sample = static_cast<OT*>(out);
|
||||||
|
for (std::size_t i = 0; i < sample_count; ++i)
|
||||||
|
{
|
||||||
|
ctx.shift_sample(sample_bitsize, sample);
|
||||||
|
dump_sample(*sample);
|
||||||
|
decode_sample(sample_bitsize, sample, stream_encoding);
|
||||||
|
++sample;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Static utilities
|
||||||
|
void IONGSMSChunkData::decode_sample(const uint8_t sample_bitsize, auto* sample, const GnssMetadata::StreamEncoding encoding)
|
||||||
|
{
|
||||||
|
using SampleType = std::remove_pointer_t<decltype(sample)>;
|
||||||
|
switch (sample_bitsize)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
*sample = GnssMetadata::two_bit_look_up<SampleType>[encoding][*sample];
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
*sample = GnssMetadata::three_bit_look_up<SampleType>[encoding][*sample];
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
*sample = GnssMetadata::four_bit_look_up<SampleType>[encoding][*sample];
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
*sample = GnssMetadata::five_bit_look_up<SampleType>[encoding][*sample];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// TODO - Is this an error that can happen?
|
||||||
|
// for now we'll just do nothing, if the sample is this wide it may need no decoding
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void IONGSMSChunkData::dump_sample(auto value)
|
void IONGSMSChunkData::dump_sample(auto value)
|
||||||
{
|
{
|
||||||
@ -102,7 +238,7 @@ void IONGSMSChunkData::dump_sample(auto value)
|
|||||||
if (count > 0)
|
if (count > 0)
|
||||||
{
|
{
|
||||||
--count;
|
--count;
|
||||||
std::cout << "SAMPLE: " << std::bitset<32>(value) << std::endl;
|
// std::cout << "SAMPLE: [0x" << std::hex << value << "] " << std::bitset<32>(value) << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
#define ION_GSM_CHUNK_DATA_H
|
#define ION_GSM_CHUNK_DATA_H
|
||||||
|
|
||||||
#include "GnssMetadata.h"
|
#include "GnssMetadata.h"
|
||||||
|
#include "ion_gsms_stream_encodings.h"
|
||||||
|
#include "ion_gsms_chunk_unpacking_ctx.h"
|
||||||
#include <gnuradio/block.h>
|
#include <gnuradio/block.h>
|
||||||
|
|
||||||
#if USE_GLOG_AND_GFLAGS
|
#if USE_GLOG_AND_GFLAGS
|
||||||
@ -72,144 +74,6 @@ void with_word_type(const uint8_t word_size, auto&& callback)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace GnssMetadata
|
|
||||||
{
|
|
||||||
using StreamEncoding = unsigned char;
|
|
||||||
|
|
||||||
namespace StreamEncodings
|
|
||||||
{
|
|
||||||
constexpr unsigned char SIGN = 0;
|
|
||||||
constexpr unsigned char OB = 1;
|
|
||||||
constexpr unsigned char SM = 2;
|
|
||||||
constexpr unsigned char MS = 3;
|
|
||||||
constexpr unsigned char TC = 4;
|
|
||||||
constexpr unsigned char OG = 5;
|
|
||||||
constexpr unsigned char OBA = 6;
|
|
||||||
constexpr unsigned char SMA = 7;
|
|
||||||
constexpr unsigned char MSA = 8;
|
|
||||||
constexpr unsigned char TCA = 9;
|
|
||||||
constexpr unsigned char OGA = 10;
|
|
||||||
constexpr unsigned char FP = 11;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline StreamEncoding encoding_from_string(const std::string& str)
|
|
||||||
{
|
|
||||||
if (str == "SIGN")
|
|
||||||
{
|
|
||||||
return StreamEncodings::SIGN;
|
|
||||||
}
|
|
||||||
if (str == "OB")
|
|
||||||
{
|
|
||||||
return StreamEncodings::OB;
|
|
||||||
}
|
|
||||||
if (str == "SM")
|
|
||||||
{
|
|
||||||
return StreamEncodings::SM;
|
|
||||||
}
|
|
||||||
if (str == "MS")
|
|
||||||
{
|
|
||||||
return StreamEncodings::MS;
|
|
||||||
}
|
|
||||||
if (str == "TC")
|
|
||||||
{
|
|
||||||
return StreamEncodings::TC;
|
|
||||||
}
|
|
||||||
if (str == "OG")
|
|
||||||
{
|
|
||||||
return StreamEncodings::OG;
|
|
||||||
}
|
|
||||||
if (str == "OBA")
|
|
||||||
{
|
|
||||||
return StreamEncodings::OBA;
|
|
||||||
}
|
|
||||||
if (str == "SMA")
|
|
||||||
{
|
|
||||||
return StreamEncodings::SMA;
|
|
||||||
}
|
|
||||||
if (str == "MSA")
|
|
||||||
{
|
|
||||||
return StreamEncodings::MSA;
|
|
||||||
}
|
|
||||||
if (str == "TCA")
|
|
||||||
{
|
|
||||||
return StreamEncodings::TCA;
|
|
||||||
}
|
|
||||||
if (str == "OGA")
|
|
||||||
{
|
|
||||||
return StreamEncodings::OGA;
|
|
||||||
}
|
|
||||||
if (str == "FP")
|
|
||||||
{
|
|
||||||
return StreamEncodings::FP;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline T two_bit_look_up[11][4]
|
|
||||||
{
|
|
||||||
[0] = {},
|
|
||||||
[1 /*OB*/] = {-2, -1, 0, 1},
|
|
||||||
[2 /*SM*/] = {0, 1, 0, -1},
|
|
||||||
[3 /*MS*/] = {0, 0, 1, -1},
|
|
||||||
[4 /*TC*/] = {0, 1, -2, -1},
|
|
||||||
[5 /*OG*/] = {-2, -1, 1, 0},
|
|
||||||
[6 /*OBA*/] = {-3, -1, 1, 3},
|
|
||||||
[7 /*SMA*/] = {1, 3, -1, -3},
|
|
||||||
[8 /*MSA*/] = {1, -1, 3, -3},
|
|
||||||
[9 /*TCA*/] = {1, 3, -3, -1},
|
|
||||||
[10 /*OGA*/] = {-3, -1, 3, 1},
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline T three_bit_look_up[11][8]
|
|
||||||
{
|
|
||||||
[0] = {},
|
|
||||||
[1 /*OB*/] = {-4, -3, -2, -1, 0, 1, 2, 3},
|
|
||||||
[2 /*SM*/] = {0, 1, 2, 3, 0, -1, -2, -3},
|
|
||||||
[3 /*MS*/] = {0, 0, 1, -1, 0, 0, 1, -1},
|
|
||||||
[4 /*TC*/] = {0, 1, 2, 3, -4, -3, -2, -1},
|
|
||||||
[5 /*OG*/] = {-4, -3, -1, -2, 3, 2, 0, 1},
|
|
||||||
[6 /*OBA*/] = {-7, -5, -3, -1, 1, 3, 5, 7},
|
|
||||||
[7 /*SMA*/] = {1, 3, 5, 7, -1, -3, -5, -7},
|
|
||||||
[8 /*MSA*/] = {1, -1, 3, -3, 5, -5, 7, -7},
|
|
||||||
[9 /*TCA*/] = {1, 3, 5, 7, -7, -5, -3, -1},
|
|
||||||
[10 /*OGA*/] = {-7, -5, -1, -3, 7, 5, 1, 3},
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline T four_bit_look_up[11][16]
|
|
||||||
{
|
|
||||||
[0] = {},
|
|
||||||
[1 /*OB*/] = {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7},
|
|
||||||
[2 /*SM*/] = {0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7},
|
|
||||||
[3 /*MS*/] = {0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1},
|
|
||||||
[4 /*TC*/] = {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1},
|
|
||||||
[5 /*OG*/] = {-8, -7, -5, -6, -1, -2, -4, -3, 7, 6, 4, 5, 0, 1, 3, 2},
|
|
||||||
[6 /*OBA*/] = {-15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15},
|
|
||||||
[7 /*SMA*/] = {1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15},
|
|
||||||
[8 /*MSA*/] = {1, -1, 3, -3, 5, -5, 7, -7, 9, -9, 11, -11, 13, -13, 15, -15},
|
|
||||||
[9 /*TCA*/] = {1, 3, 5, 7, 9, 11, 13, 15, -15, -13, -11, -9, -7, -5, -3, -1},
|
|
||||||
[10 /*OGA*/] = {-15, -13, -9, -11, -1, -3, -7, -5, 15, 13, 9, 11, 1, 3, 7, 5},
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline T five_bit_look_up[11][32]
|
|
||||||
{
|
|
||||||
[0] = {},
|
|
||||||
[1 /*OB*/] = {-16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
|
||||||
[2 /*SM*/] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15},
|
|
||||||
[3 /*MS*/] = {0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1},
|
|
||||||
[4 /*TC*/] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1},
|
|
||||||
[5 /*OG*/] = {-16, -15, -13, -14, -9, -10, -12, -11, -1, -2, -4, -3, -8, -7, -5, -6, 15, 14, 12, 13, 8, 9, 11, 10, 0, 1, 3, 2, 7, 6, 4, 5},
|
|
||||||
[6 /*OBA*/] = {-31, -29, -27, -25, -23, -21, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31},
|
|
||||||
[7 /*SMA*/] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, -1, -3, -5, -7, -9, -11, -13, -15, -17, -19, -21, -23, -25, -27, -29, -31},
|
|
||||||
[8 /*MSA*/] = {1, -1, 3, -3, 5, -5, 7, -7, 9, -9, 11, -11, 13, -13, 15, -15, 17, -17, 19, -19, 21, -21, 23, -23, 25, -25, 27, -27, 29, -29, 31, -31},
|
|
||||||
[9 /*TCA*/] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, -31, -29, -27, -25, -23, -21, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1},
|
|
||||||
[10 /*OGA*/] = {-31, -29, -25, -27, -17, -19, -23, -21, -1, -3, -7, -5, -15, -13, -9, -11, 31, 29, 25, 27, 17, 19, 23, 21, 1, 3, 7, 5, 15, 13, 9, 11},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
class IONGSMSChunkData
|
class IONGSMSChunkData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -232,258 +96,26 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename WT>
|
template <typename WT>
|
||||||
struct unpacking_context_t
|
void unpack_words(gr_vector_void_star& outputs, const std::function<void(int output, int nitems)>& produce);
|
||||||
{
|
|
||||||
WT* iterator_;
|
|
||||||
WT current_word_;
|
|
||||||
uint8_t bitshift_ = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename WT>
|
|
||||||
void unpack_words(gr_vector_void_star& outputs, const std::function<void(int output, int nitems)>& produce)
|
|
||||||
{
|
|
||||||
WT* data = static_cast<WT*>(buffer_);
|
|
||||||
// TODO - Swap endiannes if needed
|
|
||||||
|
|
||||||
unpacking_context_t<WT> ctx{};
|
|
||||||
if (chunk_.Shift() == GnssMetadata::Chunk::Left)
|
|
||||||
{
|
|
||||||
ctx.iterator_ = data;
|
|
||||||
}
|
|
||||||
else if (chunk_.Shift() == GnssMetadata::Chunk::Right)
|
|
||||||
{
|
|
||||||
ctx.iterator_ = &data[countwords_];
|
|
||||||
}
|
|
||||||
advance_word(ctx); // Initializes ctx.current_word_
|
|
||||||
|
|
||||||
// Head padding
|
|
||||||
if (padding_bitsize_ > 0 && chunk_.Padding() == GnssMetadata::Chunk::Head)
|
|
||||||
{
|
|
||||||
shift_padding(ctx, padding_bitsize_);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Samples
|
|
||||||
for (const auto& [lump, stream, encoding, output_index] : streams_)
|
|
||||||
{
|
|
||||||
if (output_index == -1)
|
|
||||||
{
|
|
||||||
skip_stream(ctx, lump, stream);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
produce(output_index, write_stream_samples(ctx, lump, stream, encoding, outputs[output_index]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename WT>
|
|
||||||
void skip_stream(
|
|
||||||
unpacking_context_t<WT>& ctx,
|
|
||||||
const GnssMetadata::Lump& lump,
|
|
||||||
const GnssMetadata::IonStream& stream)
|
|
||||||
{
|
|
||||||
shift_padding(ctx, stream.Packedbits());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename WT>
|
template <typename WT>
|
||||||
std::size_t write_stream_samples(
|
std::size_t write_stream_samples(
|
||||||
unpacking_context_t<WT>& ctx,
|
IONGSMSChunkUnpackingCtx<WT>& ctx,
|
||||||
const GnssMetadata::Lump& lump,
|
const GnssMetadata::Lump& lump,
|
||||||
const GnssMetadata::IonStream& stream,
|
const GnssMetadata::IonStream& stream,
|
||||||
const GnssMetadata::StreamEncoding stream_encoding,
|
GnssMetadata::StreamEncoding stream_encoding,
|
||||||
void*& out)
|
void*& out);
|
||||||
{
|
|
||||||
std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor();
|
|
||||||
std::size_t sample_count = stream.RateFactor();
|
|
||||||
|
|
||||||
if (stream.Packedbits() >= 2 * stream.RateFactor() * stream.Quantization())
|
|
||||||
{
|
|
||||||
// Samples have 'Complex' format
|
|
||||||
sample_bitsize /= 2;
|
|
||||||
sample_count *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sample_bitsize <= 8)
|
|
||||||
{
|
|
||||||
write_n_samples<WT, int8_t>(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, out);
|
|
||||||
}
|
|
||||||
else if (sample_bitsize <= 16)
|
|
||||||
{
|
|
||||||
write_n_samples<WT, int16_t>(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, out);
|
|
||||||
}
|
|
||||||
else if (sample_bitsize <= 32)
|
|
||||||
{
|
|
||||||
write_n_samples<WT, int32_t>(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, out);
|
|
||||||
}
|
|
||||||
else if (sample_bitsize <= 64)
|
|
||||||
{
|
|
||||||
write_n_samples<WT, int64_t>(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sample_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename WT, typename OT>
|
template <typename WT, typename OT>
|
||||||
void write_n_samples(
|
void write_n_samples(
|
||||||
unpacking_context_t<WT>& ctx,
|
IONGSMSChunkUnpackingCtx<WT>& ctx,
|
||||||
GnssMetadata::Lump::LumpShift lump_shift,
|
GnssMetadata::Lump::LumpShift lump_shift,
|
||||||
uint8_t sample_bitsize,
|
uint8_t sample_bitsize,
|
||||||
std::size_t sample_count,
|
std::size_t sample_count,
|
||||||
GnssMetadata::StreamEncoding stream_encoding,
|
GnssMetadata::StreamEncoding stream_encoding,
|
||||||
void*& out)
|
void*& out);
|
||||||
{
|
|
||||||
if (lump_shift == GnssMetadata::Lump::shiftRight)
|
|
||||||
{
|
|
||||||
auto* sample = static_cast<OT*>(out);
|
|
||||||
sample += sample_count;
|
|
||||||
for (std::size_t i = 0; i < sample_count; ++i)
|
|
||||||
{
|
|
||||||
shift_sample(ctx, sample_bitsize, sample);
|
|
||||||
decode_sample(sample_bitsize, sample, stream_encoding);
|
|
||||||
--sample;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // if (lump_shift == GnssMetadata::Lump::shiftLeft || lump_shift == GnssMetadata::Lump::shiftUndefined)
|
|
||||||
{
|
|
||||||
auto* sample = static_cast<OT*>(out);
|
|
||||||
for (std::size_t i = 0; i < sample_count; ++i)
|
|
||||||
{
|
|
||||||
shift_sample(ctx, sample_bitsize, sample);
|
|
||||||
decode_sample(sample_bitsize, sample, stream_encoding);
|
|
||||||
++sample;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename WT, typename OT>
|
static void decode_sample(uint8_t sample_bitsize, auto* sample, GnssMetadata::StreamEncoding encoding);
|
||||||
void shift_sample(unpacking_context_t<WT>& ctx, uint8_t sample_bitsize, OT* output, uint8_t output_bit_offset = 0)
|
|
||||||
{
|
|
||||||
const uint8_t word_bitsize = sizeword_ * 8;
|
|
||||||
|
|
||||||
if ((sample_bitsize + (ctx.bitshift_ % word_bitsize)) > word_bitsize)
|
|
||||||
{
|
|
||||||
uint8_t bits_shifted = word_bitsize - (ctx.bitshift_ % word_bitsize);
|
|
||||||
|
|
||||||
if (chunk_.Shift() == GnssMetadata::Chunk::Left)
|
|
||||||
{
|
|
||||||
WT mask = ~((1 << (word_bitsize - bits_shifted)) - 1);
|
|
||||||
dump_sample(ctx.current_word_ & mask);
|
|
||||||
*output |= ((ctx.current_word_ & mask) >> output_bit_offset);
|
|
||||||
ctx.current_word_ <<= bits_shifted;
|
|
||||||
}
|
|
||||||
else if (chunk_.Shift() == GnssMetadata::Chunk::Right)
|
|
||||||
{
|
|
||||||
WT mask = ((1 << (bits_shifted)) - 1);
|
|
||||||
dump_sample(ctx.current_word_ & mask);
|
|
||||||
*output |= (ctx.current_word_ & mask) << output_bit_offset;
|
|
||||||
// TODO - reverse bit order of sample? maybe?
|
|
||||||
ctx.current_word_ >>= bits_shifted;
|
|
||||||
}
|
|
||||||
|
|
||||||
advance_word(ctx);
|
|
||||||
ctx.bitshift_ += bits_shifted;
|
|
||||||
shift_sample(ctx, sample_bitsize - bits_shifted, output, bits_shifted);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (chunk_.Shift() == GnssMetadata::Chunk::Left)
|
|
||||||
{
|
|
||||||
WT mask = ~((1 << (word_bitsize - sample_bitsize)) - 1);
|
|
||||||
OT sample = (ctx.current_word_ & mask) >> (word_bitsize - sample_bitsize);
|
|
||||||
dump_sample(sample);
|
|
||||||
*output |= (sample) >> output_bit_offset;
|
|
||||||
ctx.current_word_ <<= sample_bitsize;
|
|
||||||
}
|
|
||||||
else if (chunk_.Shift() == GnssMetadata::Chunk::Right)
|
|
||||||
{
|
|
||||||
WT mask = ((1 << (sample_bitsize)) - 1);
|
|
||||||
dump_sample(ctx.current_word_ & mask);
|
|
||||||
*output |= (ctx.current_word_ & mask) << output_bit_offset;
|
|
||||||
// TODO - reverse bit order of sample? maybe?
|
|
||||||
ctx.current_word_ >>= sample_bitsize;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.bitshift_ += sample_bitsize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename WT>
|
|
||||||
void shift_padding(unpacking_context_t<WT>& ctx, uint8_t n_bits)
|
|
||||||
{
|
|
||||||
if(n_bits == 0) return;
|
|
||||||
|
|
||||||
const uint8_t word_bitsize = sizeword_ * 8;
|
|
||||||
|
|
||||||
if ((n_bits + (ctx.bitshift_ % word_bitsize)) >= word_bitsize)
|
|
||||||
{
|
|
||||||
uint8_t bits_shifted = word_bitsize - (ctx.bitshift_ % word_bitsize);
|
|
||||||
|
|
||||||
if (chunk_.Shift() == GnssMetadata::Chunk::Left)
|
|
||||||
{
|
|
||||||
ctx.current_word_ <<= bits_shifted;
|
|
||||||
}
|
|
||||||
else if (chunk_.Shift() == GnssMetadata::Chunk::Right)
|
|
||||||
{
|
|
||||||
ctx.current_word_ >>= bits_shifted;
|
|
||||||
}
|
|
||||||
|
|
||||||
advance_word(ctx);
|
|
||||||
ctx.bitshift_ += bits_shifted;
|
|
||||||
shift_padding(ctx, n_bits - bits_shifted);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (chunk_.Shift() == GnssMetadata::Chunk::Left)
|
|
||||||
{
|
|
||||||
ctx.current_word_ <<= n_bits;
|
|
||||||
}
|
|
||||||
else if (chunk_.Shift() == GnssMetadata::Chunk::Right)
|
|
||||||
{
|
|
||||||
ctx.current_word_ >>= n_bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.bitshift_ += n_bits;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename WT>
|
|
||||||
void advance_word(unpacking_context_t<WT>& ctx)
|
|
||||||
{
|
|
||||||
WT word = *ctx.iterator_;
|
|
||||||
if (chunk_.Shift() == GnssMetadata::Chunk::Left)
|
|
||||||
{
|
|
||||||
++ctx.iterator_;
|
|
||||||
}
|
|
||||||
else if (chunk_.Shift() == GnssMetadata::Chunk::Right)
|
|
||||||
{
|
|
||||||
--ctx.iterator_;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.current_word_ = word;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ST>
|
|
||||||
static void decode_sample(const uint8_t sample_bitsize, ST* sample, const GnssMetadata::StreamEncoding encoding)
|
|
||||||
{
|
|
||||||
switch (sample_bitsize)
|
|
||||||
{
|
|
||||||
case 2:
|
|
||||||
*sample = GnssMetadata::two_bit_look_up<ST>[encoding][*sample];
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
*sample = GnssMetadata::three_bit_look_up<ST>[encoding][*sample];
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
*sample = GnssMetadata::four_bit_look_up<ST>[encoding][*sample];
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
*sample = GnssMetadata::five_bit_look_up<ST>[encoding][*sample];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// TODO - Is this an error that can happen?
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dump_sample(auto value);
|
static void dump_sample(auto value);
|
||||||
|
|
||||||
|
153
src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h
Normal file
153
src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
/*!
|
||||||
|
* \file ion_gsms_chunk_unpacking_ctx.h
|
||||||
|
* \brief Holds state and provides utilities for unpacking samples from a chunk
|
||||||
|
* \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com
|
||||||
|
*
|
||||||
|
* This is a template class, and thus, its member functions must be defined in the header file.
|
||||||
|
*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||||
|
* This file is part of GNSS-SDR.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ION_GSM_CHUNK_UNPACKING_CTX_H
|
||||||
|
#define ION_GSM_CHUNK_UNPACKING_CTX_H
|
||||||
|
|
||||||
|
#include "GnssMetadata.h"
|
||||||
|
#include <gnuradio/block.h>
|
||||||
|
|
||||||
|
#if USE_GLOG_AND_GFLAGS
|
||||||
|
#include <glog/logging.h>
|
||||||
|
#else
|
||||||
|
#include <absl/log/log.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <typename WT>
|
||||||
|
struct IONGSMSChunkUnpackingCtx
|
||||||
|
{
|
||||||
|
static constexpr uint8_t word_bitsize_ = sizeof(WT) * 8;
|
||||||
|
|
||||||
|
const GnssMetadata::Chunk::WordShift word_shift_direction_;
|
||||||
|
WT* iterator_; // Not owned by this class, must not destroy
|
||||||
|
WT current_word_;
|
||||||
|
uint8_t bitshift_ = 0;
|
||||||
|
|
||||||
|
IONGSMSChunkUnpackingCtx(
|
||||||
|
const GnssMetadata::Chunk::WordShift word_shift,
|
||||||
|
WT* data_buffer,
|
||||||
|
uint8_t data_buffer_word_count) : word_shift_direction_(word_shift)
|
||||||
|
{
|
||||||
|
if (word_shift_direction_ == GnssMetadata::Chunk::Left)
|
||||||
|
{
|
||||||
|
iterator_ = data_buffer;
|
||||||
|
}
|
||||||
|
else if (word_shift_direction_ == GnssMetadata::Chunk::Right)
|
||||||
|
{
|
||||||
|
iterator_ = &data_buffer[data_buffer_word_count];
|
||||||
|
}
|
||||||
|
advance_word(); // Initializes current_word_
|
||||||
|
}
|
||||||
|
|
||||||
|
void advance_word()
|
||||||
|
{
|
||||||
|
WT word = *iterator_;
|
||||||
|
if (word_shift_direction_ == GnssMetadata::Chunk::Left)
|
||||||
|
{
|
||||||
|
++iterator_;
|
||||||
|
}
|
||||||
|
else if (word_shift_direction_ == GnssMetadata::Chunk::Right)
|
||||||
|
{
|
||||||
|
--iterator_;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_word_ = word;
|
||||||
|
}
|
||||||
|
|
||||||
|
void shift_current_word(uint8_t n)
|
||||||
|
{
|
||||||
|
if (word_shift_direction_ == GnssMetadata::Chunk::Left)
|
||||||
|
{
|
||||||
|
current_word_ <<= n;
|
||||||
|
}
|
||||||
|
else if (word_shift_direction_ == GnssMetadata::Chunk::Right)
|
||||||
|
{
|
||||||
|
current_word_ >>= n;
|
||||||
|
}
|
||||||
|
|
||||||
|
bitshift_ += n;
|
||||||
|
if (bitshift_ >= word_bitsize_)
|
||||||
|
{
|
||||||
|
advance_word();
|
||||||
|
bitshift_ -= word_bitsize_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void shift_padding(uint8_t n_bits)
|
||||||
|
{
|
||||||
|
if (n_bits == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((n_bits + (bitshift_ % word_bitsize_)) >= word_bitsize_)
|
||||||
|
{
|
||||||
|
const uint8_t bits_shifted = word_bitsize_ - (bitshift_ % word_bitsize_);
|
||||||
|
|
||||||
|
shift_current_word(bits_shifted);
|
||||||
|
shift_padding(n_bits - bits_shifted);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shift_current_word(n_bits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename OT>
|
||||||
|
void shift_sample(const uint8_t sample_bitsize, OT* output, uint8_t output_bit_offset = 0)
|
||||||
|
{
|
||||||
|
if ((sample_bitsize + (bitshift_ % word_bitsize_)) > word_bitsize_)
|
||||||
|
{
|
||||||
|
const uint8_t bits_shifted = word_bitsize_ - (bitshift_ % word_bitsize_);
|
||||||
|
|
||||||
|
if (word_shift_direction_ == GnssMetadata::Chunk::Left)
|
||||||
|
{
|
||||||
|
WT mask = ~((1 << (word_bitsize_ - bits_shifted)) - 1);
|
||||||
|
*output |= ((current_word_ & mask) >> output_bit_offset);
|
||||||
|
}
|
||||||
|
else if (word_shift_direction_ == GnssMetadata::Chunk::Right)
|
||||||
|
{
|
||||||
|
WT mask = ((1 << (bits_shifted)) - 1);
|
||||||
|
*output |= (current_word_ & mask) << output_bit_offset;
|
||||||
|
// TODO - reverse bit order of sample? maybe?
|
||||||
|
}
|
||||||
|
|
||||||
|
shift_current_word(bits_shifted);
|
||||||
|
shift_sample(sample_bitsize - bits_shifted, output, bits_shifted);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (word_shift_direction_ == GnssMetadata::Chunk::Left)
|
||||||
|
{
|
||||||
|
WT mask = ~((1 << (word_bitsize_ - sample_bitsize)) - 1);
|
||||||
|
OT sample = (current_word_ & mask) >> (word_bitsize_ - sample_bitsize);
|
||||||
|
*output |= (sample) >> output_bit_offset;
|
||||||
|
}
|
||||||
|
else if (word_shift_direction_ == GnssMetadata::Chunk::Right)
|
||||||
|
{
|
||||||
|
WT mask = ((1 << (sample_bitsize)) - 1);
|
||||||
|
*output |= (current_word_ & mask) << output_bit_offset;
|
||||||
|
// TODO - reverse bit order of sample? maybe?
|
||||||
|
}
|
||||||
|
|
||||||
|
shift_current_word(sample_bitsize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //ION_GSM_CHUNK_UNPACKING_CTX_H
|
164
src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h
Normal file
164
src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
/*!
|
||||||
|
* \file ion_gsms_stream_encodings.h
|
||||||
|
* \brief Implements look up tables for all encodings in the standard
|
||||||
|
* \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com
|
||||||
|
*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
|
||||||
|
* This file is part of GNSS-SDR.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010-2020 (see AUTHORS file for a list of contributors)
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ION_GSM_STREAM_ENCODINGS_H
|
||||||
|
#define ION_GSM_STREAM_ENCODINGS_H
|
||||||
|
|
||||||
|
#if USE_GLOG_AND_GFLAGS
|
||||||
|
#include <glog/logging.h>
|
||||||
|
#else
|
||||||
|
#include <absl/log/log.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace GnssMetadata
|
||||||
|
{
|
||||||
|
using StreamEncoding = unsigned char;
|
||||||
|
|
||||||
|
namespace StreamEncodings
|
||||||
|
{
|
||||||
|
constexpr unsigned char SIGN = 0;
|
||||||
|
constexpr unsigned char OB = 1;
|
||||||
|
constexpr unsigned char SM = 2;
|
||||||
|
constexpr unsigned char MS = 3;
|
||||||
|
constexpr unsigned char TC = 4;
|
||||||
|
constexpr unsigned char OG = 5;
|
||||||
|
constexpr unsigned char OBA = 6;
|
||||||
|
constexpr unsigned char SMA = 7;
|
||||||
|
constexpr unsigned char MSA = 8;
|
||||||
|
constexpr unsigned char TCA = 9;
|
||||||
|
constexpr unsigned char OGA = 10;
|
||||||
|
constexpr unsigned char FP = 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline StreamEncoding encoding_from_string(const std::string& str)
|
||||||
|
{
|
||||||
|
if (str == "SIGN")
|
||||||
|
{
|
||||||
|
return StreamEncodings::SIGN;
|
||||||
|
}
|
||||||
|
if (str == "OB")
|
||||||
|
{
|
||||||
|
return StreamEncodings::OB;
|
||||||
|
}
|
||||||
|
if (str == "SM")
|
||||||
|
{
|
||||||
|
return StreamEncodings::SM;
|
||||||
|
}
|
||||||
|
if (str == "MS")
|
||||||
|
{
|
||||||
|
return StreamEncodings::MS;
|
||||||
|
}
|
||||||
|
if (str == "TC")
|
||||||
|
{
|
||||||
|
return StreamEncodings::TC;
|
||||||
|
}
|
||||||
|
if (str == "OG")
|
||||||
|
{
|
||||||
|
return StreamEncodings::OG;
|
||||||
|
}
|
||||||
|
if (str == "OBA")
|
||||||
|
{
|
||||||
|
return StreamEncodings::OBA;
|
||||||
|
}
|
||||||
|
if (str == "SMA")
|
||||||
|
{
|
||||||
|
return StreamEncodings::SMA;
|
||||||
|
}
|
||||||
|
if (str == "MSA")
|
||||||
|
{
|
||||||
|
return StreamEncodings::MSA;
|
||||||
|
}
|
||||||
|
if (str == "TCA")
|
||||||
|
{
|
||||||
|
return StreamEncodings::TCA;
|
||||||
|
}
|
||||||
|
if (str == "OGA")
|
||||||
|
{
|
||||||
|
return StreamEncodings::OGA;
|
||||||
|
}
|
||||||
|
if (str == "FP")
|
||||||
|
{
|
||||||
|
return StreamEncodings::FP;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T two_bit_look_up[11][4]
|
||||||
|
{
|
||||||
|
[0] = {},
|
||||||
|
[1 /*OB*/] = {-2, -1, 0, 1},
|
||||||
|
[2 /*SM*/] = {0, 1, 0, -1},
|
||||||
|
[3 /*MS*/] = {0, 0, 1, -1},
|
||||||
|
[4 /*TC*/] = {0, 1, -2, -1},
|
||||||
|
[5 /*OG*/] = {-2, -1, 1, 0},
|
||||||
|
[6 /*OBA*/] = {-3, -1, 1, 3},
|
||||||
|
[7 /*SMA*/] = {1, 3, -1, -3},
|
||||||
|
[8 /*MSA*/] = {1, -1, 3, -3},
|
||||||
|
[9 /*TCA*/] = {1, 3, -3, -1},
|
||||||
|
[10 /*OGA*/] = {-3, -1, 3, 1},
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T three_bit_look_up[11][8]
|
||||||
|
{
|
||||||
|
[0] = {},
|
||||||
|
[1 /*OB*/] = {-4, -3, -2, -1, 0, 1, 2, 3},
|
||||||
|
[2 /*SM*/] = {0, 1, 2, 3, 0, -1, -2, -3},
|
||||||
|
[3 /*MS*/] = {0, 0, 1, -1, 0, 0, 1, -1},
|
||||||
|
[4 /*TC*/] = {0, 1, 2, 3, -4, -3, -2, -1},
|
||||||
|
[5 /*OG*/] = {-4, -3, -1, -2, 3, 2, 0, 1},
|
||||||
|
[6 /*OBA*/] = {-7, -5, -3, -1, 1, 3, 5, 7},
|
||||||
|
[7 /*SMA*/] = {1, 3, 5, 7, -1, -3, -5, -7},
|
||||||
|
[8 /*MSA*/] = {1, -1, 3, -3, 5, -5, 7, -7},
|
||||||
|
[9 /*TCA*/] = {1, 3, 5, 7, -7, -5, -3, -1},
|
||||||
|
[10 /*OGA*/] = {-7, -5, -1, -3, 7, 5, 1, 3},
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T four_bit_look_up[11][16]
|
||||||
|
{
|
||||||
|
[0] = {},
|
||||||
|
[1 /*OB*/] = {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7},
|
||||||
|
[2 /*SM*/] = {0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7},
|
||||||
|
[3 /*MS*/] = {0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1},
|
||||||
|
[4 /*TC*/] = {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1},
|
||||||
|
[5 /*OG*/] = {-8, -7, -5, -6, -1, -2, -4, -3, 7, 6, 4, 5, 0, 1, 3, 2},
|
||||||
|
[6 /*OBA*/] = {-15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15},
|
||||||
|
[7 /*SMA*/] = {1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15},
|
||||||
|
[8 /*MSA*/] = {1, -1, 3, -3, 5, -5, 7, -7, 9, -9, 11, -11, 13, -13, 15, -15},
|
||||||
|
[9 /*TCA*/] = {1, 3, 5, 7, 9, 11, 13, 15, -15, -13, -11, -9, -7, -5, -3, -1},
|
||||||
|
[10 /*OGA*/] = {-15, -13, -9, -11, -1, -3, -7, -5, 15, 13, 9, 11, 1, 3, 7, 5},
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T five_bit_look_up[11][32]
|
||||||
|
{
|
||||||
|
[0] = {},
|
||||||
|
[1 /*OB*/] = {-16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
||||||
|
[2 /*SM*/] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15},
|
||||||
|
[3 /*MS*/] = {0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1},
|
||||||
|
[4 /*TC*/] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1},
|
||||||
|
[5 /*OG*/] = {-16, -15, -13, -14, -9, -10, -12, -11, -1, -2, -4, -3, -8, -7, -5, -6, 15, 14, 12, 13, 8, 9, 11, 10, 0, 1, 3, 2, 7, 6, 4, 5},
|
||||||
|
[6 /*OBA*/] = {-31, -29, -27, -25, -23, -21, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31},
|
||||||
|
[7 /*SMA*/] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, -1, -3, -5, -7, -9, -11, -13, -15, -17, -19, -21, -23, -25, -27, -29, -31},
|
||||||
|
[8 /*MSA*/] = {1, -1, 3, -3, 5, -5, 7, -7, 9, -9, 11, -11, 13, -13, 15, -15, 17, -17, 19, -19, 21, -21, 23, -23, 25, -25, 27, -27, 29, -29, 31, -31},
|
||||||
|
[9 /*TCA*/] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, -31, -29, -27, -25, -23, -21, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1},
|
||||||
|
[10 /*OGA*/] = {-31, -29, -25, -27, -17, -19, -23, -21, -1, -3, -7, -5, -15, -13, -9, -11, 31, 29, 25, 27, 17, 19, 23, 21, 1, 3, 7, 5, 15, 13, 9, 11},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //ION_GSM_STREAM_ENCODINGS_H
|
Loading…
Reference in New Issue
Block a user