libwireless 源码解析
来源:互联网 发布:福州淘宝代运营 编辑:程序博客网 时间:2024/05/29 02:29
libwireless 源码的解析,扩展 和 使用
注:工程主体部分采用了抽象工厂模式,我们按照工程目录的结构,自顶向下地分析代码
源码可以在 Jonathan Perry 的 github 上面下载:https://github.com/yonch/wireless
代码在Ubuntu14.04版本上面的安装步骤可参考:http://blog.csdn.net/baobao3456810/article/details/50955788
1 python
说明:顶层 python 代码
1.1 python/codes
说明:只有 python 版本的
Spinal Codes
,C++版本的Spinal Codes
以工厂的形式呈现
1.2 python/protocols
说明:protocol 共包括,
1 Spinal Codes 的 protocol(C++)
2 One Try protocol(C++)
3 Multiple Try protocol(Python)
4 Rate Approximate protocol(C++)
文件包含: protocols/MultipleTryProtocol.py
:python/simulator/factories/ProtocolFactory.py
的第三种
1.3 python/simulator
说明:抽象工厂,根据给定的参数构造具体工厂,各个具体工厂根据参数生产具体产品
文件包含: simulator/factories
给出了一些具体的工厂,包括:
- Channel_Factory
- Demap_Factory
- Detector_Factory
- Map_Factory
- PacketGen_Factory
- Protocol_Factory:除了 Spinal Codes 外所使用的 protocol
- Statistics_Factory:调用 python/statistics 中的内容
- Codes_Factory: 包含几种信道编码的具体工厂,下面详细展开
simulator/factories/codes/*.py
给出了几种信道编码的具体工厂,包括:
- Fading_Strider_Factory
- LDPC_Factory
- LT_Factory
- Multiplexed_Factory
- Null_Factory
- Raptor_Factory
Spinal_Factory
- public:
- make_encoder:最终返回 MultiToSingleStreamEncoder 构造的编码器,以及符号数组类型,如 wireless.vectorus=vector< unsigned short>=16-bit
- make_decoder
- make_protocol
private:
围绕着
include/codes/spinal/CodeFactory.h
的编译码的实现,其中的三个模块是相互递进的关系。
CodeFactory 为Spinal编译码的主工厂,返回一种具体的哈希函数编码方案,包括:salsa,lookup3,oneAtATime。
IEncoderFactory Spinal 信道选择工厂,返回针对特定信道下的编码方案,包括:linear,soft,gaussian,bitwise,coherence。
ISearchFactory Spinal 译码算法选择工厂,在楼上的基础上选择一种译码方案,包括:beamDecoder,lookaheadBeamDecoder,并返回译码器和信道符号类型。- _make_unpunctured_encoder:选择一种哈希编码方案,使用CodeFactory.encoder()方法构造编码器。
- _make_unpunctured_decoder:选择一种信道模式,以及译码算法(regular,lookahead,parallel)
- _get_punctured_decoder_type:返回与信道对应打孔后的符号类型,使用了MultiToSingleStreamDecoder类,符号的表示不清楚可以参考
bindings/codes/codes.i
的类型的重命名(即python与C++版本的对应关系) - _get_num_blocks:=n/k
- _get_puncturing:选择一种打孔机制(8-way-v2,static),以及是否要重复打孔(encoderToSymbolRate)
- public:
- Strider_Factory
- Turbo_Factory
simulator/default_configuration.py
返回一个列表,为仿真组建提供了可以访问的工厂,参考 simulator/factories/
中实现的工厂。 simulator/FactoryCollection.py
工厂类,使仿真组建可以聚合多个具体工厂,也就是生产工厂的工厂
- self._factories:字典,Key=’make_pre_packet_manipulator’, ‘make_packet_generator’, ‘make_encoder’, ‘make_mapper’, ‘make_channel’, ‘make_demapper’, ‘make_decoder’, ‘make_detector’, make_protocol’, ‘make_statistics’,Value=[defaulte_configuration中工厂类中所有名为 Key 值的工厂方法]
- self._cache:字典,Key同上,Value为一个元组(工厂方法的参数,工厂方法返回的值“产品”)
- add_factory(self, factory):输入 factory 为 defaulte_configuration 的 get_factory_list() 方法返回的各种工厂之一(如 ChannelFactory),功能是为 _factories 添加 Value
- make(self, func_name, *args):需要注意的是,工厂方法接收到“不认识”的参数时,会返回None,遍历_factories[某工厂方法名],即同名的所有方法,当参数不满足时返回None,也就是说只要传给工厂方法的参数满足某个工厂方法的输入要求,就会返回该工厂的“产品”
simulator/SanityTest.py
包含了多个测试程序,配合 simulator/Simlator.py
使用,包括:
Spinal Codes:
- run_Test:random packet,spinal,linear map,AWGN,no demap,regular beamSearch decode,oracle detect,sequential protocol,errors statistics
- run_ParallelK_Test:parallel k beamSearch decode,其他同“1”
- run_Coherence_FadingTest:soft map,coherence-fading channel,其他同“1”
- run_Rate_Approx_ProtocolTest:rate-approx protocol,其他同“1”
- run_Gaussian_Test:trunc-norm-v2 map,其他同“1”
- run_Lookahead_Test:lookahead decode,其他同“1”
- run_Crc_Test:crc16 packet,crc16 detector,其他同“1”
- run_First_Error_Statistics_Test:first-error,其他同“1”
LDPC:
- run_LDPC_Test:random packet,ldpc,gray map,AWGN,ml-gray demap,ldpc-float-bp decode,oracle detector,one-try protocol,errors statistics
- run_Itpp_Qam_LDPC_Test:QAM map,AWGN_c(),QAM demap,其他同“2”
- run_Bsc_LDPC_Test:linear map,BSC,BSC demap,其他同“2”
Turbo:
- run_Itpp_Qam_Turbo_Test:random packet,Turbo,AWGN_c,QAM map,regular demap,oracle detector,one-try protocol,errors statistics
LT codes
- run_LT_Test:random packet,LT codes,QAM map,AWGN_c,LT decode,oracle detector,rate-approx protocol,errors statistics
Raptor codes
- run_Raptor_Test:raptor codes,raptor decode,其他同“3”
Strider codes
- run_Strider_Test:strider codes,null map,null demap,strider decode,multiple-try protocol,其他同“3”
- run_Short_Strider_Test:与上面长度不同
- run_Strider_Transparent_Fading_Test:transparent-coherence_c channel,其他同上strider
- run_Strider_Fading_Test:coherence-fading_c channel,strider-fading decode,其他同上
Null 无编码
- run_Null_Decoder_Test:random packet,null code,AWGN_c,QAM map,null decode,oracle detector,one-try protocol,errors statistics
simulator/Simulator.py
具体类,实现了一个完整的数据包的发送过程,适用于所有的编码方案,包括:
- getComponents (experiment): 由 exper_spec 给出的参数方案 make 组件(由工厂生产产品)
- seed (seed): 为用到 random 的组件的提供“种子”
- runPacket (): 针对单个数据包 模拟传输机制,当统计结果中 isFinish==True 或者 nextNumChannelSymbols == 0 时,停止对当前数据包的发送,转向下一个数据包。
- runExperiment(experiment, initialSeed, numPackets): 运行实验的过程
1.4 python/statistics
说明:给出收集统计信息的方式,Jonathan实现了三种方式,这里给出的是python实现,被 StatisticsFactory() 工厂类调用
三种统计方式的区别还有待于研究
文件包含: statistics/ErrorLocationStatistics.py
:对应 StatisticsFactory 中的 bit-statistics 模式。Collected statistics on location of errors
- ErrorLocationStatisticsResult:(被下者调用的):记录单条信息的错误模式(error pattern)
- ErrorLocationStatistics(被工厂使用的):在译码结束时记录统计信息,并统计错误出现次数
statistics/ErrorRateStatistics.py
:对应 StatisticsFactory 中的 error 模式。Collected statistics on number of errors
- Error_Rate_Statistics_Result(被下者调用的):针对某一个 packet,将译码后的 packet 与发送的 packet 做比较,统计当前 packet 的译码正确率
- Error_Rate_Statistics(被工厂使用的):在译码结束时记录统计信息,并统计错误出现次数
statistics/FirstErrorStatistics.py
:对应 StatisticsFactory 中的 first-error 模式。 Collected statistics on bit-index of first bit error ,包括以下几类:
- First_Error_Statistics_Result(被下者调用的):记录单条信息的错误模式(error pattern)
- First_Error_Statistics(被工厂使用的):在译码结束时记录统计信息,并统计错误出现次数
1.5 python/util
说明:Google Protocol Buffer,
util/serialization/results.proto
不太明确,只知道被ErrorRateStatistics.py
调用
2 bindings
说明:python API from C++,在阅读或修改 binding 代码时最好对应着
./include
中的内容
补充:在 SWIG 中,不是所有头文件以及辅助文件中被包含的模块都要封装到 binding codes 中,所以在 SWIG 中使用%include
来导入模块,且 %include 的内容在预编译时只编译一次,同时把不需要预编译的模块放入%{ ... %}
中。
注意:该工程中多处定义了各种不同功能的智能指针,这些将留在指针的定义中详细介绍,SWIG 使用只能指针的方法是%shared_ptr(T)
;另外,binding 中的所有注释有numpy
的地方请见 Numpy.i SWIG 文档
2.1 bindings/codes
说明:顾名思义,该模块实现了几种仿真需要的信道编码的 Python 接口
codes/spinal
codes/spinal/spinal.i
:实现了include/codes/spinal
中的模块的接口
codes/codes_workaround.i
:辅助下面的 codes.i
codes/codes.i
封装几乎所有跟差错控制编码有关的智能指针,并包含 include/codes
中所有跟代码有关的功能模块,如 编码指针/解码指针/打孔/码流控制 等
codes/fountain.i
封装了 LT 码 和 Raptor 码 相关的模块和智能指针,对应 include/codes/fountain
codes/ldpc.i
封装了LDPC模块,对应 include/codes/ldpc
codes/null.i
对应 include/codes/null
,无编码 codes/strider.i
封装了 strider 模块,对应 include/codes/strider
codes/turbo.i
封装了 turbo 模块,对应 include/codes/turbo
2.2 bindings/itpp
说明:虽然 IT++ 中实现了大部分通信仿真所需要的功能,但该工程中并没有使用 IT++ 中的规则,而只是使用了 IT++ 中个别的模块,详细请见下文
包括:
- base_sparse.i
- base_vec.i
- ldpc.i
- llr.i
- modulator.i
2.3 bindings/util
说明:对应实现了
include/util/
中的部分模块的接口
包括:(基本与 include
目录下的模块对应,详细功能去 include 中查找)
- config.i
- hashes.i
- inference.i
2.4 bindings/*.i
bindings/numpy.i
:binding 的节头注意中有表述
bindings/common.i
包括 Exception handling,numpy,Smart pointers,SWIG 对 exception 和 Smart pointers 有相应的扩展,故这里可以直接 %include,另外若要了解 SWIG 使用 shared_ptr 的详细用法请参考 SWIG 的官方文档,简单地说就是定义一个宏变量,并包含 %include < std_shared_ptr.i>,至于 numpy.i
在前面介绍过
bindings/general.i
:STL模板的实例化,以及数据类型的转换,其中所使用到的模板的定义在C++声明中,留意各个数据类型的定义即可,比较复杂,故这里一一列出,以便查找
- Symbol = int
- SoftSymbol = float
- N0_t = float
- FadingMagnitude = float
- LLRValue = float
- ComplexSymbol = complex
- FadingSymbol == FadingSymbolTuple< SoftSymbol>
- FadingComplexSymbol == FadingSymbolTuple< ComplexSymbol>
- vectori == vector< int>
- vectorcf == vector< std::complex< float> >
- vectorcd == vector< std::complex< double> >
- vectorui == vector< unsigned int>
- vectorus == vector< unsigned short>
- vectors == vector< short>
- vectorul == vector< unsigned long>
- vectorull == vector< unsigned long long>
- vectorb == vector< bool>
- vectorf == vector< float>
- vectorstr == vector< string>
- vector_fadingsymbol == vector< FadingSymbol>
- vector_fading_csymbol == vector< FadingComplexSymbol>
- vector_csymbol = vectorcd
- vector_symbol = vectori
- vector_softsymbol = vectorf
- vector_llr = vectorf
bindings/channels.i
:主要包括 下面模块(详细请见代码),比较复杂,故这里一一列出,以便查找
- SymbolAwgnChannel == AwgnChannel< Symbol>
- ComplexAwgnChannel == AwgnChannel< ComplexSymbol>
- SoftAwgnChannel == AwgnChannel< SoftSymbol>
- FadingAwgnChannel == AwgnChannel< FadingSymbol>
- FadingComplexAwgnChannel == AwgnChannel< FadingComplexSymbol>
- SoftCoherenceFading == CoherenceFading< SoftSymbol>
- ComplexCoherenceFading == CoherenceFading< ComplexSymbol>
- MimoAwgnChannel == CompositeChannel< MimoChannel ,ComplexAwgnChannel>
- AwgnCoherenceFadingChannel == CompositeChannel< SoftCoherenceFading, FadingAwgnChannel>
- AwgnCoherenceComplexFadingChannel == CompositeChannel< ComplexCoherenceFading, FadingComplexAwgnChannel>
- ComplexTransparentFadingChannel == TransparentCoherenceFading< ComplexSymbol>
- SoftTransparentFadingChannel == TransparentCoherenceFading< SoftSymbol>
- SymbolTransparentFadingChannel == TransparentCoherenceFading< Symbol>
bindings/mappers_workaround.i
:辅助下面的 mappers.i
,但据观察,下文并没有包含这个文件
bindings/mappers.i
:封装了只能指针 IMapper,QPSKMapper,QamMapper,LinearMapper,并包含了 include/mappers
中的内容
bindings/demappers_workaround.i
:辅助下面的 demappers.i
,但据观察,下文并没有包含这个文件
bindings/demappers.i
:包含了 include/mappers
中的部分内容,封装并实例化了 IDemapper 智能指针,分别为 template_IDemapper_Symbol,template_IDemapper_ComplexSymbol,GrayDemapper,ItppComplexDemapper
bindings/misc.i
bindings/protocols.i
:实现了对应 include/protocol
中的模块的接口,即 OneTryProtocol 和 RateApproxProtocol
3 include
说明:大部分功能模块的声明(.h),个别功能模块的实现(.hh)。本人C++不是很好,只能先这样理解,在这里具体的类往往声明和实现是分开的,而模板类中方法的实现是定义在模板类的声明文件中
3.1 include/channels
AwgnChannel.h
:实现了 AWGN 信道的仿真,其中 N0_t
为 float 类型,名称规则要与channel.i
一致
- AwgnChannel(N0_t n0):定义噪声的功率谱密度
- void seed(unsigned int* const seed, int seedSize):所有的伪随机数生成器都要有种子
- void process(const std::vector& inSymbols, std::vector& outSymbols):将噪声加到 inSymbols 上,生成 outSymbols
- unsigned int forecast(unsigned int numOutputs):骗人的,没实现啥
- double getStddevPerDimension():返回噪声的标准差
- ChannelSymbol noisify(ChannelSymbol x, double stddevPerDimension):见
AwgnNoiseGenerator.h
AwgnChannel.hh
:AwgnChannel.h
中方法的实现
AwgnNoiseGenerator.h
:实现了将噪声加到符号上 BscChannel.h
:BSC 信道的仿真,结构跟 AWGN 差不多,但实现起来要简单多了 CoherenceFading.h
:瑞利衰减信道实现(接收端知道衰减系数)
CoherenceFading.hh
CoherenceCoeffGenerator.h
:可以根据相干时间计算衰减系数
TransparentCoherenceFading.h
:瑞利衰减信道实现(接收端不知道衰减系数)
TransparentCoherenceFading.hh
CompositeChannel.h
:通过合并两个信道成为一个新的信道
CompositeChannel.hh
MimoChannel.h
:MIMO 信道的仿真
3.2 include/codes
说明:该模块给出了编码器和译码器的实现结构,以及多种编码译码方法(这里用“方法”是为了与util中的“算法想区分”),由于该部分是本工程的主体,故这里对主要的类的组成结构也做详细介绍,虽然只是把内容从代码中摘出来,但这样看起来对功能的理解会很有帮助。特别要注意的是虚基类的使用。
注意:代码中的“I”开头的类表示接口(interface),实现上都是采用虚基类,且与 shared_ptr 指针一同使用,下文不一一雷述。而我们使用的都是“非接口”模块,所以对所有的模块都要好好的理解。
另外,值得注意的是,对 Spinal Codes 来说,打孔(puncturing)的方法可能与传统上有些差别,涉及到将一个码流(Code Stream)分解(divide)为多个子码流,故这里Jonathan(代码作者)在包含打孔的编码器和译码器的命名上采用 MultiStream××× 的形式,这里为了方便理解单独指出。
include/codes/archive
说明: 顾名思义,编码过程中的所有的内存管理。
CachedEncoder.h
:还有待于研究,继承自 IEncoder,符号输出前在 pass 中的内存管理类,以通道(passes)为单位成批地生产编码符号,代码结构如下:- public:
- CachedEncoder( Encoder encoder, unsigned int numPackets, unsigned int numCachedSymbolsPerPacket):指定编码器,数据包的数量,每个 batch 中的符号数量
- ~CachedEncoder()
- void setPacket(unsigned int packetInd, const string& packet)
- void removePacket(unsigned int packetInd):Removes the packet from the cache
- bool hasPacket(unsigned int packetInd):True if packet exists, False otherwise.
- void getSymbols( unsigned int packetInd, unsigned int firstSymbolToEmit, unsigned int lastSymbolToEmit, std::vector< Symbol>& outSymbols):从指定的 pass 中取出输出符号到 outSymbol 中
- private:
- CachedEncoder(const CachedEncoder&)
- CachedEncoder& operator=(const CachedEncoder&)
- void getAndCacheSymbolBlock(unsigned int packetInd, unsigned int blockIndex):为每个 symbol block 分配内存
- Encoder m_encoder:指定的编码器
- unsigned int m_numPackets:实例所提供的数据包数量
- unsigned int m_numCachedSymbolsPerPacket:每个数据包所分配的 cache 数量
- vector< string> m_packets:待编码的数据包,下面的成员数组中的序号应该是数据包的编号
- vector< bool> m_hasPacket:是否指定了数据包
- vector< int> m_cachedBlockIndex:不是很明确,packet 的数量往往不是正好的,故有多少 cache 需要额外补偿呢?
- public:
CachedEncoder.hh
:楼上的实现IMultiEncoder.h
:虚基类,功能更多的 IEncoder,但大部分用的都是 IEncoder,结构如下:- virtual ~IMultiEncoder() {}
- virtual void setPacket(unsigned int packetInd, const std::string& packet) = 0
- virtual void removePacket(unsigned int packetInd) = 0
- virtual bool hasPacket(unsigned int packetInd) = 0
- virtual void encode( unsigned int packetInd, unsigned int numSymbols, std::vector< uint16_t>& outSymbols) = 0
IMultiDecoder.h
:结构如下:- virtual ~IMultiDecoder() {}
- virtual void resetPacket(unsigned int packetInd) = 0
- virtual void addSymbols( unsigned int packetInd, const std::vector< ChannelSymbol>& symbols) = 0
- virtual void decode(unsigned int packetInd) = 0
- virtual DecodeResult getDecodeResult(unsigned int packetInd) = 0
CachedMultiDecoder.h
:继承自 IMultiDecoder ,功能不是很明确CachedMultiDecoder.hh
:楼上的实现LinearCheckNodeUpdater.h
:结合 BP 使用,参考 include/util/inference/bp/NodeUpdater.h- class LogPmQ
- class LinearCheckNodeUpdater : public NodeUpdater< float>
LinearCheckNodeUpdater.cpp
:楼上的实现
include/codes/fountain
说明:主要实现了 LT 和 Raptor 喷泉码的算法
- LT Codes:
LTParityNeighborGenerator.h
:生成 LT 的节点分布,并选择使用哪些 bit 进行 XORParityEncoder.h
:LT 码编码器,只是被抽象成了根据给定的节点分布的图编码- public:
- ParityEncoder( unsigned int numMessageBits, const NeighborGenerator& neighborGenerator, const SymbolFunction& symbolFunction):其中 neighborGenerator 由楼上的模块产生
- virtual ~ParityEncoder() {}
- virtual void setPacket(const std::string& packet)
- virtual void encode( unsigned int numSymbols, std::vector< uint16_t>& outSymbols)
- private:
- uint16_t next()
- const unsigned int m_numMessageBits
- NeighborGenerator m_neighborGenerator
- SymbolFunction m_symbolFunction
- unsigned int m_nextSymbolIndex
- std::vector< bool> m_packetVector
- std::vector< unsigned int> m_neighbors
- public:
LTDecoder.h
:继承自 ILLRDecoder,LT 码的译码器,- public:
- LTDecoder(uint32_t numVariables, uint32_t llrBufferSize, uint32_t numIterations)
- virtual ~LTDecoder() {}
- virtual void reset()
- virtual void add(const std::vector< LLRValue>& llrs):为译码器添加似然信息,注意译码器只支持连续的似然信息
- virtual DecodeResult decode():根据给定的接受符号解码出数据包
- virtual void softDecode(std::vector< LLRValue>& llrs):软判决译码方法,
- private:
- const uint32_t m_numVariables:可变节点的数量
- std::vector< LLRValue> m_llrs:
- LTParityNeighborGenerator m_neighborGenerator:存储度分布
- public:
- Raptor Codes:
RaptorEncoder.h
:外码(预编码) LDPC(取自 itpp 库),内码 LT,而 Raptor Codes 真正生成的函数位于python/simulator/factories/codes/RaptorFactory.py 中 。注意:在级联码的概念中,预编码称为外码(首先操作),与之级联的码称为内码(在预编码之后操作)- public:
- RaptorEncoder(const std::string& ldpcFilename):ldpcFilename 位于 ./data/ldpc 中,为 itpp 生成的 *.it 文件,data 中的数据是如何产生的???
- virtual void setPacket(const std::string& packet):(这个函数很讲究),其中首先将 数据包转换成 itpp::bvec 类型,然后使用 itpp::ldpc 编码,得到 ldpcCodeword,转为 string 后,在将 ldpc 的编码结果传递给 LT 码编码器
- virtual void encode( unsigned int numSymbols, std::vector< uint16_t>& outSymbols):必须结合 setPacket 方法,因为这一步只进行 LT 编码,但 LT 的输入为 ldpc 码字
- private:
- static BitwiseXorSymbolFunction getSymbolFunction()
- static LTParityNeighborGenerator getNeighborGenerator(uint32_t codewordSize)
- itpp::LDPC_Generator_Systematic m_G
- itpp::LDPC_Code m_ldpc
- ParityEncoder< BitwiseXorSymbolFunction, LTParityNeighborGenerator> m_lt
- itpp::bvec m_packetBits
- itpp::bvec m_encodedBits
- std::vector< uint16_t> m_encodedVec
- public:
RaptorDecoder.h
:继承自 ILLRDecoder ,先 LT 解外码,然后用 itpp::ldpc 解内码- public:
- RaptorDecoder(const std::string& ldpcFilename, uint32_t numLtIterations)
- virtual ~RaptorDecoder() {}
- virtual void reset()
- virtual void add(const std::vector< LLRValue>& llrs)
- virtual DecodeResult decode()
- private:
- itpp::LDPC_Generator_Systematic m_G
- itpp::LDPC_Code m_ldpc
- LTDecoder m_lt
- std::vector< LLRValue> m_llrs
- itpp::vec m_itppLlrs
- itpp::bvec m_decodedBits
- public:
include/codes/ldpc
说明: 没有仔细看,自己实现的 LDPC 码,有一些扩展功能
include/codes/null
说明: 继承了 IEncoder,基本就是一个空壳,不对输入做任何修改
NullDecoder.h
NullEncoder.h
include/codes/puncturing
说明:实现了各种打孔机制
IPuncturingSchedule.h
:打孔机制的接口- virtual ~IPuncturingSchedule() {}
- virtual void reset() = 0
- virtual void batchNext(unsigned int numSymbols, std::vector< uint16_t>& streamIndices) = 0:产生输出码流
RepeatingPuncturingSchedule.h
:Splits the symbols stream to 8 sub-groups, then sends symbols from each sub-groupRoundRobinPuncturingSchedule.h
:Gets symbols from index 0 to last index and wraps around,一种调度机制StaticPuncturingSchedule.h
:Punctures according to a given vector,传统的打孔StridedPuncturingSchedule.h
:Splits the symbols stream to 8 sub-groups, then sends symbols from each sub-group,strider 的打孔方式
include/codes/spinal (重点!故换颜色!)
说明:重点中的重点,整个工程的核心编码算法,实现部分最好也要搞明白
图注:从上面两幅层次结构图可以看出 IMultiStreamEncoder 和 IMultiStreamDecoder 基本就是为 Spinal Codes 这样的编码设计的,因为两者都包含码流结构的打孔方法。
protocols
说明:为 Spinal Codes 提供传输协议
SequentialProtocol.h
:pinal protocol, transmits one pass after another,一个 pass 接一个 pass 发送SequentialProtocol.hh
:楼上的实现
StridedProtocol.h
:超级重要!!! Spinal Codes 的 Strided 传输协议,配合 Strided 打孔使用。 Spinal protocol, suited for StridedPuncturingSchedule (“8-way puncturing”).- public:
- StridedProtocol(unsigned int numPackets,
unsigned int spineLength,
unsigned int maxSymbols,
unsigned int numLastStepSymbolsPerPass,
unsigned int numRepetitions) - unsigned int numSymbolsNextDecode(unsigned int packetInd)
- void setResult(unsigned int packetInd,
unsigned int numSymbols,
bool isFinished):起到记录当前译码结果的作用。如果本次译码成功,则记录所发送的符号数,如果本次译码失败,则使用 maxSymbol 作为下一次译码的 推荐符号数 - void resetPacket(unsigned int packetInd)
- StridedProtocol(unsigned int numPackets,
- private:
- const unsigned int m_maxSymbols:阈值,译码器用来尝试译码的最大的符号数,超过这个值就放弃译码。
- vector< unsigned int> m_numSymbolsPerSubpass
- vector< unsigned int> m_lastSubpassInd
- vector< unsigned int> m_lastOutputNumSymbols:numSymbolsNextDecode的返回值。
- vector< unsigned int> m_lastActualNumSymbols:上一次译码使用到的符号的数量。
- public:
IHashDecoder.h
- struct SpinalDecodeResult : public DecodeResult:Spinal Codes 译码结果保存形式,多了一个 weight 参数
- class IHashDecoder : public IMultiStreamDecoder< ChannelSymbol>
CodeFactory.h
:针对 Spinal Codes 的编解码的各个工厂模块,包括:- class CodeFactory:编解码主工厂,选择一种编码方式(IEncoderFactory),包括:salsa/lookup3/oneAtATime
- class IEncoderFactory:选择一种信道模式,也就是接收端接收到的信道的符号格式(ISymbolSearchFactory),包括:linear/soft/gaussian/bitwise/coherence
- class ISearchFactory:选择一种译码时使用到的搜索方式,包括:beamDecoder/lookaheadBeamDecoder
FlatSymbolStorage.h
:symbol 的存储,使用 Spine 值作为索引FlatSymbolStorage.hh
:楼上的实现
HashEncoder.h
:Spinal Codes 的编码器,class HashEncoder : public IMultiStreamEncoder- public:
- HashEncoder(unsigned int k, unsigned int spineLength):Encodes the packet “packet” into real symbols in [-1,1].
- virtual void setPacket(const std::string& packet)
- virtual void encode( const std::vector< uint16_t>& spineValueIndices, std::vector< uint16_t>& outSymbols)
- private:
- const unsigned int m_k:“K”值
- const unsigned int m_numMessageBits:信息序列的比特数
- const unsigned int m_spineLength:Spine 的比特长度
- std::vector< SpineValueType> m_spine:用于存储 spine 值的数组
HashEncoder.hh
:楼上的实现
- public:
SpinalBranchEvaluator.h
:用于 Spinal Codes Bubble decode 译码树上的分支度量的计算,包括:- IntegerEuclidianDistance.dist(Symbol x, Symbol y):计算整数符号 x 和 y 的欧式距离
- SoftEuclidianDistance.dist(SoftSymbol x, SoftSymbol y):计算软符号 x 和 y 的欧式距离
- HammingDistance.dist(Symbol x, Symbol y):计算整数符号 x 和 y 的汉明距离
- FadingEuclidianDistance.dist(Symbol x, Symbol y):计算衰减后的软符号 x 和 y 的欧式距离
- struct SpinalNode:存储了 Spinal Codes 译码树的节点结构
- bool operator<(const SpinalNode& other) const
- WeightType getWeight()
- WeightType getLikelihood
- WeightType likelihood
- WeightType lastCodeStepLikelihood
- SpineValueSeed hash
- struct SymbolCollection:用于存储接收符号
- class SpinalBranchEvaluator:用于估计译码树上的分支最大似然值
- public:
- SpinalBranchEvaluator(const ChannelTransformation& xform, uint32_t k)
- void branch(Node& parent, unsigned int edge, BranchData& syms, Node& child)
- void initNode(Node& node)
- private:
- const uint32_t m_k
- const uint32_t m_mask:低 k 比特的 mask
- ChannelTransformation m_xform:ChannelTransformation from bits to symbols,不明觉历
- typename std::vector< uint16_t> m_encodedSymbols:重新编码后的符号
- std::vector< typename ChannelTransformation::OutputType> m_candidateSymbols:序列译码的候选符号
- std::vector< typename ChannelTransformation::OutputType> m_observedSymbols:被计算过分支度量的符号
- 个别模板类的实现,其他的实现在 src/codes/spinal/ 中
- public:
HashDecoder.h
:Spinal Codes 的译码- struct SpinalIntermediateResult:保存了译码的中间状态
- class HashDecoder : public IHashDecoder < typename Search::Evaluator::ChannelSymbol>:真正的译码器部分
HashDecoder.hh
:实现
StubHashDecoder.h
:译码器的输入被保存起来,可访问,用于测试用的译码器Composites.h
:typedef SequentialProtocol< StridedPuncturingSchedule> StridedSequentialProtocol,没有别的内容了
include/codes/strider
说明: strider 编码的实现,没有对这个编码有详细的研究
LayeredDecoder.h
LayeredEncoder.h
LayerManipulator.h
LayerSuperposition.h
StriderFactory.h
StriderGeneratorMatrix.h
StriderInterleaver.h
StriderTurboCode.h
include/codes/turbo
说明: 基于 itpp 的 turbo 编码
TurboCodec.h
:Turbo 交织器TurboEncoder.h
:Turbo 编码器TurboDecoder.h
:Turbo 译码器
注意:下面给出的编码器和译码器一部分是提供了顶层的接口,一方便用户使用,另一部分是为 Spinal Codes 提供编码和译码,继承关系如下图所示
codes/IEncoder.h
:虚基类,编码器的接口,同 shared_ptr 一同使用,大部分的编码器都继承自 IEncoder 类,因此可以理解为编码器的框架,包括:
- virtual ~IEncoder() {}
- virtual void setPacket(const std::string& packet) = 0:读入将被编码的数据包
- virtual void encode(unsigned int numSymbols, std::vector< uint16_t>& outSymbols) = 0:将第numSymbols个编码符号存入outSymbols
codes/IMultiStreamEncoder.h
:提供打孔功能的编码器的接口,貌似处理 location 和 stream 能够实现打孔功能,包括:
- virtual ~IMultiStreamEncoder() {}
- virtual void setPacket(const std::string& packet) = 0
- virtual void encode( const std::vector< uint16_t>& streamIndices, std::vector< uint16_t>& outSymbols) = 0
codes/EncoderMultiplexer.h
:继承自 IEcoder,负责将源信息分别分给不同的编码器,并用 round-robins 方法调度不同的编码器
- public:
- typedef std::tr1::shared_ptr< EncoderMultiplexer> Ptr
- EncoderMultiplexer(const std::vector< IEncoderPtr>& encoders, const std::vector< uint32_t>& messageLengthsBits)
- virtual ~EncoderMultiplexer() {}
- virtual void setPacket(const std::string& packet)
- virtual void encode( unsigned int numSymbols, std::vector< uint16_t>& outSymbols)
- private:
- const std::vector< IEncoderPtr> m_encoders
- const std::vector< uint32_t> m_messageLengthsBits
- uint32_t m_next
- std::vector< uint16_t> m_symbolBuffer
codes/InterleavedEncoder.h
:继承自 IEcoder,首先使用指定的编码器进行编码,然后根据给定的交织序列随机打乱(shuffle)编码器的输出符号,以实现交织,实现部分位于 src/codes/InterleavedEncoder.cpp
- public:
- InterleavedEncoder(IEncoderPtr& encoder, const std::vector< uint16_t>& interleaveSequence)
- virtual ~InterleavedEncoder() {}
- virtual void setPacket(const std::string& packet)
- virtual void encode( unsigned int numSymbols, std::vector< uint16_t>& outSymbols)
- private:
- IEncoderPtr m_encoder:给定的编码器
- const std::vector< uint16_t> m_interleavingSequence:交织序列
- const uint16_t m_maxIndex:交织序列中的最大的序号
- std::vector< uint16_t> m_encoded:编码后的数据包
- unsigned int m_next:下一个输出的符号
codes/MultiToSingleStreamEncoder.h
:继承自 IEncoder,使用指定的编码器对数据包进行编码,并采用“分流法”对编好的码字打孔,产生一系列的码流的过程。其实现位于 src/codes/MultiToSingleStreamEncoder.cpp 中,代码结构如下:
- MultiToSingleStreamEncoder(IMultiStreamEncoder::Ptr& encoder, IPuncturingSchedulePtr& puncturing):指定编码器 与 打孔机制。 -
codes/DecodeResult.h
:译码后结果的结构,包括:
- std::string packet:(string)某数据包的译码结果
- float logProbError:(float)经过译码处理后表现出来的差错概率的 log 值。
codes/IDecoder.h
:虚基类,译码器接口,同 shared_ptr 一同使用,包括:
- virtual ~IDecoder() {}
- virtual void reset() = 0:Resets the decoder, so a different packet can be decoded
- virtual void add(const std::vector< ChannelSymbol>& symbols, N0_t n0) = 0:假设噪声功率对不同的信息符号是相同的,为译码器添加符号
- virtual void add(const std::vector< ChannelSymbol>& symbols, const std::vector< FadingMagnitude>& fadingMagnitude, N0_t n0) = 0:假设数据包传输在衰减信道中,其中噪声功率是恒定的,但接收到的噪声功率发生了变化,同样是为译码器添加符号
- virtual DecodeResult decode() = 0:译码函数,返回译码结果 DecodeResult
codes/ILLRDecoder.h
:在译码时,基于对数似然比估计信息比特,结果与 IDecoder 很像,包括
- virtual ~**ILLRDecoder**() {}
- virtual void reset() = 0
- virtual void add(const std::vector< LLRValue>& llrs) = 0:为译码器加入最大似然信息
- virtual DecodeResult decode() = 0:译码函数
codes/IMultiStreamDecoder.h
:为打孔码字(punctured codes)提供译码器的接口,包括:
- virtual ~IMultiStreamDecoder() {}
- virtual void reset() = 0
- virtual void add(const std::vector< uint16_t>& streamIndices, const std::vector< ChannelSymbol>& symbols, N0_t n0) = 0:为译码器添加符号,其中 streamIndices 为当前 symbol 所属的 stream 编号
- virtual DecodeResult decode() = 0
codes/InterleavedDecoder.h
:继承自 ILLRDecoder ,解交织,再译码
- public:
- InterleavedDecoder(const Decoder& decoder, const std::vector< uint16_t>& interleaveSequence)
- virtual ~InterleavedDecoder() {}
- virtual void reset()
- virtual void add(const std::vector< float>& symbols)
- virtual DecodeResult decode()
- private:
- Decoder m_decoder
- std::vector< uint16_t> m_interleavingSequence:有交织功能,就要有交织序列存储在译码器中
codes/InterleavedDecoder.hh
:InterleavedDecoder 中方法的实现
codes/MultiToSingleStreamDecoder.h
:继承自 IDecoder< ChannelSymbol>,通过对接收符号进行重新排序(或者称之为组合跟容易理解),以实现对打孔后的接收序列的译码
- public:
- typedef std::tr1::shared_ptr< MultiToSingleStreamDecoder< ChannelSymbol> > Ptr
- MultiToSingleStreamDecoder(typename IMultiStreamDecoder< ChannelSymbol>::Ptr& decoder, IPuncturingSchedulePtr& puncturing)
- virtual void reset()
- virtual void add(const std::vector< ChannelSymbol>& symbols, N0_t n0)
- virtual void add(const std::vector< ChannelSymbol>& symbols, const std::vector< FadingMagnitude>& fadingMagnitude, N0_t n0)
- virtual DecodeResult decode()
- private:
- typename IMultiStreamDecoder< ChannelSymbol>::Ptr m_decoder
- IPuncturingSchedulePtr m_puncturing
- std::vector< uint16_t> m_streamIndicesWorkArr
codes/MultiToSingleStreamDecoder.hh
:MultiToSingleStreamDecoder 的实现
codes/RandomPermutationGenerator.h
:随机排列(permutation)生成,不知作者在这里为什么用排列,而不用序列,没遇到使用这个模块的其他模块,等遇到了再好好研究这个模块的功能
codes/SymbolToLLRDecoderAdaptor.h
:将指定的 demaper 和 LLRdecoder 结合起来 codes/SymbolToLLRDecoderAdaptor.hh
:楼上的实现部分
3.3 include/mappers
说明: 实现了调制过程,因为在定义工厂时,调制也会有详细的使用,所以这里尽量列出代码结构。
IMapper.h
:映射的接口,包括:
- virtual ~IMapper() {}
- virtual void process(const std::vector< uint16_t>& inSymbols, std::vector< ChannelSymbol>& outSymbols) = 0
- virtual float getAveragePower() = 0
- virtual unsigned int forecast(unsigned int numOutputs) = 0
ComplexLinearMapper.h
:把一个整数映射到 I-Q 域上,代码结构如下:
- public:
- ComplexLinearMapper(unsigned int numBitsPerDim)
- void process(const std::vector< uint16_t>& inSymbols, std::vector< ComplexSymbol>& outSymbols):Maps symbols to the complex domain. 规则是 LSB’s taken for real part, next bits for imaginary
- ComplexSymbol map(uint16_t sym):Maps a single symbol to the complex domain
- float getAveragePower():假设 Spinal 编码的结果是均匀分布的,求出了信号的平均功率
- unsigned int forecast(unsigned int numOutputs):
- private:
- const unsigned int m_numBitsPerDim:单维度上,每个符号的比特数
- const uint16_t m_symbolMask:取符号的 LSB 作为一个维度,如:Mask(I-Q) = 0x00FF
GaussianMapper.h
:将符号映射到 truncated Gaussian 分布上,代码结构:
- public:
- GaussianMapper(unsigned int inputNumBits, unsigned int precisionBits, float numStandardDevs): inputNumBits 为输入数据的比特数,precisionBits 信道支持的比特数,numStandardDevs 为高斯分布的标准差
- GaussianMapper(const GaussianMapper& other)
- ~GaussianMapper()
- void process(const std::vector< uint16_t>& inSymbols, std::vector< Symbol>& outSymbols):将符号线性映射成较大的精度
- Symbol map(uint16_t sym):Maps a single symbol to the (larger) precision, linearly
- float getAveragePower()
- unsigned int forecast(unsigned int numOutputs)
- private:
- uint16_t m_highestInput:模块支持的最大的输入值
- Symbol* m_mappingTable:[(1 << inputNumBits) - 1] 长的数组,构造位于构造函数中
- float m_variance:输出符号的方差
NormalDistribution.h
:被 TruncatedNormalDistribution.cpp 包含,帮忙实现正太分布
- static double pdf(double u):Probability Density Function
- static double cdf(double u):Cumulative Distribution Function
- static double ppf(double p):Percentage Point Function
TruncatedNormalDistribution.h
:被 GaussianMapper.cpp 包含,生成一个(a,b)截断区间的高斯分布
- public:
- TruncatedNormalDistribution(double a, double b)
- double ppf(double p)
- double variance()
- private:
- double m_a
- double m_b
- double m_cdfOfA:The CDF of point a on a standard normal variable
GrayMapper.h
:使用 Gray code 将比特序列映射到 constellation,换汤不换药,不做详细介绍了 LinearMapper.h
:Maps integers to fixed-precision symbols,个人对 precision 的理解不是很好
- LinearMapper(unsigned int symbolSizeBits, unsigned int precisionBits):输入符号的精度,和信道要求的精度
- 其他部分同上
QamMapper.h
:使用了 IMapper,但程序中使用了 itpp::QAM,参考 binding 中的内容,此处可以作为了解 QPSKMapper.h
:使用了IMapper ,但程序中使用了 itpp::QPSK,参考 binding 中的内容,此处可以作为了解 SoftMapper.h
:不明确,参考 simulation 中的实验再回头看看。
3.4 include/demappers
说明:需要了解一些 map 和 demap 的方法
IDemapper.h
:Demapper 的接口模块,代码结构:
- virtual ~IDemapper() {}
- virtual void process(const std::vector< ChannelSymbol>& symbols, N0_t n0, std::vector< LLRValue>& llrs) = 0:将接受符号解调为 soft bit values,理解不是很好
- virtual void process(const std::vector< ChannelSymbol>& symbols, const std::vector< FadingMagnitude>& fadingMagnitude, N0_t n0, std::vector< LLRValue>& llrs) = 0:将接受符号解调为 soft bit values,且每个符号有不同的噪声值
- virtual unsigned int forecast(unsigned int numOutputs) = 0
BitwiseDemapper.h
:通过枚举星座图上的点,来解星座映射,找到最大似然的点解调
BitwiseDemapper.hh
:楼上的实现函数
BscDemapper.h
:比特翻转 BSC 信道解调 ItppDemapper.h
:继承 IDemapper,相比之下只有参数不太一样 ,IT++ Modulator 和 IDemapper 之间的适配器
- public:
- ItppDemapper(ModulatorPtr& modulator, unsigned int forecastFactor, bool useApprox):
- virtual ~ItppDemapper() {}
- virtual void process(const std::vector< ChannelSymbol>& symbols, N0_t n0, std::vector< LLRValue>& llrs)
- virtual void process(const std::vector< ChannelSymbol>& symbols, const std::vector< FadingMagnitude>& fadingMagnitude, N0_t n0, std::vector< LLRValue>& llrs):
- virtual unsigned int forecast(unsigned int numOutputs)
- private:
- ModulatorPtr m_modulator
- const unsigned int m_forecastFactor
- itpp::Soft_Method m_softMethod
ItppDemapper.hh
:楼上的实现
NullDemapper.h
:不调制,不解调
3.5 include/protocols
说明:给出了两种编码符号的传输方案,回头仿真时时再好好研究每个函数的功能。
注意:还有第三种传输方案,位于 pythonprotocols/MultipleTryProtocol.py 中。
另外:Spinal Codes 的 protocol 定义在 Spinal Codes 本身中,当使用 Simulator 做仿真时,只要定义了 Spinal,protocol 就会使用 Spinal 中的,位于 include/codes/spinal/protocols 中
OneTryProtocol.h
:一次性发送所有的编码符号
- public:
- OneTryProtocol(unsigned int numPackets, unsigned int numSymbols)
- unsigned int numSymbolsNextDecode(unsigned int packetInd)
- void setResult(unsigned int packetInd, unsigned int numSymbols, bool isFinished)
- void resetPacket(unsigned int packetInd)
- private:
- unsigned int m_numSymbols
- vector< unsigned int> m_nextDecode
RateApproxProtocol.h
:自适应码率传输,怕理解不好,直接引用原文:
Attempts a sequence of rates, to find a rate up to (1+delta) factor from the minimal possible rate for the channel.
A protocol that tries rates such that the spacing between rates is at most a given constant factor ‘delta’. This means that if a system achieves a rate R, then the protocol will at the worst case try rate R * delta.
- public:
- RateApproxProtocol( unsigned int numPackets, unsigned int maxSymbols, float delta, uint32_t minSymbols)
- unsigned int numSymbolsNextDecode(unsigned int packetInd)
- void setResult(unsigned int packetInd, unsigned int numSymbols, bool isFinished)
- void resetPacket(unsigned int packetInd)
- private:
- const unsigned int m_maxSymbols
- const float m_oneOverDelta
- const unsigned int m_minSymbols
- std::vector< unsigned int> m_nextNumSymbols
3.6 include/util
说明:很重要,给出了差错控制编码和信道的实现的基础函数,实现了工程中大部分的基础算法
Spinal Codes 说明:基于 hash 函数算法的差错控制编码,在使用是请注意区分 symbol,state,hash digest 的概念
util/hashes
说明:分为三个部分介绍,一部分是 hash 函数 的“生产”方式;另一种是,hash 函数算法的具体实现;然后是,hash 函数的 Python 接口
hash 函数的顶层模板类:
UnlimitedHash.h
(重要):较为常用的类,实现一个可以生成 16-bit 的 stream 的 hash 函数UnlimitedHash.hh
:IMPLEMENTATION OFUnlimitedHash.h
INLINE FUNCTIONS.UnlimitedHash(const Seed prevSeed, uint32_t data)
:初始化void hash(uint32_t data)
:Hash the internal seed with an external 32-bit word is done with hash().Seed getSeed()
:The internal state (the “seed”) can be retrieved using getSeed().uint16_t next()
:The stream of 16-bit values is produced by iteratively calling nextBits().
SingleSymbolFunction.h
:从当前的 hash digest 中取出编码符号,相当与一个小型的生产 hash 函数的工厂,可以让用户不必知道内部算法而直接使用ShiftRegisterAdaptorHash.h
:An adaptor class that allows updates bit-by-bit, then hashes the entire state.(没有用到,没有细看)
hash 函数的实现:
BitwiseXor.h
:32-bit-state 的 XOR 更新操作,类声明,实现位于文件src/util/hashes/BitwiseXor.cpp
Lookup3Hash.h
:实现了Bob Jenkin’s lookup3 算法,此处为类声明,实现位于src/util/hash/Lookup3Hash.cpp
中,包括:- Lookup3Hash 类:Implementation of Bob Jenkin’s lookup3 hash function.
- Lookup3SymbolFunction 类:Produces symbols from the digest of a Lookup3Hash,相当于Spinal Codes中提到的 RNG 的作用,即取 32-bit-state 的 16-bit 移位
OneAtATimeHash.h
:实现了Bob Jenkin’s one-at-a-time 算法,实现部分位于src/util/hashes/OneAtATimeHash.cpp
salsa20.h
:Salsa20 算法中使用到的类型和函数的定义SalsaHash.h
:Salsa20 算法的实现类,结构基本与Lookup3Hash.h
相同ecrypt-config.h
:源自于 Salsa20 算法,请勿改动ecrypt-machine.h
:源自于 Salsa20 算法,请勿改动ecrypt-portable.h
:源自于 Salsa20 算法,请勿改动
hash 函数的 Python 接口:
SWIGHash.h
:配合bindings/util/hashes.i
中%pythoncode %{ %}
使用,使用方法为,在 Python 环境下按如下方式,即可调用封装好的 hash 函数:
import wireless.util.hashes as hashhash_func = hash.OneAtATimeHash_init()
util/inference
说明:给出了两种译码时用到的推到方式,一种是基于置信度的 BP 法,另一种是基于状态图的搜索算法。
- bp:LDPC 译码中使用,这里先不做介绍
BipartiteBP.h
BipartiteGraph.h
BPMessage.h
ElementHeap.h
LinearVariableNodeUpdater.h
MessagePassingDecoder.h
MessagePassingDecoder.hh
MultiStack.h
MultiVector.h
NodeUpdater.h
hmm:广义来说这些搜索方法是可以算作是 HMM 的,作者这样命名也不无道理
LookaheadBeamSearch.h
:A beam search, with lookahead.LookaheadAdaptor.h
:BeamSearch.h
:A generic implementation of beam search exploration.Backtracker.h
:BestK.h
:DualPool.h
:
IPruner.h
:return: true if the node might be added, false if the node has been pruned.ParallelBestK.h
:Collection of several BestK lists, insertions round-robin within the collection.
util/Utils.h
:不同的 bit / string / likelihood 之间的转换,其中的类方法均为静态方法 ,以便在只定义类的情况下也能够调用类方法,而不需将其实例化util/ItppUtils.h
:实现 string 与 itpp bvec 之间的转换util/BitStatCounter.h
:统计多个字符串中“1”出现的次数util/BlockStatCounter.h
:统计一个长为 k 的 block 非零的次数util/crc.h
:实现了 crc16 和 crc32util/MTRand.h
:MersenneTwister 随机数生成
3.7 include/*.h
说明:定义了一些包括 代码符号定义规则,变换的级联,两种检测译码是否正确的方法(crc,oracle),包生成
代码符号定义规则:
include/CodeBench.h
:C++ 部分的编码标准,给出了一些 typedef 和 define 等,注意如果在这里进行了修改,那么./binding
中的相关内容也要修改,对应的封装在bindings/general.i
中,如需要请向前查阅
变换的级联:
include/ComposedTransformation.h
:ComposedTransformation2 类的声明和实现,将两种变换组合为一种变换,包括 constructor,transform,forecast 方法,可以理解为变换的级联吧。include/TransformationAdaptor.h
:貌似没怎么用过,且文件中有详细表述,等遇到了再做研究
检测译码是否正确:
include/CrcDetector.h
:CRC -16的检测模块的声明和实现,包括 CrcDetector() / setPacket() / isFinished() 方法,由 CrcPacketGenerator 生成的数据包的正确性。检测方法是使用接收的数据(这里一般为译码后的结果)的除了前两个字节之外的其他部分生成的CRC值和前两个字节的值想对比,若相等则isFinished=True
include/OracleDetector.h
:将译码后得到的result
数据结构中的 packet 和 与之相对的发送的 packet 做对比,以判断译码是否成功,包括 OracleDetector,setPacket,isFinished 方法
数据包生成:
include/PacketGenerator.h
:生成随机的数据包,包括PacketGenerator,seed,get 方法,实现部分在src/PacketGenerator.cpp
include/CrcPacketGenerator.h
:实现了使用include/util/crc.h
中的CRC-16 查表算法,生成带有CRC头(位于数据包的前两个字节)的数据包,实现部分在src/CrcPacketGenerator.cpp
中,包括 CrcPacketGenerator,seed,get,这里要注意生成的是完整的包而不是根据包生成头
4 src
说明:大部分功能模块的实现(.cpp),在
include
(上一节)中顺带说明,不做单独介绍
5 .metadata
说明:不知道是什么
6 .settings
说明:eclipse的设置记录
7 autom4te.cache
说明:不知道是什么
8 build-aux
说明:存放了一些m4的辅助宏
9 data
说明:LDPC的编码结果
10 doc
说明:Doxyfile文档
11 lablog
说明:
12 release
说明:
13 test
说明:
14 util
- libwireless 源码解析
- 源码解析
- 源码解析
- 【JDk源码解析之一】ArrayList源码解析
- 【源码解析】-- ArrayList的源码解析
- EventBus源码解析(史上最全的源码解析)
- 【源码】Vector、Stack源码解析
- Sping源码解析-源码下载
- <Android源码>IntentService源码解析
- JAVA源码解析-String源码
- JAVA源码解析-ArrayList源码
- JAVA源码解析-LinkedList源码
- Spark源码-SparkContext源码解析
- Jboss源码解析
- 网页病毒源码解析
- strlen源码解析
- chrome源码解析系列
- gnash源码解析
- 关于PDO--数据库抽象层
- 2016 腾讯笔试题 最长回文字串(不连续)(dp)
- POJ2376-Cleaning Shifts
- Spark Streaming + kafka
- [2016-4-4]实验三要求已上传,请提前编写程序
- libwireless 源码解析
- Oracle Multitenant Option - 12c Frequently Asked Questions
- 12个球一个天平,现知道只有一个和其它的重量不同,问怎样称才能用三次就找到那个球。13个呢?(注意此题并未说明那个球的重量是轻是重,所以需要仔细考虑)
- linux目录说明
- Android Converty问题解决方案
- leetcode 链表排序
- IDEA UL 打开 MyEclipse工程几个关键的设置
- JavaScript滑动门特效
- 献给和我合作的过得前端童靴们:jquery源码分析--序4