mirror of
https://github.com/Show-maket/IR-protocol.git
synced 2026-04-28 03:08:08 +00:00
Analyzer plug
This commit is contained in:
200
Analyzer/raw/IR_Fox/src/IrFoxAnalyzer.cpp
Normal file
200
Analyzer/raw/IR_Fox/src/IrFoxAnalyzer.cpp
Normal file
@ -0,0 +1,200 @@
|
||||
#include "IrFoxAnalyzer.h"
|
||||
#include "IrFoxAnalyzerSettings.h"
|
||||
#include "IrFoxDecoder.h"
|
||||
#include <AnalyzerChannelData.h>
|
||||
#include <AnalyzerResults.h>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
IrFoxAnalyzer::IrFoxAnalyzer()
|
||||
: Analyzer2(),
|
||||
mSettings(),
|
||||
mSimulationInitilized(false)
|
||||
{
|
||||
SetAnalyzerSettings(&mSettings);
|
||||
UseFrameV2();
|
||||
}
|
||||
|
||||
IrFoxAnalyzer::~IrFoxAnalyzer()
|
||||
{
|
||||
KillThread();
|
||||
}
|
||||
|
||||
void IrFoxAnalyzer::SetupResults()
|
||||
{
|
||||
m_packet_hex_by_frame.clear();
|
||||
mResults.reset(new IrFoxAnalyzerResults(this, &mSettings));
|
||||
SetAnalyzerResults(mResults.get());
|
||||
mResults->AddChannelBubblesWillAppearOn(mSettings.mInputChannel);
|
||||
}
|
||||
|
||||
static void append_hex(std::string& s, const uint8_t* p, size_t n, size_t max_bytes = 64)
|
||||
{
|
||||
static const char* hd = "0123456789abcdef";
|
||||
const size_t m = n < max_bytes ? n : max_bytes;
|
||||
for (size_t i = 0; i < m; i++)
|
||||
{
|
||||
s.push_back(hd[p[i] >> 4]);
|
||||
s.push_back(hd[p[i] & 0xFu]);
|
||||
if (i + 1 < m)
|
||||
s.push_back(' ');
|
||||
}
|
||||
if (n > max_bytes)
|
||||
s += "...";
|
||||
}
|
||||
|
||||
const char* IrFoxAnalyzer::PacketHexForFrame(U64 frame_id)
|
||||
{
|
||||
auto it = m_packet_hex_by_frame.find(frame_id);
|
||||
if (it == m_packet_hex_by_frame.end())
|
||||
return "";
|
||||
m_hex_scratch = it->second;
|
||||
return m_hex_scratch.c_str();
|
||||
}
|
||||
|
||||
const char* IrFoxAnalyzer::BubbleTextForFrame(U64 frame_id) const
|
||||
{
|
||||
auto it = m_bubble_text_by_frame.find(frame_id);
|
||||
if (it == m_bubble_text_by_frame.end())
|
||||
return "";
|
||||
m_bubble_scratch = it->second;
|
||||
return m_bubble_scratch.c_str();
|
||||
}
|
||||
|
||||
void IrFoxAnalyzer::WorkerThread()
|
||||
{
|
||||
mIr = GetAnalyzerChannelData(mSettings.mInputChannel);
|
||||
m_packet_hex_by_frame.clear();
|
||||
m_bubble_text_by_frame.clear();
|
||||
|
||||
const U32 fs = GetSampleRate();
|
||||
IrFoxDecoder decoder;
|
||||
decoder.reset();
|
||||
|
||||
U32 frames_since_commit = 0;
|
||||
const U32 kCommitBatch = 256;
|
||||
|
||||
IrFoxOnBit on_bit = [&](const IrFoxEmitBit& e) {
|
||||
Frame frame;
|
||||
frame.mStartingSampleInclusive = static_cast<S64>(e.start_sample);
|
||||
frame.mEndingSampleInclusive = static_cast<S64>(e.end_sample);
|
||||
frame.mType = e.frame_type;
|
||||
frame.mData1 = e.bit_value;
|
||||
frame.mData2 = e.bit_index | (U64(e.err_low) << 16) | (U64(e.err_high) << 24) | (U64(e.err_other) << 32);
|
||||
frame.mFlags = e.mflags;
|
||||
// В SDK только ERROR/WARNING меняют цвет бабла; sync выделяем янтарным (как warning), данные — обычные.
|
||||
if (e.frame_type == IRF_FT_SYNC_BIT)
|
||||
frame.mFlags |= DISPLAY_AS_WARNING_FLAG;
|
||||
|
||||
const U64 fid = mResults->AddFrame(frame);
|
||||
if (e.bubble_text[0] != '\0')
|
||||
m_bubble_text_by_frame[fid] = e.bubble_text;
|
||||
if (++frames_since_commit >= kCommitBatch)
|
||||
{
|
||||
mResults->CommitResults();
|
||||
frames_since_commit = 0;
|
||||
}
|
||||
};
|
||||
|
||||
IrFoxOnPacket on_pkt = [&](const IrFoxEmitPacket& p) {
|
||||
Frame frame;
|
||||
frame.mStartingSampleInclusive = static_cast<S64>(p.start_sample);
|
||||
frame.mEndingSampleInclusive = static_cast<S64>(p.end_sample);
|
||||
frame.mType = p.crc_ok ? IRF_FT_PACKET_OK : IRF_FT_PACKET_CRC_FAIL;
|
||||
frame.mData1 = p.pack_size;
|
||||
frame.mData2 = (U64(p.err_low) << 0) | (U64(p.err_high) << 8) | (U64(p.err_other) << 16);
|
||||
if (!p.crc_ok)
|
||||
frame.mFlags |= DISPLAY_AS_ERROR_FLAG;
|
||||
|
||||
const U64 fid = mResults->AddFrame(frame);
|
||||
|
||||
std::string hx;
|
||||
append_hex(hx, p.data_bytes, p.pack_size);
|
||||
m_packet_hex_by_frame[fid] = std::move(hx);
|
||||
|
||||
FrameV2 fv2;
|
||||
fv2.AddBoolean("crc_ok", p.crc_ok);
|
||||
fv2.AddInteger("len", static_cast<S64>(p.pack_size));
|
||||
fv2.AddInteger("err_low", static_cast<S64>(p.err_low));
|
||||
fv2.AddInteger("err_high", static_cast<S64>(p.err_high));
|
||||
fv2.AddInteger("err_other", static_cast<S64>(p.err_other));
|
||||
fv2.AddByteArray("data", p.data_bytes, p.pack_size);
|
||||
mResults->AddFrameV2(fv2, p.crc_ok ? "packet_ok" : "packet_bad", static_cast<U64>(p.start_sample),
|
||||
static_cast<U64>(p.end_sample));
|
||||
|
||||
if (++frames_since_commit >= kCommitBatch)
|
||||
{
|
||||
mResults->CommitResults();
|
||||
frames_since_commit = 0;
|
||||
}
|
||||
};
|
||||
|
||||
for (;;)
|
||||
{
|
||||
CheckIfThreadShouldExit();
|
||||
|
||||
const U64 segment_start = mIr->GetSampleNumber();
|
||||
const BitState level = mIr->GetBitState();
|
||||
|
||||
mIr->AdvanceToNextEdge();
|
||||
|
||||
const U64 edge_sample = mIr->GetSampleNumber();
|
||||
if (edge_sample == segment_start)
|
||||
break;
|
||||
|
||||
const BitState new_level = mIr->GetBitState();
|
||||
const bool rising = (new_level == BIT_HIGH);
|
||||
|
||||
decoder.processEdge(edge_sample, rising, fs, on_bit, on_pkt);
|
||||
ReportProgress(edge_sample);
|
||||
}
|
||||
|
||||
decoder.flushEnd(mIr->GetSampleNumber(), fs, on_bit, on_pkt);
|
||||
|
||||
if (frames_since_commit != 0)
|
||||
mResults->CommitResults();
|
||||
}
|
||||
|
||||
bool IrFoxAnalyzer::NeedsRerun()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
U32 IrFoxAnalyzer::GenerateSimulationData(U64 minimum_sample_index, U32 device_sample_rate,
|
||||
SimulationChannelDescriptor** simulation_channels)
|
||||
{
|
||||
if (mSimulationInitilized == false)
|
||||
{
|
||||
mSimulationDataGenerator.Initialize(GetSimulationSampleRate(), &mSettings);
|
||||
mSimulationInitilized = true;
|
||||
}
|
||||
|
||||
return mSimulationDataGenerator.GenerateSimulationData(minimum_sample_index, device_sample_rate,
|
||||
simulation_channels);
|
||||
}
|
||||
|
||||
U32 IrFoxAnalyzer::GetMinimumSampleRateHz()
|
||||
{
|
||||
return 200000;
|
||||
}
|
||||
|
||||
const char* IrFoxAnalyzer::GetAnalyzerName() const
|
||||
{
|
||||
return "IR Fox";
|
||||
}
|
||||
|
||||
const char* GetAnalyzerName()
|
||||
{
|
||||
return "IR Fox";
|
||||
}
|
||||
|
||||
Analyzer* CreateAnalyzer()
|
||||
{
|
||||
return new IrFoxAnalyzer();
|
||||
}
|
||||
|
||||
void DestroyAnalyzer(Analyzer* analyzer)
|
||||
{
|
||||
delete analyzer;
|
||||
}
|
||||
Reference in New Issue
Block a user