Rewrote scanning algo for bins of bandwidth
This commit is contained in:
parent
9dbf2fb763
commit
621f2810ab
|
|
@ -17,7 +17,7 @@
|
|||
using namespace piscan;
|
||||
|
||||
ScannerSM::ScannerSM(MessageReceiver& central, SystemList& dataSource) :
|
||||
StateMachine(7), _centralQueue(central), _systems(dataSource), _currentSystem(nullptr), _currentEntry(nullptr) {
|
||||
StateMachine(7), _centralQueue(central), _systems(dataSource) {
|
||||
}
|
||||
|
||||
void ScannerSM::startScan(){
|
||||
|
|
@ -82,7 +82,8 @@ void ScannerSM::ST_Load(EventData* data){
|
|||
generator->generateSystemList(_systems);
|
||||
LOG_F(INFO, "Loaded %u systems", _systems.size());
|
||||
|
||||
_currentSystem = _systems[0];
|
||||
//_currentSystem = _systems[0];
|
||||
_systems.sortBins(2000000);
|
||||
|
||||
// do not issue event - SM will wait until an event is generated before proceeding
|
||||
//InternalEvent(ST_SCAN);
|
||||
|
|
@ -107,22 +108,24 @@ void ScannerSM::ST_Scan(EventData* data){
|
|||
|
||||
// incremental scan pattern
|
||||
if(!_squelchHits || (currentState != lastState)){
|
||||
_entryCounter = (_entryCounter + 1) % _currentSystem->size();
|
||||
//_entryCounter = (_entryCounter + 1) % _currentSystem->size();
|
||||
|
||||
|
||||
|
||||
if(_entryCounter == 0){
|
||||
_sysCounter = (_sysCounter + 1) % _systems.size();
|
||||
// if(_entryCounter == 0){
|
||||
// _sysCounter = (_sysCounter + 1) % _systems.size();
|
||||
//
|
||||
// _currentSystem = _systems[_sysCounter];
|
||||
// assert(_currentSystem != nullptr);
|
||||
//
|
||||
// //_broadcastContextUpdate();
|
||||
// }
|
||||
|
||||
_currentSystem = _systems[_sysCounter];
|
||||
assert(_currentSystem != nullptr);
|
||||
//CHECK_F(_currentSystem->size() > 0);
|
||||
//_currentEntry = _currentSystem->operator[](_entryCounter);
|
||||
//CHECK_F(_currentEntry != NULL);
|
||||
|
||||
//_broadcastContextUpdate();
|
||||
}
|
||||
|
||||
CHECK_F(_currentSystem->size() > 0);
|
||||
_currentEntry = _currentSystem->operator[](_entryCounter);
|
||||
CHECK_F(_currentEntry != NULL);
|
||||
_currentEntry = _systems.getNextEntry();
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -216,15 +219,16 @@ void ScannerSM::ST_Manual(EventData* data){
|
|||
LOG_F(1, "Setting manual frequency to %.4lfMHz", (*freq / 1E6));
|
||||
|
||||
/* delete old manual entry */
|
||||
if(_manualEntry != nullptr)
|
||||
delete _manualEntry;
|
||||
//if(_manualEntry != nullptr)
|
||||
//delete _manualEntry;
|
||||
|
||||
_manualEntry = new FMChannel(*freq, "", false, false);
|
||||
_manualEntry = std::make_shared<FMChannel>(*freq, "", false, false);
|
||||
delete freq;
|
||||
_currentEntry = _manualEntry;
|
||||
_externalHold = true;
|
||||
_manualMode = true;
|
||||
InternalEvent(ST_HOLD);
|
||||
|
||||
}
|
||||
|
||||
void ScannerSM::ST_SaveAll(EventData* data){
|
||||
|
|
@ -257,9 +261,10 @@ void ScannerSM::_broadcastContextUpdate() {
|
|||
}
|
||||
else
|
||||
{
|
||||
_currentContext.systemTag = _currentSystem->tag();
|
||||
//_currentContext.systemTag = _currentSystem->tag();
|
||||
_currentContext.systemTag = _systems[_currentEntry->getSysIndex()]->tag();
|
||||
_currentContext.entryTag = _currentEntry->tag();
|
||||
_currentContext.entryIndex = std::to_string(_sysCounter) + "-" + std::to_string(_entryCounter);
|
||||
_currentContext.entryIndex = std::to_string(_currentEntry->getSysIndex()) + "-" + std::to_string(_currentEntry->getEntryIndex());
|
||||
}
|
||||
_currentContext.frequency = _currentEntry->freq();
|
||||
_currentContext.modulation = _currentEntry->modulation();
|
||||
|
|
|
|||
|
|
@ -65,10 +65,10 @@ private:
|
|||
MessageReceiver& _centralQueue;
|
||||
//moodycamel::ReaderWriterQueue<Message> _msgQueue;
|
||||
SystemList& _systems;
|
||||
RadioSystem* _currentSystem;
|
||||
Entry* _currentEntry;
|
||||
Entry* _manualEntry = nullptr;
|
||||
size_t _sysCounter = 0, _entryCounter = 0;
|
||||
//RadioSystem* _currentSystem;
|
||||
std::shared_ptr<Entry> _currentEntry;
|
||||
std::shared_ptr<Entry> _manualEntry;
|
||||
//size_t _sysCounter = 0, _entryCounter = 0;
|
||||
ScannerContext _currentContext;
|
||||
std::mutex _contextMutex;
|
||||
|
||||
|
|
|
|||
|
|
@ -45,13 +45,14 @@ protected:
|
|||
void ExternalEvent(unsigned char, EventData* = NULL);
|
||||
void InternalEvent(unsigned char, EventData* = NULL);
|
||||
virtual const StateStruct* GetStateMap() = 0;
|
||||
std::thread _stateMachineThread;
|
||||
private:
|
||||
const int _maxStates;
|
||||
bool _eventGenerated;
|
||||
EventData* _pEventData;
|
||||
void StateEngine(void);
|
||||
void StateThreadFunc(void);
|
||||
std::thread _stateMachineThread;
|
||||
|
||||
std::mutex _eventMutex;
|
||||
std::condition_variable _cv;
|
||||
bool _run = false;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,13 @@ using namespace piscan;
|
|||
|
||||
DemodInterface* Entry::demod = nullptr;
|
||||
|
||||
bool DummyChannel::hasSignal(){
|
||||
if(!demod->setFrequency(this->frequency))
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FMChannel::hasSignal(void){
|
||||
assert(demod != nullptr);
|
||||
|
||||
|
|
|
|||
|
|
@ -25,13 +25,19 @@ public:
|
|||
bool useDelay() { return _scanDelay; }
|
||||
void lockout(bool val = true) { _lockedOut = val; }
|
||||
virtual bool hasSignal() = 0;
|
||||
virtual unsigned long freq() = 0;
|
||||
virtual long freq() = 0;
|
||||
|
||||
size_t getSysIndex() { return _sysIndex; };
|
||||
void setSysIndex(size_t index) { _sysIndex = index; };
|
||||
size_t getEntryIndex() { return _entryIndex; };
|
||||
void setEntryIndex(size_t index) { _entryIndex = index; };
|
||||
|
||||
private:
|
||||
std::string _tag;
|
||||
bool _lockedOut;
|
||||
bool _scanDelay;
|
||||
|
||||
size_t _sysIndex = 0;
|
||||
size_t _entryIndex = 0;
|
||||
protected:
|
||||
static DemodInterface* demod;
|
||||
friend void setDemodulator(DemodInterface* demod);
|
||||
|
|
@ -39,16 +45,29 @@ protected:
|
|||
|
||||
class Channel: public Entry {
|
||||
public:
|
||||
Channel(unsigned long freq, std::string tag, bool lo, bool del) : Entry(tag, lo, del), frequency(freq){}
|
||||
Channel(long freq, std::string tag, bool lo, bool del) : Entry(tag, lo, del), frequency(freq){}
|
||||
virtual ~Channel() {};
|
||||
virtual unsigned long freq() { return frequency; };
|
||||
virtual long freq() { return frequency; };
|
||||
protected:
|
||||
const unsigned long frequency;
|
||||
const long frequency;
|
||||
|
||||
};
|
||||
|
||||
class DummyChannel: public Channel {
|
||||
public:
|
||||
DummyChannel(long freq) : Channel(freq, "", false, false){
|
||||
|
||||
}
|
||||
~DummyChannel(){};
|
||||
|
||||
std::string modulation() { return ""; };
|
||||
|
||||
bool hasSignal();
|
||||
};
|
||||
|
||||
class FMChannel : public Channel {
|
||||
public:
|
||||
FMChannel(unsigned long freq, std::string tag, bool lo, bool del) : Channel(freq, tag, lo, del){}
|
||||
FMChannel(long freq, std::string tag, bool lo, bool del) : Channel(freq, tag, lo, del){}
|
||||
~FMChannel() {};
|
||||
|
||||
std::string modulation() {
|
||||
|
|
@ -60,7 +79,7 @@ public:
|
|||
|
||||
class PLChannel: public FMChannel {
|
||||
public:
|
||||
PLChannel(unsigned long freq, float tn, std::string tag, bool lo, bool del) :
|
||||
PLChannel(long freq, float tn, std::string tag, bool lo, bool del) :
|
||||
FMChannel(freq, tag, lo, del), tone(tn) {
|
||||
}
|
||||
~PLChannel() {};
|
||||
|
|
@ -72,7 +91,7 @@ protected:
|
|||
|
||||
class DCChannel : public FMChannel {
|
||||
public:
|
||||
DCChannel(unsigned long freq, unsigned int tn, std::string tag, bool lo, bool del) :
|
||||
DCChannel(long freq, unsigned int tn, std::string tag, bool lo, bool del) :
|
||||
FMChannel(freq, tag, lo, del), code(tn) {
|
||||
}
|
||||
~DCChannel() {};
|
||||
|
|
@ -84,7 +103,7 @@ protected:
|
|||
|
||||
class AMChannel : public Channel {
|
||||
public:
|
||||
AMChannel(unsigned long freq, std::string tag, bool lo, bool del) : Channel(freq, tag, lo, del){}
|
||||
AMChannel(long freq, std::string tag, bool lo, bool del) : Channel(freq, tag, lo, del){}
|
||||
~AMChannel() {};
|
||||
|
||||
bool hasSignal() { return false; };
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ public:
|
|||
void generateSystemList(SystemList& list);
|
||||
|
||||
private:
|
||||
SystemList* _list;
|
||||
RadioSystem* _system;
|
||||
SystemList* _list = nullptr;
|
||||
std::shared_ptr<RadioSystem> _system;
|
||||
|
||||
void _newAnalogSys(std::vector<std::string>& tokens);
|
||||
void _newAnalogEntry(std::vector<std::string>& tokens);
|
||||
|
|
|
|||
|
|
@ -26,13 +26,13 @@ public:
|
|||
RadioSystem(std::string tag, bool lo) : _tag(tag), _lockout(lo) {};
|
||||
virtual ~RadioSystem() {};
|
||||
|
||||
virtual Entry* operator[](size_t pos) = 0;
|
||||
virtual std::shared_ptr<Entry> operator[](size_t pos) = 0;
|
||||
|
||||
virtual size_t size() { return numEntries; }
|
||||
|
||||
std::string tag() { return _tag; };
|
||||
|
||||
virtual void addEntry(Entry* entry) = 0;
|
||||
virtual void addEntry(std::shared_ptr<Entry> entry) = 0;
|
||||
private:
|
||||
//const RadioSystemType type;
|
||||
const std::string _tag;
|
||||
|
|
@ -47,13 +47,13 @@ public:
|
|||
AnalogSystem(std::string tag, bool lo) : RadioSystem(tag, lo) {};
|
||||
~AnalogSystem() {};
|
||||
|
||||
virtual Entry* operator[](size_t pos) { return entries[pos]; };
|
||||
virtual std::shared_ptr<Entry> operator[](size_t pos) { return entries[pos]; };
|
||||
|
||||
/*virtual size_t size() {
|
||||
return entries.size();
|
||||
}*/
|
||||
|
||||
virtual void addEntry(Entry* entry){
|
||||
virtual void addEntry(std::shared_ptr<Entry> entry){
|
||||
if(entry != nullptr){
|
||||
entries.push_back(entry);
|
||||
numEntries++;
|
||||
|
|
@ -61,7 +61,7 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
std::vector<Entry*> entries;
|
||||
std::vector<std::shared_ptr<Entry>> entries;
|
||||
};
|
||||
}
|
||||
#endif /* RADIOSYSTEM_H_ */
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ void SentinelFile::generateSystemList(SystemList& list) {
|
|||
std::string& type = tokens[0];
|
||||
if(!type.compare(C_GROUP))
|
||||
_newAnalogSys(tokens);
|
||||
else if(!type.compare(C_FREQ))
|
||||
else if(!type.compare(C_FREQ) && _system != nullptr)
|
||||
_newAnalogEntry(tokens);
|
||||
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ void SentinelFile::generateSystemList(SystemList& list) {
|
|||
|
||||
void SentinelFile::_newAnalogSys(std::vector<std::string>& tokens){
|
||||
LOG_F(4, "New AnalogSystem: %s", tokens[C_GROUP_TAG_POS].c_str());
|
||||
_system = new AnalogSystem(tokens[C_GROUP_TAG_POS], (!tokens[C_GROUP_LO_POS].compare(SENTINEL_TRUE)));
|
||||
_system = std::make_shared<AnalogSystem>(tokens[C_GROUP_TAG_POS], (!tokens[C_GROUP_LO_POS].compare(SENTINEL_TRUE)));
|
||||
_list->addSystem(_system);
|
||||
}
|
||||
|
||||
|
|
@ -102,8 +102,12 @@ void SentinelFile::_newAnalogEntry(std::vector<std::string>& tokens){
|
|||
LOG_F(4, "Entry: %s - Freq: %s", tag.c_str(), freq.c_str());
|
||||
|
||||
if(!mode.compare(SENTINEL_NFM) || !mode.compare(SENTINEL_FM) || !mode.compare(SENTINEL_AUTO)) {
|
||||
Entry* entry = new FMChannel(std::stoul(freq), tag,
|
||||
auto entry = std::make_shared<FMChannel>(std::stoul(freq), tag,
|
||||
(!lockout.compare(SENTINEL_TRUE)), (delay.compare("0")));
|
||||
|
||||
entry->setSysIndex(_list->size() - 1);
|
||||
entry->setEntryIndex(_system->size());
|
||||
|
||||
_system->addEntry(entry);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,3 +18,138 @@ SystemList::~SystemList() {
|
|||
// TODO Auto-generated destructor stub
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<Entry> SystemList::getNextEntry(){
|
||||
if(_entryNum == 0 && _retune){
|
||||
_retune = false;
|
||||
return std::make_shared<DummyChannel>(_bins[_binNum]->getCenterFreq());
|
||||
}
|
||||
|
||||
auto entry = _bins[_binNum]->operator [](_entryNum);
|
||||
|
||||
_entryNum = (_entryNum + 1) % _bins[_binNum]->size();
|
||||
|
||||
if(_entryNum == 0){
|
||||
_binNum = (_binNum + 1) % _bins.size();
|
||||
_retune = true;
|
||||
}
|
||||
|
||||
return entry;
|
||||
|
||||
}
|
||||
|
||||
void SystemList::sortBins(int bandwidth){
|
||||
size_t numEntries = 0;
|
||||
for(size_t i = 0; i < _systems.size(); i++)
|
||||
for(size_t k = 0; k < _systems[i]->size(); k++)
|
||||
numEntries++;
|
||||
std::shared_ptr<Entry> entries[numEntries];
|
||||
|
||||
numEntries = 0;
|
||||
|
||||
for(size_t i = 0; i < _systems.size(); i++)
|
||||
for(size_t k = 0; k < _systems[i]->size(); k++){
|
||||
//entries.push_back(_systems[i]->operator [](k));
|
||||
entries[numEntries] = _systems[i]->operator [](k);
|
||||
numEntries++;
|
||||
}
|
||||
|
||||
mergeSort(entries, 0, numEntries - 1);
|
||||
|
||||
std::shared_ptr<EntryBin> newBin = std::make_shared<EntryBin>();
|
||||
_bins.push_back(newBin);
|
||||
long lastFreq = 0;
|
||||
for(size_t i = 0; i < numEntries; i++){
|
||||
if(newBin->size() && entries[i]->freq() >= (newBin->front()->freq() + bandwidth)){
|
||||
newBin = std::make_shared<EntryBin>();
|
||||
_bins.push_back(newBin);
|
||||
}
|
||||
|
||||
if(entries[i]->freq() < lastFreq)
|
||||
LOG_F(WARNING, "Entries not sorted properly!");
|
||||
lastFreq = entries[i]->freq();
|
||||
newBin->push_back(entries[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void SystemList::merge(std::shared_ptr<Entry> arr[], int l, int m, int r)
|
||||
{
|
||||
int i, j, k;
|
||||
int n1 = m - l + 1;
|
||||
int n2 = r - m;
|
||||
|
||||
/* create temp arrays */
|
||||
std::shared_ptr<Entry> L[n1], R[n2];
|
||||
|
||||
/* Copy data to temp arrays L[] and R[] */
|
||||
for (i = 0; i < n1; i++)
|
||||
L[i] = arr[l + i];
|
||||
for (j = 0; j < n2; j++)
|
||||
R[j] = arr[m + 1+ j];
|
||||
|
||||
/* Merge the temp arrays back into arr[l..r]*/
|
||||
i = 0; // Initial index of first subarray
|
||||
j = 0; // Initial index of second subarray
|
||||
k = l; // Initial index of merged subarray
|
||||
while (i < n1 && j < n2)
|
||||
{
|
||||
if (static_cast<long>(L[i]->freq()) <= static_cast<long>(R[j]->freq()))
|
||||
{
|
||||
arr[k] = L[i];
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
arr[k] = R[j];
|
||||
j++;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
|
||||
/* Copy the remaining elements of L[], if there
|
||||
are any */
|
||||
while (i < n1)
|
||||
{
|
||||
arr[k] = L[i];
|
||||
i++;
|
||||
k++;
|
||||
}
|
||||
|
||||
/* Copy the remaining elements of R[], if there
|
||||
are any */
|
||||
while (j < n2)
|
||||
{
|
||||
arr[k] = R[j];
|
||||
j++;
|
||||
k++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* l is for left index and r is right index of the
|
||||
sub-array of arr to be sorted */
|
||||
void SystemList::mergeSort(std::shared_ptr<Entry> arr[], int l, int r)
|
||||
{
|
||||
if (l < r)
|
||||
{
|
||||
// Same as (l+r)/2, but avoids overflow for
|
||||
// large l and h
|
||||
int m = l+(r-l)/2;
|
||||
|
||||
// Sort first and second halves
|
||||
mergeSort(arr, l, m);
|
||||
mergeSort(arr, m+1, r);
|
||||
|
||||
merge(arr, l, m, r);
|
||||
}
|
||||
}
|
||||
|
||||
long SystemList::EntryBin::getCenterFreq(){
|
||||
if(this->size() > 1){
|
||||
long range = this->back()->freq() + this->front()->freq();
|
||||
return (range) / 2;
|
||||
}
|
||||
else
|
||||
return this->front()->freq();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,19 +19,39 @@ public:
|
|||
SystemList();
|
||||
~SystemList();
|
||||
|
||||
RadioSystem* operator[](size_t pos) { return _systems[pos]; };
|
||||
std::shared_ptr<RadioSystem> operator[](size_t pos) { return _systems[pos]; };
|
||||
|
||||
size_t size(){ return _systems.size(); }
|
||||
|
||||
void addSystem(RadioSystem& system){
|
||||
addSystem(&system);
|
||||
}
|
||||
void addSystem(RadioSystem* system) {
|
||||
void addSystem(std::shared_ptr<RadioSystem> system) {
|
||||
_systems.push_back(system);
|
||||
}
|
||||
|
||||
std::shared_ptr<Entry> getNextEntry();
|
||||
|
||||
void sortBins(int bandwidth);
|
||||
private:
|
||||
std::vector<RadioSystem*> _systems;
|
||||
|
||||
class EntryBin: public std::vector<std::shared_ptr<Entry>>{
|
||||
public:
|
||||
EntryBin(){};
|
||||
~EntryBin(){};
|
||||
|
||||
void sort();
|
||||
long getCenterFreq();
|
||||
};
|
||||
|
||||
|
||||
std::vector<std::shared_ptr<RadioSystem>> _systems;
|
||||
//size_t _size = 0;
|
||||
|
||||
std::vector<std::shared_ptr<EntryBin>> _bins;
|
||||
|
||||
size_t _binNum = 0, _entryNum = 0;
|
||||
bool _retune = true;
|
||||
|
||||
void merge(std::shared_ptr<Entry> arr[], int l, int m, int r);
|
||||
void mergeSort(std::shared_ptr<Entry> arr[], int l, int r);
|
||||
};
|
||||
}
|
||||
#endif /* SYSTEMLIST_H_ */
|
||||
|
|
|
|||
Loading…
Reference in New Issue