1
0
mirror of https://github.com/JvanKatwijk/dab-cmdline synced 2025-10-05 23:52:50 +02:00
Files
SDR-DAB_dab-cmdline/devices/xml-filereader-old/xml-descriptor.cpp
2025-03-17 19:03:03 +01:00

293 lines
11 KiB
C++

#
/*
* Copyright (C) 2014 .. 2019
* Jan van Katwijk (J.vanKatwijk@gmail.com)
* Lazy Chair Computing
*
* This file is part of eti-cmdline
*
* eti-cmdline is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* eti-cmdline is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with eti-cmdline; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "xml-descriptor.h"
#include "rapidxml.hpp"
using namespace rapidxml;
xmlDescriptor::~xmlDescriptor () {
}
void xmlDescriptor::printDescriptor () {
fprintf (stderr, "sampleRate = %d\n", sampleRate);
fprintf (stderr, "nrChannels = %d\n", nrChannels);
fprintf (stderr, "bitsperChannel = %d\n", bitsperChannel);
fprintf (stderr, "container = %s\n", container. c_str ());
fprintf (stderr, "byteOrder = %s\n",
byteOrder. c_str ());
fprintf (stderr, "iqOrder = %s\n",
iqOrder. c_str ());
fprintf (stderr, "nrBlocks = %d (%d)\n",
nrBlocks, (int)(blockList. size ()));
for (int i = 0; i < (int)blockList. size (); i ++)
fprintf (stderr, ">>> %d %d %s %d %s\n",
blockList. at (i). blockNumber,
blockList. at (i). nrElements,
blockList. at (i). typeofUnit. c_str (),
blockList. at (i). frequency,
blockList. at (i). modType. c_str ());
}
void xmlDescriptor::setSamplerate (int sr) {
this -> sampleRate = sr;
}
void xmlDescriptor::setChannels (int nrChannels,
int bitsperChannel,
std::string ct,
std::string byteOrder) {
this -> nrChannels = nrChannels;
this -> bitsperChannel = bitsperChannel;
this -> container = ct;
this -> byteOrder = byteOrder;
}
void xmlDescriptor::addChannelOrder (int channelOrder, std::string Value) {
if (channelOrder > 1)
return;
if (channelOrder == 0) // first element
this -> iqOrder = Value == "I" ? "I_ONLY" : "Q_ONLY";
else
if ((this -> iqOrder == "I_ONLY") && (Value == "Q"))
this -> iqOrder = "IQ";
else
if ((this -> iqOrder == "Q_ONLY") && (Value == "I"))
this -> iqOrder = "QI";
}
void xmlDescriptor::add_dataBlock (int currBlock, int Count,
int blockNumber, std::string Unit) {
Blocks b;
b. blockNumber = blockNumber;
b. nrElements = Count;
b. typeofUnit = Unit;
blockList. push_back (b);
}
void xmlDescriptor::add_freqtoBlock (int blockno, int freq) {
blockList. at (blockno). frequency = freq;
}
void xmlDescriptor::add_modtoBlock (int blockno, std::string modType) {
blockList. at (blockno). modType = modType;
}
//
// precondition: file exists and is readable.
// Note that after the object is filled, the
// file pointer points to where the contents starts
xmlDescriptor::xmlDescriptor (FILE *f, bool *ok) {
xml_document<> doc;
uint8_t theBuffer [10000];
int zeroCount = 0;
//
// set default values
sampleRate = 2048000;
nrChannels = 2;
bitsperChannel = 16;
container = "int16_t";
byteOrder = std::string ("MSB");
iqOrder ="IQ";
uint8_t theChar;
int index = 0;
while (zeroCount < 500) {
theChar = fgetc (f);
if (theChar == 0)
zeroCount ++;
else
zeroCount = 0;
theBuffer [index++] = theChar;
}
*ok = false;
doc. parse <0>((char *)theBuffer);
xml_node<> *root_node = doc. first_node ();
if (root_node == nullptr) {
fprintf (stderr, "failing to extract valid xml text\n");
return;
}
fprintf (stderr, "rootnode %s\n", root_node -> name ());
xml_node<> *node = root_node -> first_node ();
while (node != nullptr) {
if (std::string (node -> name ()) == "Recorder") {
for (xml_attribute<>*attr = node -> first_attribute ();
attr;attr = attr -> next_attribute ()) {
if (std::string (attr -> name ()) == "Name")
this -> recorderName = std::string (attr -> value ());
if (std::string (attr -> name ()) == "Version")
this -> recorderVersion = std::string (attr -> value ());
}
}
if (std::string (node -> name ()) == "Device") {
for (xml_attribute<>*attr = node -> first_attribute ();
attr;attr = attr -> next_attribute ()) {
if (std::string (attr -> name ()) == "Name")
this -> deviceName = std::string (attr -> value ());
if (std::string (attr -> name ()) == "Model")
this -> deviceModel = std::string (attr -> value ());
}
}
if (std::string (node -> name ()) == "Time") {
for (xml_attribute<>*attr = node -> first_attribute ();
attr;attr = attr -> next_attribute ()) {
if (std::string (attr -> name ()) == "Value")
this -> recordingTime = std::string (attr -> value ());
}
}
if (std::string (node -> name ()) == "Sample") {
xml_node<>* subNode = node -> first_node ();
while (subNode != nullptr) {
if (std::string (subNode -> name ()) == "Samplerate") {
std::string SR = "2048000";
std::string Hz = "Hz";
for (xml_attribute<>* attr = node -> first_attribute ();
attr; attr = attr -> next_attribute ()) {
if (std::string (attr -> name ()) == "Value")
SR = std::string (attr -> value ());
if (std::string (attr -> name ()) == "Unit") {
Hz = std::string (attr -> value ());
int factor = Hz == "Hz" ? 1 :
(Hz == "KHz") || (Hz == "Khz") ? 1000 :
1000000;
setSamplerate (std::stoi (SR) * factor);
}
}
}
if (std::string (subNode -> name ()) == "Channels") {
std::string Amount = "2";
std::string Bits = "16";
std::string Container = "uint8";
std::string Ordering = "N/A";
for (xml_attribute<>* attr = subNode -> first_attribute ();
attr; attr = attr -> next_attribute ()) {
if (std::string (attr -> name ()) == "Amount")
Amount = std::string (attr -> value ());
if (std::string (attr -> name ()) == "Bits")
Bits = std::string (attr -> value ());
if (std::string (attr -> name ()) == "Container")
Container = std::string (attr -> value ());
if (std::string (attr -> name ()) == "Ordering")
Ordering = std::string (attr -> value ());
}
setChannels (std::stoi (Amount),
std::stoi (Bits),
Container,
Ordering);
xml_node <>* subsubNode = subNode -> first_node ();
int channelOrder = 0;
while (subsubNode != nullptr) {
if (std::string (subsubNode -> name ()) == "Channel") {
std::string Value = "I/Q";
xml_attribute <>* attr =
subsubNode -> first_attribute ();
if (std::string (attr -> name ()) == "Value")
Value = std::string (attr -> value ());
addChannelOrder (channelOrder, Value);
channelOrder ++;
}
subsubNode = subsubNode -> next_sibling ();
}
}
subNode = subNode -> next_sibling ();
}
}
if (std::string (node -> name ()) == "Datablocks") {
this -> nrBlocks = 0;
int currBlock = 0;
xml_node<>* subNode = node -> first_node ();
while (subNode != nullptr) {
if (std::string (subNode -> name ()) == "Datablock") {
fprintf (stderr, "Datablock detected\n");
std::string Count = "100";
std::string Number = "10";
std::string Unit = "Channel";
for (xml_attribute<>* attr = subNode -> first_attribute ();
attr; attr = attr -> next_attribute ()) {
fprintf (stderr, "attribute %s (%s)\n",
attr -> name (), attr -> value ());
if (std::string (attr -> name ()) == "Count")
Count = std::string (attr -> value ());
if (std::string (attr -> name ()) == "Number")
Number = std::string (attr -> value ());
if (std::string (attr -> name ()) == "Channel")
Unit = std::string (attr -> value ());
}
add_dataBlock (currBlock, std::stoi (Count),
std::stoi (Number), Unit);
xml_node <>* subsubNode = subNode -> first_node ();
while (subsubNode != nullptr) {
if (std::string (subsubNode -> name ()) == "Frequency") {
std::string Unit = "Hz";
std::string Value = "200";
for (xml_attribute<>* attr =
subsubNode -> first_attribute ();
attr; attr = attr -> next_attribute ()) {
if (std::string (attr -> name ()) == "Unit")
Unit = std::string (attr -> value ());
if (std::string (attr -> name ()) == "Value")
Value = std::string (attr -> value ());
}
int Frequency =
Unit == "Hz" ? std::stoi (Value) :
((Unit == "KHz") | (Unit == "Khz")) ?
std::stoi (Value) * 1000 :
std::stoi (Value) * 1000000;
add_freqtoBlock (currBlock, Frequency);
}
if (std::string (subsubNode -> name ()) == "Modulation") {
for (xml_attribute<>* attr =
subsubNode -> first_attribute ();
attr; attr = attr -> next_attribute ()) {
if (std::string (attr -> name ()) == "Value") {
std::string Value =
std::string (attr -> value ());
add_modtoBlock (currBlock, Value);
}
}
}
subsubNode = subsubNode -> next_sibling ();
}
currBlock ++;
}
subNode = subNode -> next_sibling ();
}
nrBlocks = currBlock;
}
node = node -> next_sibling ();
}
*ok = nrBlocks > 0;
printDescriptor ();
}