aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/DabMultiplexer.cpp32
-rw-r--r--src/fig/FIGCarousel.cpp122
-rw-r--r--src/fig/FIGCarousel.h35
3 files changed, 124 insertions, 65 deletions
diff --git a/src/DabMultiplexer.cpp b/src/DabMultiplexer.cpp
index c7a5554..ea5a582 100644
--- a/src/DabMultiplexer.cpp
+++ b/src/DabMultiplexer.cpp
@@ -32,7 +32,7 @@
using namespace std;
using namespace boost;
-static unsigned char Padding_FIB[] = {
+static const unsigned char Padding_FIB[] = {
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -635,17 +635,16 @@ void DabMultiplexer::mux_frame(std::vector<boost::shared_ptr<DabOutput> >& outpu
tm* timeData;
- unsigned char figSize = 0;
-
- // FIB 0 Insertion
+ // Insert all FIBs
if (m_use_new_fig_carousel) {
fig_carousel.update(currentFrame, date);
- figSize += fig_carousel.carousel(0, &etiFrame[index], 30, currentFrame % 4);
- index += figSize;
+ const bool fib3_present = ensemble->mode == 3;
+ index += fig_carousel.write_fibs(&etiFrame[index], currentFrame % 4, fib3_present);
}
- // Skip creating a block for the else because
- // I don't want to reindent the whole switch block
- else switch (insertFIG) {
+ else {
+ unsigned char figSize = 0;
+ // FIB 0 Insertion
+ switch (insertFIG) {
case 0:
case 4:
@@ -1136,10 +1135,7 @@ void DabMultiplexer::mux_frame(std::vector<boost::shared_ptr<DabOutput> >& outpu
figSize = 0;
// FIB 1 insertion
- if (m_use_new_fig_carousel) {
- figSize += fig_carousel.carousel(1, &etiFrame[index], 30, currentFrame % 4);
- index += figSize;
- } else switch (rotateFIB) {
+ switch (rotateFIB) {
case 0: // FIG 0/8 program
fig0 = NULL;
@@ -1536,11 +1532,7 @@ void DabMultiplexer::mux_frame(std::vector<boost::shared_ptr<DabOutput> >& outpu
figSize = 0;
// FIB 2 insertion
- if (m_use_new_fig_carousel) {
- figSize += fig_carousel.carousel(2, &etiFrame[index], 30, currentFrame % 4);
- index += figSize;
- }
- else if (rotateFIB < ensemble->services.size()) {
+ if (rotateFIB < ensemble->services.size()) {
service = ensemble->services.begin() + rotateFIB;
// FIG type 1/1, SI, Service label, one instance per subchannel
@@ -1661,8 +1653,7 @@ void DabMultiplexer::mux_frame(std::vector<boost::shared_ptr<DabOutput> >& outpu
etiFrame[index++] = ((char *) &CRCtmp)[0];
}
- if ( !m_use_new_fig_carousel and
- ensemble->services.size() > 30) {
+ if (ensemble->services.size() > 30) {
etiLog.log(error,
"Sorry, but this software currently can't write "
"Service Label of more than 30 services.\n");
@@ -1674,6 +1665,7 @@ void DabMultiplexer::mux_frame(std::vector<boost::shared_ptr<DabOutput> >& outpu
// We rotate through the FIBs every 30 frames
rotateFIB = (rotateFIB + 1) % 30;
+ }
/**********************************************************************
****** Input Data Reading *******************************************
diff --git a/src/fig/FIGCarousel.cpp b/src/fig/FIGCarousel.cpp
index 1d79f2d..106e78e 100644
--- a/src/fig/FIGCarousel.cpp
+++ b/src/fig/FIGCarousel.cpp
@@ -26,6 +26,7 @@
along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "crc.h"
#include "Log.h"
#include "fig/FIGCarousel.h"
#include <boost/format.hpp>
@@ -73,25 +74,26 @@ FIGCarousel::FIGCarousel(boost::shared_ptr<dabEnsemble> ensemble) :
m_fig0_18(&m_rti),
m_fig0_19(&m_rti)
{
- load_and_allocate(m_fig0_0, 0);
- load_and_allocate(m_fig0_1, 0);
- load_and_allocate(m_fig0_2, 0);
- load_and_allocate(m_fig0_3, 0);
- load_and_allocate(m_fig0_17, 0);
-
- load_and_allocate(m_fig0_8, 1);
- load_and_allocate(m_fig1_0, 1);
- load_and_allocate(m_fig0_13, 1);
- load_and_allocate(m_fig0_10, 1);
- load_and_allocate(m_fig0_9, 1);
-
- load_and_allocate(m_fig1_1, 2);
- load_and_allocate(m_fig1_5, 2);
- load_and_allocate(m_fig0_18, 2);
- load_and_allocate(m_fig0_19, 2);
+ load_and_allocate(m_fig0_1, FIBAllocation::FIB_ANY);
+ load_and_allocate(m_fig0_2, FIBAllocation::FIB_ANY);
+
+ load_and_allocate(m_fig0_0, FIBAllocation::FIB0);
+ load_and_allocate(m_fig0_3, FIBAllocation::FIB0);
+ load_and_allocate(m_fig0_17, FIBAllocation::FIB0);
+
+ load_and_allocate(m_fig0_8, FIBAllocation::FIB1);
+ load_and_allocate(m_fig1_0, FIBAllocation::FIB1);
+ load_and_allocate(m_fig0_13, FIBAllocation::FIB1);
+ load_and_allocate(m_fig0_10, FIBAllocation::FIB1);
+ load_and_allocate(m_fig0_9, FIBAllocation::FIB1);
+
+ load_and_allocate(m_fig1_1, FIBAllocation::FIB2);
+ load_and_allocate(m_fig1_5, FIBAllocation::FIB2);
+ load_and_allocate(m_fig0_18, FIBAllocation::FIB2);
+ load_and_allocate(m_fig0_19, FIBAllocation::FIB2);
}
-void FIGCarousel::load_and_allocate(IFIG& fig, int fib)
+void FIGCarousel::load_and_allocate(IFIG& fig, FIBAllocation fib)
{
int type = fig.figtype();
int extension = fig.figextension();
@@ -106,12 +108,8 @@ void FIGCarousel::update(unsigned long currentFrame, time_t dabTime)
m_rti.date = dabTime;
}
-void FIGCarousel::allocate_fig_to_fib(int figtype, int extension, int fib)
+void FIGCarousel::allocate_fig_to_fib(int figtype, int extension, FIBAllocation fib)
{
- if (fib < 0 or fib >= 3) {
- throw std::out_of_range("Invalid FIB");
- }
-
auto fig = m_figs_available.find(std::make_pair(figtype, extension));
if (fig != m_figs_available.end()) {
@@ -136,23 +134,76 @@ void dumpfib(const uint8_t *buf, size_t bufsize) {
std::cerr << std::endl;
}
+size_t FIGCarousel::write_fibs(
+ uint8_t *buf,
+ int framephase,
+ bool fib3_present)
+{
+ /* Decrement all deadlines of all figs */
+ for (auto& fib_fig : m_fibs) {
+ auto fig = fib_fig.second;
+ for (auto fig_el : fig) {
+ fig_el.reduce_deadline();
+ }
+ }
+
+ const int fibCount = fib3_present ? 4 : 3;
+
+ for (int fib = 0; fib < fibCount; fib++) {
+ memset(buf, 0x00, 30);
+ size_t figSize = carousel(fib, buf, 30, framephase);
+
+ if (figSize < 30) {
+ buf[figSize] = 0xff; // end marker
+ }
+ else if (figSize > 30) {
+ std::stringstream ss;
+ ss << "FIB" << fib << " overload (" << figSize << "> 30)";
+ throw std::runtime_error(ss.str());
+ }
+
+ uint16_t CRCtmp = 0xffff;
+ CRCtmp = crc16(CRCtmp, buf, 30);
+ CRCtmp ^= 0xffff;
+
+ buf += 30;
+ *(buf++) = ((char *) &CRCtmp)[1];
+ *(buf++) = ((char *) &CRCtmp)[0];
+ }
+
+ return 32 * fibCount;
+}
+
size_t FIGCarousel::carousel(
- size_t fib,
+ int fib,
uint8_t *buf,
const size_t bufsize,
int framephase)
{
uint8_t *pbuf = buf;
- std::list<FIGCarouselElement>& figs = m_fibs[fib];
+ FIBAllocation fibix;
- std::deque<FIGCarouselElement*> sorted_figs;
-
- /* Decrement all deadlines */
- for (auto& fig_el : figs) {
- fig_el.reduce_deadline();
+ if (fib == 0) {
+ fibix = FIBAllocation::FIB0;
+ }
+ else if (fib == 1) {
+ fibix = FIBAllocation::FIB1;
+ }
+ else if (fib == 2) {
+ fibix = FIBAllocation::FIB2;
+ }
+ else {
+ throw std::invalid_argument("FIGCarousel::carousel called with invalid fib");
+ }
- sorted_figs.push_back(&fig_el);
+ // Create our list of FIGs to consider for this FIB
+ std::deque<FIGCarouselElement*> sorted_figs;
+ for (auto& fig : m_fibs[fibix]) {
+ sorted_figs.push_back(&fig);
+ }
+ for (auto& fig : m_fibs[FIBAllocation::FIB_ANY]) {
+ sorted_figs.push_back(&fig);
}
/* Sort the FIGs in the FIB according to their deadline */
@@ -190,7 +241,7 @@ size_t FIGCarousel::carousel(
pbuf += written;
#if CAROUSELDEBUG
- std::cerr << " ****** FIG0/0 wrote\t" << written << " bytes"
+ std::cerr << " ****** FIG0/0(special) wrote\t" << written << " bytes"
<< std::endl;
if ( (*fig0_0)->fig->figtype() != 0 or
@@ -240,12 +291,13 @@ size_t FIGCarousel::carousel(
if (written > 2) {
available_size -= written;
pbuf += written;
+ }
#if CAROUSELDEBUG
- std::cerr << " ****** FIG" << fig_el->fig->figtype() << "/" <<
- fig_el->fig->figextension() << " wrote\t" << written <<
- " bytes" << std::endl;
+ std::cerr << " ****** FIG" << fig_el->fig->figtype() << "/" <<
+ fig_el->fig->figextension() << " wrote\t" << written <<
+ " bytes" << (status.complete_fig_transmitted ? ", complete" :
+ ", incomplete") << std::endl;
#endif
- }
if (status.complete_fig_transmitted) {
fig_el->increase_deadline();
diff --git a/src/fig/FIGCarousel.h b/src/fig/FIGCarousel.h
index f7a839c..bb6b546 100644
--- a/src/fig/FIGCarousel.h
+++ b/src/fig/FIGCarousel.h
@@ -48,40 +48,55 @@ struct FIGCarouselElement {
void increase_deadline(void);
};
+enum class FIBAllocation {
+ FIB0,
+ FIB1,
+ FIB2,
+ FIB3,
+ FIB_ANY
+};
+
class FIGCarousel {
public:
FIGCarousel(boost::shared_ptr<dabEnsemble> ensemble);
void update(unsigned long currentFrame, time_t dabTime);
- void allocate_fig_to_fib(int figtype, int extension, int fib);
+ void allocate_fig_to_fib(int figtype, int extension, FIBAllocation fib);
+
+ /* Write all FIBs to the buffer, including correct padding and crc.
+ * Returns number of bytes written.
+ *
+ * The buffer buf must be large enough to accomodate the FIBs, i.e.
+ * 32 bytes per FIB.
+ */
+ size_t write_fibs(
+ uint8_t *buf,
+ int framephase,
+ bool fib3_present);
- size_t carousel(size_t fib, uint8_t *buf, size_t bufsize, int framephase);
private:
+ size_t carousel(int fib, uint8_t *buf, size_t bufsize, int framephase);
- void load_and_allocate(IFIG& fig, int fib);
+ void load_and_allocate(IFIG& fig, FIBAllocation fib);
FIGRuntimeInformation m_rti;
std::map<std::pair<int, int>, IFIG*> m_figs_available;
- // Each FIB contains a list of carousel elements
- std::map<int, std::list<FIGCarouselElement> > m_fibs;
+ // Some FIGs can be mapped to a specific FIB or to FIB_ANY
+ std::map<FIBAllocation, std::list<FIGCarouselElement> > m_fibs;
- // FIB 0 figs
+ // See in ctor for allocation to FIBs
FIG0_0 m_fig0_0;
FIG0_1 m_fig0_1;
FIG0_2 m_fig0_2;
FIG0_3 m_fig0_3;
FIG0_17 m_fig0_17;
-
- // FIB 1 figs
FIG0_8 m_fig0_8;
FIG1_0 m_fig1_0;
FIG0_13 m_fig0_13;
FIG0_10 m_fig0_10;
FIG0_9 m_fig0_9;
-
- // FIB 2 figs
FIG1_1 m_fig1_1;
FIG1_4 m_fig1_4;
FIG1_5 m_fig1_5;