mirror of
https://github.com/JvanKatwijk/dabradio
synced 2025-10-05 15:52:42 +02:00
major update to sync (more or less) with qt-dab
This commit is contained in:
@@ -123,14 +123,16 @@ endif ()
|
||||
${QT_QTGUI_INCLUDE_DIR}
|
||||
.
|
||||
./
|
||||
./service-description
|
||||
./includes
|
||||
./includes/ofdm
|
||||
./includes/backend
|
||||
./includes/backend/viterbi_768
|
||||
./includes/backend/audio
|
||||
./includes/backend/data
|
||||
./includes/backend/data/journaline
|
||||
./includes/various
|
||||
./includes/backend/data/mot
|
||||
./includes/support
|
||||
./includes/support/viterbi_768
|
||||
./includes/output
|
||||
./devices
|
||||
/usr/include/
|
||||
@@ -138,14 +140,17 @@ endif ()
|
||||
|
||||
set (${objectName}_HDRS
|
||||
./dab-processor.h
|
||||
./service-list.h
|
||||
./service-display.h
|
||||
./includes/ofdm/sample-reader.h
|
||||
./includes/dab-constants.h
|
||||
./service-description/service-descriptor.h
|
||||
./service-description/audio-descriptor.h
|
||||
./includes/country-codes.h
|
||||
./includes/ofdm/timesyncer.h
|
||||
./includes/ofdm/sample-reader.h
|
||||
./includes/ofdm/phasereference.h
|
||||
./includes/ofdm/phasetable.h
|
||||
./includes/ofdm/freq-interleaver.h
|
||||
./includes/backend/viterbi_768/viterbi-768.h
|
||||
./includes/ofdm/fic-handler.h
|
||||
./includes/ofdm/fib-processor.h
|
||||
./includes/backend/protection.h
|
||||
./includes/backend/uep-protection.h
|
||||
./includes/backend/eep-protection.h
|
||||
@@ -163,40 +168,42 @@ endif ()
|
||||
./includes/backend/audio/mp2processor.h
|
||||
./includes/backend/data/virtual-datahandler.h
|
||||
./includes/backend/data/pad-handler.h
|
||||
./includes/backend/data/mot-handler.h
|
||||
./includes/backend/data/mot-dir.h
|
||||
./includes/backend/data/mot-object.h
|
||||
./includes/backend/data/mot/mot-handler.h
|
||||
./includes/backend/data/mot/mot-object.h
|
||||
./includes/backend/data/mot/mot-dir.h
|
||||
./includes/backend/data/data-processor.h
|
||||
./devices/virtual-input.h
|
||||
./includes/output/fir-filters.h
|
||||
./includes/output/audio-base.h
|
||||
./includes/output/newconverter.h
|
||||
./includes/various/fft-handler.h
|
||||
./includes/various/ringbuffer.h
|
||||
./includes/various/Xtan2.h
|
||||
./includes/various/dab-params.h
|
||||
./includes/various/band-handler.h
|
||||
./includes/various/text-mapper.h
|
||||
./includes/support/viterbi_768/viterbi-768.h
|
||||
./includes/support/fft-handler.h
|
||||
./includes/support/ringbuffer.h
|
||||
./includes/support/Xtan2.h
|
||||
./includes/support/dab-params.h
|
||||
./includes/support/band-handler.h
|
||||
./includes/support/text-mapper.h
|
||||
./includes/support/dab_tables.h
|
||||
|
||||
)
|
||||
|
||||
set (${objectName}_SRCS
|
||||
${${objectName}_SRCS}
|
||||
./main.cpp
|
||||
./dab-processor.cpp
|
||||
./service-list.cpp
|
||||
./service-display.cpp
|
||||
./service-description/service-descriptor.cpp
|
||||
./service-description/audio-descriptor.cpp
|
||||
./src/ofdm/timesyncer.cpp
|
||||
./src/ofdm/sample-reader.cpp
|
||||
./src/ofdm/ofdm-decoder.cpp
|
||||
./src/ofdm/phasereference.cpp
|
||||
./src/ofdm/phasetable.cpp
|
||||
./src/ofdm/freq-interleaver.cpp
|
||||
./src/backend/viterbi_768/viterbi-768.cpp
|
||||
./src/backend/viterbi_768/spiral-no-sse.c
|
||||
./src/backend/fic-handler.cpp
|
||||
./src/ofdm/fic-handler.cpp
|
||||
./src/ofdm/fib-processor.cpp
|
||||
./src/backend/protection.cpp
|
||||
./src/backend/eep-protection.cpp
|
||||
./src/backend/uep-protection.cpp
|
||||
./src/backend/fib-processor.cpp
|
||||
./src/backend/firecode-checker.cpp
|
||||
./src/backend/frame-processor.cpp
|
||||
./src/backend/protTables.cpp
|
||||
@@ -212,9 +219,9 @@ endif ()
|
||||
./src/backend/audio/mp2processor.cpp
|
||||
./src/backend/data/virtual-datahandler.cpp
|
||||
./src/backend/data/pad-handler.cpp
|
||||
./src/backend/data/mot-handler.cpp
|
||||
./src/backend/data/mot-dir.cpp
|
||||
./src/backend/data/mot-object.cpp
|
||||
./src/backend/data/mot/mot-handler.cpp
|
||||
./src/backend/data/mot/mot-object.cpp
|
||||
./src/backend/data/mot/mot-dir.cpp
|
||||
./src/backend/data/data-processor.cpp
|
||||
./devices/virtual-input.cpp
|
||||
./devices/rawfiles/rawfiles.cpp
|
||||
@@ -222,35 +229,39 @@ endif ()
|
||||
./src/output/audio-base.cpp
|
||||
./src/output/newconverter.cpp
|
||||
./src/output/fir-filters.cpp
|
||||
./src/various/fft-handler.cpp
|
||||
./src/various/Xtan2.cpp
|
||||
./src/various/dab-params.cpp
|
||||
./src/various/band-handler.cpp
|
||||
./src/various/text-mapper.cpp
|
||||
./src/support/fft-handler.cpp
|
||||
./src/support/Xtan2.cpp
|
||||
./src/support/dab-params.cpp
|
||||
./src/support/band-handler.cpp
|
||||
./src/support/text-mapper.cpp
|
||||
./src/support/dab_tables.cpp
|
||||
./src/support/viterbi_768/viterbi-768.cpp
|
||||
./src/support/viterbi_768/spiral-no-sse.c
|
||||
)
|
||||
|
||||
set (${objectName}_UIS
|
||||
${${objectName}_UIS} ./forms/dabradio.ui)
|
||||
${${objectName}_UIS} ./forms/dabradio.ui
|
||||
./forms/audio-description.ui)
|
||||
|
||||
set (${objectName}_MOCS
|
||||
./dab-processor.h
|
||||
./service-list.h
|
||||
./service-display.h
|
||||
./service-description/service-descriptor.h
|
||||
./service-description/audio-descriptor.h
|
||||
./includes/output/audio-base.h
|
||||
./includes/ofdm/sample-reader.h
|
||||
./includes/ofdm/ofdm-decoder.h
|
||||
./includes/ofdm/phasereference.h
|
||||
./includes/backend/fic-handler.h
|
||||
./includes/backend/fib-processor.h
|
||||
./includes/ofdm/fic-handler.h
|
||||
./includes/ofdm/fib-processor.h
|
||||
./includes/backend/data-backend.h
|
||||
./includes/backend/audio/faad-decoder.h
|
||||
./includes/backend/audio/mp2processor.h
|
||||
./includes/backend/audio/mp4processor.h
|
||||
./includes/backend/data/virtual-datahandler.h
|
||||
./includes/backend/data/pad-handler.h
|
||||
./includes/backend/data/mot-handler.h
|
||||
./includes/backend/data/mot-dir.h
|
||||
./includes/backend/data/mot-object.h
|
||||
./includes/backend/data/mot/mot-handler.h
|
||||
./includes/backend/data/mot/mot-object.h
|
||||
./includes/backend/data/mot/mot-dir.h
|
||||
./includes/backend/data/data-processor.h
|
||||
)
|
||||
|
||||
|
@@ -119,136 +119,145 @@ add_definitions (-DTHREADED_DECODING) # uncomment for use for an RPI
|
||||
${QT_QTGUI_INCLUDE_DIR}
|
||||
.
|
||||
./
|
||||
./includes
|
||||
./includes/ofdm
|
||||
./includes/backend
|
||||
./includes/backend/viterbi_768
|
||||
./includes/backend/audio
|
||||
./includes/backend/data
|
||||
./includes/backend/data/journaline
|
||||
./includes/various
|
||||
./includes/output
|
||||
./devices
|
||||
./service-description
|
||||
./includes
|
||||
./includes/ofdm
|
||||
./includes/backend
|
||||
./includes/backend/audio
|
||||
./includes/backend/data
|
||||
./includes/backend/data/journaline
|
||||
./includes/backend/data/mot
|
||||
./includes/support
|
||||
./includes/support/viterbi_768
|
||||
./includes/output
|
||||
./devices
|
||||
/usr/include/
|
||||
)
|
||||
|
||||
set (${objectName}_HDRS
|
||||
./dab-processor.h
|
||||
./service-list.h
|
||||
./service-display.h
|
||||
./includes/ofdm/sample-reader.h
|
||||
./includes/dab-constants.h
|
||||
./includes/ofdm/phasereference.h
|
||||
./includes/ofdm/phasetable.h
|
||||
./includes/ofdm/freq-interleaver.h
|
||||
./includes/backend/viterbi_768/viterbi-768.h
|
||||
./includes/dab-constants.h
|
||||
./service-description/service-descriptor.h
|
||||
./service-description/audio-descriptor.h
|
||||
./includes/country-codes.h
|
||||
./includes/ofdm/timesyncer.h
|
||||
./includes/ofdm/sample-reader.h
|
||||
./includes/ofdm/phasereference.h
|
||||
./includes/ofdm/phasetable.h
|
||||
./includes/ofdm/freq-interleaver.h
|
||||
./includes/ofdm/fic-handler.h
|
||||
./includes/ofdm/fib-processor.h
|
||||
./includes/backend/protection.h
|
||||
./includes/backend/uep-protection.h
|
||||
./includes/backend/eep-protection.h
|
||||
./includes/backend/firecode-checker.h
|
||||
./includes/backend/frame-processor.h
|
||||
./includes/backend/charsets.h
|
||||
./includes/backend/galois.h
|
||||
./incluces/backend/reed-solomon.h
|
||||
./includes/backend/msc-handler.h
|
||||
./includes/backend/virtual-backend.h
|
||||
./includes/backend/audio-backend.h
|
||||
./includes/backend/databackend.h
|
||||
./includes/backend/audio/faad-decoder.h
|
||||
./includes/backend/audio/mp4processor.h
|
||||
./includes/backend/audio/mp2processor.h
|
||||
./includes/backend/data/virtual-datahandler.h
|
||||
./includes/backend/data/pad-handler.h
|
||||
./includes/backend/data/mot-handler.h
|
||||
./includes/backend/data/mot-dir.h
|
||||
./includes/backend/data/mot-object.h
|
||||
./includes/backend/uep-protection.h
|
||||
./includes/backend/eep-protection.h
|
||||
./includes/backend/firecode-checker.h
|
||||
./includes/backend/frame-processor.h
|
||||
./includes/backend/charsets.h
|
||||
./includes/backend/galois.h
|
||||
./incluces/backend/reed-solomon.h
|
||||
./includes/backend/msc-handler.h
|
||||
./includes/backend/virtual-backend.h
|
||||
./includes/backend/audio-backend.h
|
||||
./includes/backend/data-backend.h
|
||||
./includes/backend/audio/faad-decoder.h
|
||||
./includes/backend/audio/mp4processor.h
|
||||
./includes/backend/audio/mp2processor.h
|
||||
./includes/backend/data/virtual-datahandler.h
|
||||
./includes/backend/data/pad-handler.h
|
||||
./includes/backend/data/mot/mot-handler.h
|
||||
./includes/backend/data/mot/mot-object.h
|
||||
./includes/backend/data/data-processor.h
|
||||
./devices/virtual-input.h
|
||||
./includes/output/fir-filters.h
|
||||
./includes/output/audio-base.h
|
||||
./includes/output/audiosink.h
|
||||
./includes/output/newconverter.h
|
||||
./includes/various/fft-handler.h
|
||||
./includes/various/ringbuffer.h
|
||||
./includes/various/Xtan2.h
|
||||
./includes/various/dab-params.h
|
||||
./includes/various/band-handler.h
|
||||
./includes/various/text-mapper.h
|
||||
./devices/virtual-input.h
|
||||
./includes/output/fir-filters.h
|
||||
./includes/output/audio-base.h
|
||||
./includes/output/newconverter.h
|
||||
./includes/support/viterbi_768/viterbi-768.h
|
||||
./includes/support/fft-handler.h
|
||||
./includes/support/ringbuffer.h
|
||||
./includes/support/Xtan2.h
|
||||
./includes/support/dab-params.h
|
||||
./includes/support/band-handler.h
|
||||
./includes/support/text-mapper.h
|
||||
./includes/support/dab_tables.h
|
||||
)
|
||||
|
||||
set (${objectName}_SRCS
|
||||
${${objectName}_SRCS}
|
||||
./main.cpp
|
||||
./dab-processor.cpp
|
||||
./service-list.cpp
|
||||
./service-display.cpp
|
||||
./dab-processor.cpp
|
||||
./service-description/service-descriptor.cpp
|
||||
./service-description/audio-descriptor.cpp
|
||||
./src/ofdm/timesyncer.cpp
|
||||
./src/ofdm/sample-reader.cpp
|
||||
./src/ofdm/ofdm-decoder.cpp
|
||||
./src/ofdm/phasereference.cpp
|
||||
./src/ofdm/phasetable.cpp
|
||||
./src/ofdm/freq-interleaver.cpp
|
||||
./src/backend/viterbi_768/viterbi-768.cpp
|
||||
./src/backend/viterbi_768/spiral-no-sse.c
|
||||
./src/backend/fic-handler.cpp
|
||||
./src/ofdm/ofdm-decoder.cpp
|
||||
./src/ofdm/phasereference.cpp
|
||||
./src/ofdm/phasetable.cpp
|
||||
./src/ofdm/freq-interleaver.cpp
|
||||
./src/ofdm/fic-handler.cpp
|
||||
./src/ofdm/fib-processor.cpp
|
||||
./src/backend/protection.cpp
|
||||
./src/backend/eep-protection.cpp
|
||||
./src/backend/uep-protection.cpp
|
||||
./src/backend/fib-processor.cpp
|
||||
./src/backend/firecode-checker.cpp
|
||||
./src/backend/frame-processor.cpp
|
||||
./src/backend/protTables.cpp
|
||||
./src/backend/charsets.cpp
|
||||
./src/backend/galois.cpp
|
||||
./src/backend/reed-solomon.cpp
|
||||
./src/backend/msc-handler.cpp
|
||||
./src/backend/virtual-backend.cpp
|
||||
./src/backend/audio-backend.cpp
|
||||
./src/backend/data-backend.cpp
|
||||
./src/backend/audio/faad-decoder.cpp
|
||||
./src/backend/audio/mp4processor.cpp
|
||||
./src/backend/audio/mp2processor.cpp
|
||||
./src/backend/data/virtual-datahandler.cpp
|
||||
./src/backend/eep-protection.cpp
|
||||
./src/backend/uep-protection.cpp
|
||||
./src/backend/firecode-checker.cpp
|
||||
./src/backend/frame-processor.cpp
|
||||
./src/backend/protTables.cpp
|
||||
./src/backend/charsets.cpp
|
||||
./src/backend/galois.cpp
|
||||
./src/backend/reed-solomon.cpp
|
||||
./src/backend/msc-handler.cpp
|
||||
./src/backend/virtual-backend.cpp
|
||||
./src/backend/audio-backend.cpp
|
||||
./src/backend/data-backend.cpp
|
||||
./src/backend/audio/faad-decoder.cpp
|
||||
./src/backend/audio/mp4processor.cpp
|
||||
./src/backend/audio/mp2processor.cpp
|
||||
./src/backend/data/virtual-datahandler.cpp
|
||||
./src/backend/data/pad-handler.cpp
|
||||
./src/backend/data/mot-handler.cpp
|
||||
./src/backend/data/mot-dir.cpp
|
||||
./src/backend/data/mot-object.cpp
|
||||
./src/backend/data/data-processor.cpp
|
||||
./devices/virtual-input.cpp
|
||||
./src/output/audio-base.cpp
|
||||
./src/output/audiosink.cpp
|
||||
./src/output/newconverter.cpp
|
||||
./src/output/fir-filters.cpp
|
||||
./src/various/fft-handler.cpp
|
||||
./src/various/Xtan2.cpp
|
||||
./src/various/dab-params.cpp
|
||||
./src/various/band-handler.cpp
|
||||
./src/various/text-mapper.cpp
|
||||
./src/backend/data/mot/mot-handler.cpp
|
||||
./src/backend/data/mot/mot-object.cpp
|
||||
./src/backend/data/mot/mot-dir.cpp
|
||||
./src/backend/data/data-processor.cpp
|
||||
./devices/virtual-input.cpp
|
||||
./devices/rawfiles/rawfiles.cpp
|
||||
./devices/wavfiles/wavfiles.cpp
|
||||
./src/output/audio-base.cpp
|
||||
./src/output/newconverter.cpp
|
||||
./src/output/fir-filters.cpp
|
||||
./src/support/fft-handler.cpp
|
||||
./src/support/Xtan2.cpp
|
||||
./src/support/dab-params.cpp
|
||||
./src/support/band-handler.cpp
|
||||
./src/support/text-mapper.cpp
|
||||
./src/support/dab_tables.cpp
|
||||
./src/support/viterbi_768/viterbi-768.cpp
|
||||
./src/support/viterbi_768/spiral-no-sse.c
|
||||
)
|
||||
|
||||
set (${objectName}_MOCS
|
||||
./dab-processor.h
|
||||
./service-list.h
|
||||
./service-display.h
|
||||
./service-description/service-descriptor.h
|
||||
./service-description/audio-descriptor.h
|
||||
./includes/output/audio-base.h
|
||||
./includes/ofdm/sample-reader.h
|
||||
./includes/ofdm/ofdm-decoder.h
|
||||
./includes/ofdm/phasereference.h
|
||||
./includes/backend/fic-handler.h
|
||||
./includes/backend/fib-processor.h
|
||||
./includes/backend/data-backend.h
|
||||
./includes/ofdm/fic-handler.h
|
||||
./includes/ofdm/fib-processor.h
|
||||
./includes/backend/data-backend.h
|
||||
./includes/backend/audio/faad-decoder.h
|
||||
./includes/backend/audio/mp2processor.h
|
||||
./includes/backend/audio/mp4processor.h
|
||||
./includes/backend/data/virtual-datahandler.h
|
||||
./includes/backend/data/pad-handler.h
|
||||
./includes/backend/data/mot-handler.h
|
||||
./includes/backend/data/mot-dir.h
|
||||
./includes/backend/data/mot-object.h
|
||||
./includes/backend/data/mot/mot-handler.h
|
||||
./includes/backend/data/mot/mot-object.h
|
||||
./includes/backend/data/mot/mot-dir.h
|
||||
./includes/backend/data/data-processor.h
|
||||
)
|
||||
|
||||
set (${objectName}_UIS
|
||||
${${objectName}_UIS} ./forms/dabradio.ui)
|
||||
set (${objectName}_UIS
|
||||
${${objectName}_UIS} ./forms/dabradio.ui
|
||||
./forms/audio-description.ui)
|
||||
|
||||
set (${objectName}_MOCS
|
||||
${${objectName}_MOCS} ./radio.h)
|
||||
|
@@ -123,14 +123,16 @@ endif ()
|
||||
${QT_QTGUI_INCLUDE_DIR}
|
||||
.
|
||||
./
|
||||
./service-description
|
||||
./includes
|
||||
./includes/ofdm
|
||||
./includes/backend
|
||||
./includes/backend/viterbi_768
|
||||
./includes/backend/audio
|
||||
./includes/backend/data
|
||||
./includes/backend/data/journaline
|
||||
./includes/various
|
||||
./includes/backend/data/mot
|
||||
./includes/support
|
||||
./includes/support/viterbi_768
|
||||
./includes/output
|
||||
./devices
|
||||
/usr/include/
|
||||
@@ -138,14 +140,17 @@ endif ()
|
||||
|
||||
set (${objectName}_HDRS
|
||||
./dab-processor.h
|
||||
./service-list.h
|
||||
./service-display.h
|
||||
./includes/ofdm/sample-reader.h
|
||||
./includes/dab-constants.h
|
||||
./service-description/service-descriptor.h
|
||||
./service-description/audio-descriptor.h
|
||||
./includes/country-codes.h
|
||||
./includes/ofdm/timesyncer.h
|
||||
./includes/ofdm/sample-reader.h
|
||||
./includes/ofdm/phasereference.h
|
||||
./includes/ofdm/phasetable.h
|
||||
./includes/ofdm/freq-interleaver.h
|
||||
./includes/backend/viterbi_768/viterbi-768.h
|
||||
./includes/ofdm/fic-handler.h
|
||||
./includes/ofdm/fib-processor.h
|
||||
./includes/backend/protection.h
|
||||
./includes/backend/uep-protection.h
|
||||
./includes/backend/eep-protection.h
|
||||
@@ -163,40 +168,42 @@ endif ()
|
||||
./includes/backend/audio/mp2processor.h
|
||||
./includes/backend/data/virtual-datahandler.h
|
||||
./includes/backend/data/pad-handler.h
|
||||
./includes/backend/data/mot-handler.h
|
||||
./includes/backend/data/mot-dir.h
|
||||
./includes/backend/data/mot-object.h
|
||||
./includes/backend/data/mot/mot-handler.h
|
||||
./includes/backend/data/mot/mot-object.h
|
||||
./includes/backend/data/mot/mot-dir.h
|
||||
./includes/backend/data/data-processor.h
|
||||
./devices/virtual-input.h
|
||||
./includes/output/fir-filters.h
|
||||
./includes/output/audio-base.h
|
||||
./includes/output/newconverter.h
|
||||
./includes/various/fft-handler.h
|
||||
./includes/various/ringbuffer.h
|
||||
./includes/various/Xtan2.h
|
||||
./includes/various/dab-params.h
|
||||
./includes/various/band-handler.h
|
||||
./includes/various/text-mapper.h
|
||||
./includes/support/viterbi_768/viterbi-768.h
|
||||
./includes/support/fft-handler.h
|
||||
./includes/support/ringbuffer.h
|
||||
./includes/support/Xtan2.h
|
||||
./includes/support/dab-params.h
|
||||
./includes/support/band-handler.h
|
||||
./includes/support/text-mapper.h
|
||||
./includes/support/dab_tables.h
|
||||
|
||||
)
|
||||
|
||||
set (${objectName}_SRCS
|
||||
${${objectName}_SRCS}
|
||||
./main.cpp
|
||||
./dab-processor.cpp
|
||||
./service-list.cpp
|
||||
./service-display.cpp
|
||||
./service-description/service-descriptor.cpp
|
||||
./service-description/audio-descriptor.cpp
|
||||
./src/ofdm/timesyncer.cpp
|
||||
./src/ofdm/sample-reader.cpp
|
||||
./src/ofdm/ofdm-decoder.cpp
|
||||
./src/ofdm/phasereference.cpp
|
||||
./src/ofdm/phasetable.cpp
|
||||
./src/ofdm/freq-interleaver.cpp
|
||||
./src/backend/viterbi_768/viterbi-768.cpp
|
||||
./src/backend/viterbi_768/spiral-no-sse.c
|
||||
./src/backend/fic-handler.cpp
|
||||
./src/ofdm/fic-handler.cpp
|
||||
./src/ofdm/fib-processor.cpp
|
||||
./src/backend/protection.cpp
|
||||
./src/backend/eep-protection.cpp
|
||||
./src/backend/uep-protection.cpp
|
||||
./src/backend/fib-processor.cpp
|
||||
./src/backend/firecode-checker.cpp
|
||||
./src/backend/frame-processor.cpp
|
||||
./src/backend/protTables.cpp
|
||||
@@ -212,9 +219,9 @@ endif ()
|
||||
./src/backend/audio/mp2processor.cpp
|
||||
./src/backend/data/virtual-datahandler.cpp
|
||||
./src/backend/data/pad-handler.cpp
|
||||
./src/backend/data/mot-handler.cpp
|
||||
./src/backend/data/mot-dir.cpp
|
||||
./src/backend/data/mot-object.cpp
|
||||
./src/backend/data/mot/mot-handler.cpp
|
||||
./src/backend/data/mot/mot-object.cpp
|
||||
./src/backend/data/mot/mot-dir.cpp
|
||||
./src/backend/data/data-processor.cpp
|
||||
./devices/virtual-input.cpp
|
||||
./devices/rawfiles/rawfiles.cpp
|
||||
@@ -222,35 +229,39 @@ endif ()
|
||||
./src/output/audio-base.cpp
|
||||
./src/output/newconverter.cpp
|
||||
./src/output/fir-filters.cpp
|
||||
./src/various/fft-handler.cpp
|
||||
./src/various/Xtan2.cpp
|
||||
./src/various/dab-params.cpp
|
||||
./src/various/band-handler.cpp
|
||||
./src/various/text-mapper.cpp
|
||||
./src/support/fft-handler.cpp
|
||||
./src/support/Xtan2.cpp
|
||||
./src/support/dab-params.cpp
|
||||
./src/support/band-handler.cpp
|
||||
./src/support/text-mapper.cpp
|
||||
./src/support/dab_tables.cpp
|
||||
./src/support/viterbi_768/viterbi-768.cpp
|
||||
./src/support/viterbi_768/spiral-no-sse.c
|
||||
)
|
||||
|
||||
set (${objectName}_UIS
|
||||
${${objectName}_UIS} ./forms/dabradio.ui)
|
||||
${${objectName}_UIS} ./forms/dabradio.ui
|
||||
./forms/audio-description.ui)
|
||||
|
||||
set (${objectName}_MOCS
|
||||
./dab-processor.h
|
||||
./service-list.h
|
||||
./service-display.h
|
||||
./service-description/service-descriptor.h
|
||||
./service-description/audio-descriptor.h
|
||||
./includes/output/audio-base.h
|
||||
./includes/ofdm/sample-reader.h
|
||||
./includes/ofdm/ofdm-decoder.h
|
||||
./includes/ofdm/phasereference.h
|
||||
./includes/backend/fic-handler.h
|
||||
./includes/backend/fib-processor.h
|
||||
./includes/ofdm/fic-handler.h
|
||||
./includes/ofdm/fib-processor.h
|
||||
./includes/backend/data-backend.h
|
||||
./includes/backend/audio/faad-decoder.h
|
||||
./includes/backend/audio/mp2processor.h
|
||||
./includes/backend/audio/mp4processor.h
|
||||
./includes/backend/data/virtual-datahandler.h
|
||||
./includes/backend/data/pad-handler.h
|
||||
./includes/backend/data/mot-handler.h
|
||||
./includes/backend/data/mot-dir.h
|
||||
./includes/backend/data/mot-object.h
|
||||
./includes/backend/data/mot/mot-handler.h
|
||||
./includes/backend/data/mot/mot-object.h
|
||||
./includes/backend/data/mot/mot-dir.h
|
||||
./includes/backend/data/data-processor.h
|
||||
)
|
||||
|
||||
|
70
LICENSE
70
LICENSE
@@ -1,39 +1,12 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (c) 2013 .. 2017
|
||||
Jan van Katwijk
|
||||
Lazy Chair Computing
|
||||
J.vanKatwijk@gmail.com
|
||||
|
||||
The Qt-DAB software - as well as its predecessors DAB-rpi and sdr-j-dab
|
||||
and derivatives - are made available under GPL license Version 2.
|
||||
|
||||
Many of the ideas as implemented in Qt-DAB are derived from
|
||||
other work, made available through the GNU general Public License.
|
||||
All copyrights of the original authors are acknowledged.
|
||||
|
||||
Qt-DAB is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License, version 2,
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
Qt-DAB 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.
|
||||
|
||||
Any non-GPL usage of this software or parts of this software is strictly
|
||||
forbidden. Commercial non-GPL licensing of this software is possible.
|
||||
For more info contact the author, named above.
|
||||
|
||||
===========================================================================
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
@@ -42,7 +15,7 @@ software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
@@ -82,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
@@ -137,7 +110,7 @@ above, provided that you also meet all of these conditions:
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
@@ -195,7 +168,7 @@ access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
@@ -252,7 +225,7 @@ impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
@@ -282,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
@@ -304,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
@@ -318,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -330,17 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
@@ -363,5 +335,5 @@ necessary. Here is a sample; alter the names:
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
|
@@ -4,19 +4,19 @@
|
||||
* Jan van Katwijk (J.vanKatwijk@gmail.com)
|
||||
* Lazy Chair Computing
|
||||
*
|
||||
* This file is part of the Qt-DAB program
|
||||
* Qt-DAB is free software; you can redistribute it and/or modify
|
||||
* This file is part of the dabradio program
|
||||
* dabradio 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.
|
||||
*
|
||||
* Qt-DAB is distributed in the hope that it will be useful,
|
||||
* dabradio 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 Qt-DAB if not, write to the Free Software
|
||||
* along with dabradio if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "dab-processor.h"
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "msc-handler.h"
|
||||
#include "radio.h"
|
||||
#include "dab-params.h"
|
||||
#include "timesyncer.h"
|
||||
//
|
||||
/**
|
||||
* \brief dabProcessor
|
||||
@@ -41,19 +42,21 @@
|
||||
int16_t diff_length,
|
||||
QString picturesPath):
|
||||
params (dabMode),
|
||||
myReader (mr, theDevice),
|
||||
myReader (mr,
|
||||
theDevice,
|
||||
nullptr),
|
||||
my_ficHandler (mr, dabMode),
|
||||
my_mscHandler (mr, dabMode,
|
||||
picturesPath),
|
||||
phaseSynchronizer (mr,
|
||||
dabMode,
|
||||
threshold,
|
||||
diff_length),
|
||||
diff_length,
|
||||
nullptr),
|
||||
my_ofdmDecoder (mr,
|
||||
dabMode,
|
||||
theDevice -> bitDepth (),
|
||||
&my_ficHandler,
|
||||
&my_mscHandler) {
|
||||
nullptr) {
|
||||
int32_t i;
|
||||
|
||||
this -> myRadioInterface = mr;
|
||||
@@ -71,8 +74,8 @@ int32_t i;
|
||||
ofdmBufferIndex = 0;
|
||||
ofdmSymbolCount = 0;
|
||||
tokenCount = 0;
|
||||
fineCorrector = 0;
|
||||
f2Correction = true;
|
||||
fineOffset = 0;
|
||||
correctionNeeded = true;
|
||||
attempts = 0;
|
||||
myReader. setRunning (false);
|
||||
}
|
||||
@@ -107,89 +110,45 @@ void dabProcessor::start (int frequency, bool giveSignal) {
|
||||
void dabProcessor::run (void) {
|
||||
int32_t startIndex;
|
||||
int32_t i;
|
||||
std::complex<float> FreqCorr;
|
||||
int32_t counter;
|
||||
float cLevel;
|
||||
int32_t syncBufferIndex = 0;
|
||||
const
|
||||
int32_t syncBufferSize = 32768;
|
||||
const
|
||||
int32_t syncBufferMask = syncBufferSize - 1;
|
||||
float envBuffer [syncBufferSize];
|
||||
int attempts;
|
||||
|
||||
fineCorrector = 0;
|
||||
f2Correction = true;
|
||||
syncBufferIndex = 0;
|
||||
std::complex<float> FreqCorr;
|
||||
timeSyncer myTimeSyncer (&myReader);
|
||||
|
||||
fineOffset = 0;
|
||||
correctionNeeded = true;
|
||||
attempts = 0;
|
||||
theDevice -> resetBuffer ();
|
||||
theDevice -> restartReader ();
|
||||
coarseOffset = 0;
|
||||
fineOffset = 0;
|
||||
myReader. setRunning (true);
|
||||
my_ofdmDecoder. start ();
|
||||
my_mscHandler. start ();
|
||||
//
|
||||
// to get some idea of the signal strength
|
||||
try {
|
||||
for (i = 0; i < T_F / 5; i ++) {
|
||||
myReader. getSample (0);
|
||||
}
|
||||
Initing:
|
||||
//Initing:
|
||||
notSynced:
|
||||
syncBufferIndex = 0;
|
||||
cLevel = 0;
|
||||
|
||||
for (i = 0; i < C_LEVEL_SIZE; i ++) {
|
||||
std::complex<float> sample = myReader. getSample (0);
|
||||
envBuffer [syncBufferIndex] = jan_abs (sample);
|
||||
cLevel += envBuffer [syncBufferIndex];
|
||||
syncBufferIndex ++;
|
||||
}
|
||||
/**
|
||||
* We now have initial values for cLevel (i.e. the sum
|
||||
* over the last C_LEVEL_SIZE samples) and sLevel, the long term average.
|
||||
*/
|
||||
SyncOnNull:
|
||||
/**
|
||||
* here we start looking for the null level, i.e. a dip
|
||||
*/
|
||||
counter = 0;
|
||||
setSynced (false);
|
||||
while (cLevel / C_LEVEL_SIZE > 0.40 * myReader. get_sLevel ()) {
|
||||
std::complex<float> sample =
|
||||
myReader. getSample (coarseOffset + fineCorrector);
|
||||
envBuffer [syncBufferIndex] = jan_abs (sample);
|
||||
// update the levels
|
||||
cLevel += envBuffer [syncBufferIndex] -
|
||||
envBuffer [(syncBufferIndex - C_LEVEL_SIZE) & syncBufferMask];
|
||||
syncBufferIndex = (syncBufferIndex + 1) & syncBufferMask;
|
||||
counter ++;
|
||||
if (counter > T_F) { // hopeless
|
||||
if (giveSignal && (++ attempts >= 5)) {
|
||||
emit (No_Signal_Found ());
|
||||
switch (myTimeSyncer. sync (T_null, T_F)) {
|
||||
case TIMESYNC_ESTABLISHED:
|
||||
break; // yes, we are ready
|
||||
|
||||
case NO_DIP_FOUND:
|
||||
if (giveSignal && (++ attempts >= 5)) {
|
||||
emit (No_Signal_Found ());
|
||||
attempts = 0;
|
||||
}
|
||||
goto notSynced;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* It seemed we found a dip that started app 65/100 * 50 samples earlier.
|
||||
* We now start looking for the end of the null period.
|
||||
*/
|
||||
counter = 0;
|
||||
SyncOnEndNull:
|
||||
while (cLevel / C_LEVEL_SIZE < 0.75 * myReader. get_sLevel ()) {
|
||||
std::complex<float> sample =
|
||||
myReader. getSample (coarseOffset + fineCorrector);
|
||||
envBuffer [syncBufferIndex] = jan_abs (sample);
|
||||
// update the levels
|
||||
cLevel += envBuffer [syncBufferIndex] -
|
||||
envBuffer [(syncBufferIndex - C_LEVEL_SIZE) & syncBufferMask];
|
||||
syncBufferIndex = (syncBufferIndex + 1) & syncBufferMask;
|
||||
counter ++;
|
||||
//
|
||||
if (counter > T_null + 50) { // hopeless
|
||||
goto notSynced;
|
||||
}
|
||||
}
|
||||
goto notSynced;
|
||||
|
||||
default: // does not happen
|
||||
case NO_END_OF_DIP_FOUND:
|
||||
goto notSynced;
|
||||
}
|
||||
|
||||
/**
|
||||
* The end of the null period is identified, the actual end
|
||||
* is probably about 40 samples earlier.
|
||||
@@ -207,17 +166,18 @@ SyncOnPhase:
|
||||
* is part of the samples read.
|
||||
*/
|
||||
myReader. getSamples (ofdmBuffer. data (),
|
||||
T_u, coarseOffset + fineCorrector);
|
||||
T_u, coarseOffset + fineOffset);
|
||||
//
|
||||
// and then, call upon the phase synchronizer to verify/compute
|
||||
// the real "first" sample
|
||||
startIndex = phaseSynchronizer. findIndex (ofdmBuffer);
|
||||
if (startIndex < 0) { // no sync, try again
|
||||
if (!f2Correction) {
|
||||
if (!correctionNeeded) {
|
||||
setSyncLost ();
|
||||
}
|
||||
goto notSynced;
|
||||
}
|
||||
|
||||
/**
|
||||
* Once here, we are synchronized, we need to copy the data we
|
||||
* used for synchronization for block 0
|
||||
@@ -238,13 +198,13 @@ Block_0:
|
||||
setSynced (true);
|
||||
myReader. getSamples (&((ofdmBuffer. data ()) [ofdmBufferIndex]),
|
||||
T_u - ofdmBufferIndex,
|
||||
coarseOffset + fineCorrector);
|
||||
coarseOffset + fineOffset);
|
||||
my_ofdmDecoder. processBlock_0 (ofdmBuffer);
|
||||
|
||||
// Here we look only at the block_0 when we need a coarse
|
||||
// frequency synchronization.
|
||||
f2Correction = !my_ficHandler. syncReached ();
|
||||
if (f2Correction) {
|
||||
correctionNeeded = !my_ficHandler. syncReached ();
|
||||
if (correctionNeeded) {
|
||||
int correction =
|
||||
phaseSynchronizer. estimate_CarrierOffset (ofdmBuffer);
|
||||
if (correction != 100) {
|
||||
@@ -264,39 +224,33 @@ Data_blocks:
|
||||
* corresponding samples in the datapart.
|
||||
*/
|
||||
FreqCorr = std::complex<float> (0, 0);
|
||||
for (ofdmSymbolCount = 1;
|
||||
ofdmSymbolCount < 4; ofdmSymbolCount ++) {
|
||||
myReader. getSamples (ofdmBuffer. data (),
|
||||
T_s, coarseOffset + fineCorrector);
|
||||
for (i = (int)T_u; i < (int)T_s; i ++)
|
||||
FreqCorr += ofdmBuffer [i] * conj (ofdmBuffer [i - T_u]);
|
||||
for (int ofdmSymbolCount = 1;
|
||||
ofdmSymbolCount < nrBlocks; ofdmSymbolCount ++) {
|
||||
std::vector<int16_t> ibits;
|
||||
ibits. resize (2 * params. get_carriers ());
|
||||
myReader. getSamples (ofdmBuffer. data (),
|
||||
T_s, coarseOffset + fineOffset);
|
||||
for (i = (int)T_u; i < (int)T_s; i ++)
|
||||
FreqCorr += ofdmBuffer [i] * conj (ofdmBuffer [i - T_u]);
|
||||
|
||||
my_ofdmDecoder. decodeFICblock (ofdmBuffer, ofdmSymbolCount);
|
||||
}
|
||||
|
||||
/// and similar for the (params -> L - 4) MSC blocks
|
||||
for (ofdmSymbolCount = 4;
|
||||
ofdmSymbolCount < (uint16_t)nrBlocks;
|
||||
ofdmSymbolCount ++) {
|
||||
myReader. getSamples (ofdmBuffer. data (),
|
||||
T_s, coarseOffset + fineCorrector);
|
||||
for (i = (int32_t)T_u; i < (int32_t)T_s; i ++)
|
||||
FreqCorr += ofdmBuffer [i] * conj (ofdmBuffer [i - T_u]);
|
||||
|
||||
my_ofdmDecoder. decodeMscblock (ofdmBuffer, ofdmSymbolCount);
|
||||
}
|
||||
if (ofdmSymbolCount < 4) {
|
||||
my_ofdmDecoder. decode (ofdmBuffer,
|
||||
ofdmSymbolCount, ibits. data ());
|
||||
my_ficHandler. process_ficBlock (ibits, ofdmSymbolCount);
|
||||
}
|
||||
my_mscHandler. process_Msc (&((ofdmBuffer. data ()) [T_g]),
|
||||
ofdmSymbolCount);
|
||||
}
|
||||
|
||||
NewOffset:
|
||||
// we integrate the newly found frequency error with the
|
||||
// existing frequency error.
|
||||
fineCorrector += 0.1 * arg (FreqCorr) / (2 * M_PI) * carrierDiff;
|
||||
fineOffset += 0.1 * arg (FreqCorr) / (2 * M_PI) * carrierDiff;
|
||||
//
|
||||
/**
|
||||
* OK, here we are at the end of the frame
|
||||
* Assume everything went well and skip T_null samples
|
||||
*/
|
||||
syncBufferIndex = 0;
|
||||
cLevel = 0;
|
||||
myReader. getSamples (ofdmBuffer. data (),
|
||||
T_null, coarseOffset);
|
||||
/**
|
||||
@@ -304,60 +258,53 @@ NewOffset:
|
||||
* samples ahead. Before going for the next frame, we
|
||||
* we just check the fineCorrector
|
||||
*/
|
||||
if (fineCorrector > carrierDiff / 2) {
|
||||
coarseOffset += carrierDiff;
|
||||
fineCorrector -= carrierDiff;
|
||||
if (fineOffset > carrierDiff / 2) {
|
||||
coarseOffset += carrierDiff;
|
||||
fineOffset -= carrierDiff;
|
||||
}
|
||||
else
|
||||
if (fineCorrector < -carrierDiff / 2) {
|
||||
if (fineOffset < -carrierDiff / 2) {
|
||||
coarseOffset -= carrierDiff;
|
||||
fineCorrector += carrierDiff;
|
||||
fineOffset += carrierDiff;
|
||||
}
|
||||
ReadyForNewFrame:
|
||||
/// and off we go, up to the next frame
|
||||
counter = 0;
|
||||
goto SyncOnPhase;
|
||||
}
|
||||
catch (int e) {
|
||||
// fprintf (stderr, "dabProcessor is stopping\n");
|
||||
;
|
||||
}
|
||||
theDevice -> stopReader ();
|
||||
my_ofdmDecoder. stop ();
|
||||
my_mscHandler. stop ();
|
||||
my_ficHandler. stop ();
|
||||
}
|
||||
|
||||
void dabProcessor:: reset (void) {
|
||||
myReader. setRunning (false);
|
||||
theDevice -> stopReader ();
|
||||
while (isRunning ())
|
||||
usleep (1000);
|
||||
usleep (10000);
|
||||
my_ofdmDecoder. stop ();
|
||||
my_mscHandler. reset ();
|
||||
my_ficHandler. reset ();
|
||||
QThread::start ();
|
||||
}
|
||||
|
||||
void dabProcessor::stop (void) {
|
||||
myReader. setRunning (false);
|
||||
theDevice -> restartReader ();
|
||||
while (isRunning ())
|
||||
usleep (1000);
|
||||
usleep (10000);
|
||||
my_ofdmDecoder. stop ();
|
||||
my_mscHandler. reset ();
|
||||
my_ficHandler. reset ();
|
||||
theDevice -> stopReader ();
|
||||
usleep (10000);
|
||||
my_ficHandler. reset ();
|
||||
}
|
||||
|
||||
void dabProcessor::coarseCorrectorOn (void) {
|
||||
f2Correction = true;
|
||||
correctionNeeded = true;
|
||||
coarseOffset = 0;
|
||||
}
|
||||
|
||||
void dabProcessor::coarseCorrectorOff (void) {
|
||||
f2Correction = false;
|
||||
correctionNeeded = false;
|
||||
}
|
||||
|
||||
// we could have derived the dab processor from fic and msc handlers,
|
||||
|
@@ -102,10 +102,10 @@ private:
|
||||
int32_t carriers;
|
||||
int32_t carrierDiff;
|
||||
std::vector<std::complex<float> > dataBuffer;
|
||||
int16_t fineCorrector;
|
||||
int16_t fineOffset;
|
||||
int32_t coarseOffset;
|
||||
|
||||
bool f2Correction;
|
||||
bool correctionNeeded;
|
||||
int32_t tokenCount;
|
||||
std::vector<std::complex<float> >ofdmBuffer;
|
||||
uint32_t ofdmBufferIndex;
|
||||
|
37
dabradio-1.0_resource.rc
Normal file
37
dabradio-1.0_resource.rc
Normal file
@@ -0,0 +1,37 @@
|
||||
#include <windows.h>
|
||||
|
||||
IDI_ICON1 ICON DISCARDABLE "/usr/shared/sdr-j-development/systems/dabradio/dabradio.ico"
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 0,0,0,0
|
||||
PRODUCTVERSION 0,0,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS VS_FF_DEBUG
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS VOS__WINDOWS32
|
||||
FILETYPE VFT_DLL
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "\0"
|
||||
VALUE "FileDescription", "\0"
|
||||
VALUE "FileVersion", "0.0.0.0\0"
|
||||
VALUE "LegalCopyright", "\0"
|
||||
VALUE "OriginalFilename", "dabradio-1.0.exe\0"
|
||||
VALUE "ProductName", "dabradio-1.0\0"
|
||||
VALUE "ProductVersion", "0.0.0.0\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x0409, 1200
|
||||
END
|
||||
END
|
||||
/* End of Version info */
|
||||
|
96
dabradio.pro
96
dabradio.pro
@@ -24,14 +24,16 @@ TRANSLATIONS = i18n/de_DE.ts i18n/it_IT.ts i18n/hu_HU.ts
|
||||
|
||||
DEPENDPATH += . \
|
||||
./src \
|
||||
./service-description \
|
||||
./includes \
|
||||
./src/ofdm \
|
||||
./src/backend \
|
||||
./src/backend/viterbi_768 \
|
||||
./src/backend/audio \
|
||||
./src/backend/data \
|
||||
./src/backend/data/mot \
|
||||
./src/output \
|
||||
./src/various \
|
||||
./src/support \
|
||||
./src/support/viterbi_768 \
|
||||
./devices \
|
||||
./devices/rawfiles \
|
||||
./devices/wavfiles \
|
||||
@@ -39,20 +41,24 @@ DEPENDPATH += . \
|
||||
./includes/backend \
|
||||
./includes/backend/audio \
|
||||
./includes/backend/data \
|
||||
./includes/backend/data/mot \
|
||||
./includes/output \
|
||||
./includes/various
|
||||
./includes/support \
|
||||
./includes/support/viterbi_768
|
||||
|
||||
INCLUDEPATH += . \
|
||||
./ \
|
||||
./src \
|
||||
./service-description \
|
||||
./includes \
|
||||
./includes/ofdm \
|
||||
./includes/backend \
|
||||
./includes/backend/viterbi_768 \
|
||||
./includes/backend/audio \
|
||||
./includes/backend/data \
|
||||
./includes/backend/data/mot \
|
||||
./includes/output \
|
||||
./includes/various \
|
||||
./includes/support \
|
||||
./includes/support/viterbi_768 \
|
||||
./devices \
|
||||
./devices/rawfiles \
|
||||
./devices/wavfiles
|
||||
@@ -60,20 +66,19 @@ INCLUDEPATH += . \
|
||||
# Input
|
||||
HEADERS += ./radio.h \
|
||||
./dab-processor.h \
|
||||
./service-list.h \
|
||||
./service-display.h \
|
||||
./service-description/service-descriptor.h \
|
||||
./service-description/audio-descriptor.h \
|
||||
./includes/dab-constants.h \
|
||||
./includes/country-codes.h \
|
||||
./includes/ofdm/timesyncer.h \
|
||||
./includes/ofdm/sample-reader.h \
|
||||
./includes/ofdm/ofdm-decoder.h \
|
||||
./includes/ofdm/phasereference.h \
|
||||
./includes/ofdm/phasetable.h \
|
||||
./includes/ofdm/freq-interleaver.h \
|
||||
# ./includes/backend/viterbi.h \
|
||||
./includes/backend/viterbi_768/viterbi-768.h \
|
||||
./includes/backend/fic-handler.h \
|
||||
./includes/ofdm/fic-handler.h \
|
||||
./includes/ofdm/fib-processor.h \
|
||||
./includes/backend/msc-handler.h \
|
||||
./includes/backend/fib-processor.h \
|
||||
./includes/backend/galois.h \
|
||||
./includes/backend/reed-solomon.h \
|
||||
./includes/backend/rscodec.h \
|
||||
@@ -89,9 +94,9 @@ HEADERS += ./radio.h \
|
||||
./includes/backend/data/data-processor.h \
|
||||
./includes/backend/data/pad-handler.h \
|
||||
./includes/backend/data/virtual-datahandler.h \
|
||||
./includes/backend/data/mot-handler.h \
|
||||
./includes/backend/data/mot-dir.h \
|
||||
./includes/backend/data/mot-object.h \
|
||||
./includes/backend/data/mot/mot-handler.h \
|
||||
./includes/backend/data/mot/mot-object.h \
|
||||
./includes/backend/data/mot/mot-dir.h \
|
||||
./includes/backend/protection.h \
|
||||
./includes/backend/eep-protection.h \
|
||||
./includes/backend/uep-protection.h \
|
||||
@@ -99,36 +104,38 @@ HEADERS += ./radio.h \
|
||||
./includes/output/audio-base.h \
|
||||
./includes/output/newconverter.h \
|
||||
./includes/output/audiosink.h \
|
||||
./includes/various/fft-handler.h \
|
||||
./includes/various/ringbuffer.h \
|
||||
./includes/various/Xtan2.h \
|
||||
./includes/various/dab-params.h \
|
||||
./includes/various/band-handler.h \
|
||||
./includes/various/text-mapper.h \
|
||||
./includes/support/viterbi_768/viterbi-768.h \
|
||||
./includes/support/fft-handler.h \
|
||||
./includes/support/ringbuffer.h \
|
||||
./includes/support/Xtan2.h \
|
||||
./includes/support/dab-params.h \
|
||||
./includes/support/band-handler.h \
|
||||
./includes/support/text-mapper.h \
|
||||
./includes/support/dab_tables.h \
|
||||
./devices/virtual-input.h \
|
||||
./devices/rawfiles/rawfiles.h \
|
||||
./devices/wavfiles/wavfiles.h
|
||||
|
||||
FORMS += ./devices/filereader-widget.ui
|
||||
FORMS += ./devices/filereader-widget.ui \
|
||||
./forms/audio-description.ui
|
||||
|
||||
SOURCES += ./main.cpp \
|
||||
./radio.cpp \
|
||||
./dab-processor.cpp \
|
||||
./service-list.cpp \
|
||||
./service-display.cpp \
|
||||
./service-description/service-descriptor.cpp \
|
||||
./service-description/audio-descriptor.cpp \
|
||||
./src/ofdm/timesyncer.cpp \
|
||||
./src/ofdm/sample-reader.cpp \
|
||||
./src/ofdm/ofdm-decoder.cpp \
|
||||
./src/ofdm/phasereference.cpp \
|
||||
./src/ofdm/phasetable.cpp \
|
||||
./src/ofdm/freq-interleaver.cpp \
|
||||
# ./src/backend/viterbi.cpp \
|
||||
./src/backend/viterbi_768/viterbi-768.cpp \
|
||||
./src/backend/fic-handler.cpp \
|
||||
./src/ofdm/fic-handler.cpp \
|
||||
./src/ofdm/fib-processor.cpp \
|
||||
./src/backend/msc-handler.cpp \
|
||||
./src/backend/protection.cpp \
|
||||
./src/backend/eep-protection.cpp \
|
||||
./src/backend/uep-protection.cpp \
|
||||
./src/backend/fib-processor.cpp \
|
||||
./src/backend/galois.cpp \
|
||||
./src/backend/reed-solomon.cpp \
|
||||
./src/backend/rscodec.cpp \
|
||||
@@ -145,18 +152,19 @@ SOURCES += ./main.cpp \
|
||||
./src/backend/data/pad-handler.cpp \
|
||||
./src/backend/data/data-processor.cpp \
|
||||
./src/backend/data/virtual-datahandler.cpp \
|
||||
./src/backend/data/mot-handler.cpp \
|
||||
./src/backend/data/mot-dir.cpp \
|
||||
./src/backend/data/mot-object.cpp \
|
||||
# ./src/output/fir-filters.cpp \
|
||||
./src/backend/data/mot/mot-handler.cpp \
|
||||
./src/backend/data/mot/mot-object.cpp \
|
||||
./src/backend/data/mot/mot-dir.cpp \
|
||||
./src/output/audio-base.cpp \
|
||||
./src/output/newconverter.cpp \
|
||||
./src/output/audiosink.cpp \
|
||||
./src/various/fft-handler.cpp \
|
||||
./src/various/Xtan2.cpp \
|
||||
./src/various/dab-params.cpp \
|
||||
./src/various/band-handler.cpp \
|
||||
./src/various/text-mapper.cpp \
|
||||
./src/support/viterbi_768/viterbi-768.cpp \
|
||||
./src/support/fft-handler.cpp \
|
||||
./src/support/Xtan2.cpp \
|
||||
./src/support/dab-params.cpp \
|
||||
./src/support/band-handler.cpp \
|
||||
./src/support/text-mapper.cpp \
|
||||
./src/support/dab_tables.cpp \
|
||||
./devices/virtual-input.cpp \
|
||||
./devices/rawfiles/rawfiles.cpp \
|
||||
./devices/wavfiles/wavfiles.cpp
|
||||
@@ -346,8 +354,8 @@ NEON_RPI2 {
|
||||
DEFINES += NEON_AVAILABLE
|
||||
QMAKE_CFLAGS += -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4
|
||||
QMAKE_CXXFLAGS += -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4
|
||||
HEADERS += ./src/backend/viterbi_768/spiral-neon.h
|
||||
SOURCES += ./src/backend/viterbi_768/spiral-neon.c
|
||||
HEADERS += ./src/support/viterbi_768/spiral-neon.h
|
||||
SOURCES += ./src/support/viterbi_768/spiral-neon.c
|
||||
}
|
||||
|
||||
# for RPI3 use:
|
||||
@@ -355,18 +363,18 @@ NEON_RPI3 {
|
||||
DEFINES += NEON_AVAILABLE
|
||||
# QMAKE_CFLAGS += -mcpu=cortex-a53 -mfloat-abi=hard -mfpu=neon-fp-armv8 -mneon-for-64bits
|
||||
# QMAKE_CXXFLAGS += -mcpu=cortex-a53 -mfloat-abi=hard -mfpu=neon-fp-armv8 -mneon-for-64bits
|
||||
HEADERS += ./src/backend/viterbi_768/spiral-neon.h
|
||||
SOURCES += ./src/backend/viterbi_768/spiral-neon.c
|
||||
HEADERS += ./src/support/viterbi_768/spiral-neon.h
|
||||
SOURCES += ./src/support/viterbi_768/spiral-neon.c
|
||||
}
|
||||
|
||||
SSE {
|
||||
DEFINES += SSE_AVAILABLE
|
||||
HEADERS += ./src/backend/viterbi_768/spiral-sse.h
|
||||
SOURCES += ./src/backend/viterbi_768/spiral-sse.c
|
||||
HEADERS += ./src/support/viterbi_768/spiral-sse.h
|
||||
SOURCES += ./src/support/viterbi_768/spiral-sse.c
|
||||
}
|
||||
|
||||
NO_SSE {
|
||||
HEADERS += ./src/backend/viterbi_768/spiral-no-sse.h
|
||||
SOURCES += ./src/backend/viterbi_768/spiral-no-sse.c
|
||||
HEADERS += ./src/support/viterbi_768/spiral-no-sse.h
|
||||
SOURCES += ./src/support/viterbi_768/spiral-no-sse.c
|
||||
}
|
||||
|
||||
|
327
forms/audio-description.ui
Normal file
327
forms/audio-description.ui
Normal file
@@ -0,0 +1,327 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>audioDescription</class>
|
||||
<widget class="QWidget" name="audioDescription">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>329</width>
|
||||
<height>311</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>audio description</string>
|
||||
</property>
|
||||
<widget class="QLabel" name="serviceName">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>50</y>
|
||||
<width>151</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>DejaVu Sans Mono</family>
|
||||
<pointsize>10</pointsize>
|
||||
<weight>75</weight>
|
||||
<italic>true</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="subChannelId">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>130</x>
|
||||
<y>140</y>
|
||||
<width>111</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="startAddress">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>130</x>
|
||||
<y>160</y>
|
||||
<width>171</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="Length">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>130</x>
|
||||
<y>180</y>
|
||||
<width>171</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>200</y>
|
||||
<width>101</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>bitRate</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="protectionLevel">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>130</x>
|
||||
<y>220</y>
|
||||
<width>161</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="programType">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>130</x>
|
||||
<y>240</y>
|
||||
<width>161</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="Language">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>130</x>
|
||||
<y>260</y>
|
||||
<width>181</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>140</y>
|
||||
<width>111</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>subchannel Id</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>160</y>
|
||||
<width>91</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Start Address</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>180</y>
|
||||
<width>81</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Length</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="bitrate">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>130</x>
|
||||
<y>200</y>
|
||||
<width>59</width>
|
||||
<height>15</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>220</y>
|
||||
<width>101</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Protection level</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>240</y>
|
||||
<width>111</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>ProgramType</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>260</y>
|
||||
<width>91</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Language</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="dabType">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>200</x>
|
||||
<y>50</y>
|
||||
<width>81</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>DejaVu Sans Mono</family>
|
||||
<pointsize>10</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>20</y>
|
||||
<width>161</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>DejaVu Sans Mono</family>
|
||||
<pointsize>11</pointsize>
|
||||
<weight>75</weight>
|
||||
<italic>true</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>audio service</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>80</y>
|
||||
<width>141</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>received on channel</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="channelLabel">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>170</x>
|
||||
<y>80</y>
|
||||
<width>81</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>DejaVu Sans Mono</family>
|
||||
<pointsize>11</pointsize>
|
||||
<weight>75</weight>
|
||||
<italic>true</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>120</y>
|
||||
<width>101</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>serviceId</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="serviceLabel">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>130</x>
|
||||
<y>120</y>
|
||||
<width>59</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@@ -345,6 +345,9 @@
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Reset button. Press this and a scan is made over all channels in the selected band (BAND III by default)</p><p>to collect data on available services in these channels.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>reset</string>
|
||||
</property>
|
||||
@@ -377,6 +380,9 @@
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Synchronization indicator. Greem means sync is OK</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
|
@@ -29,6 +29,8 @@
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
#include <QDir>
|
||||
#include <map>
|
||||
#include <iterator>
|
||||
#ifdef TRY_EPG
|
||||
#include "epgdec.h"
|
||||
#endif
|
||||
@@ -64,12 +66,11 @@ private:
|
||||
int contentType;
|
||||
int contentsubType;
|
||||
QString name;
|
||||
bool marked [128];
|
||||
QByteArray segments [128];
|
||||
void handleComplete (void);
|
||||
#ifdef TRY_EPG
|
||||
CEPGDecoder epgHandler;
|
||||
CEPGDecoder epgHandler;
|
||||
#endif
|
||||
std::map<int, QByteArray> motMap;
|
||||
|
||||
signals:
|
||||
void the_picture (QByteArray, int, QString);
|
@@ -42,9 +42,9 @@ private:
|
||||
void handle_variablePAD (uint8_t *, int16_t, uint8_t);
|
||||
void handle_shortPAD (uint8_t *, int16_t, uint8_t);
|
||||
void dynamicLabel (uint8_t *, int16_t, uint8_t);
|
||||
void new_MSC_element (std::vector<uint8_t>, int);
|
||||
void new_MSC_element (std::vector<uint8_t>);
|
||||
void add_MSC_element (std::vector<uint8_t>);
|
||||
void build_MSC_segment (std::vector<uint8_t>, int);
|
||||
void build_MSC_segment (std::vector<uint8_t>);
|
||||
bool pad_crc (uint8_t *, int16_t);
|
||||
QString picturePath;
|
||||
QString dynamicLabelText;
|
||||
@@ -61,11 +61,6 @@ private:
|
||||
// dataGroupLength is set when having processed an appType 1
|
||||
int dataGroupLength;
|
||||
//
|
||||
// msc_dataGroupLength is used while assembling an msc_data group,
|
||||
// in the end it should be equal or somewhat larger than dataGroupLength
|
||||
int msc_dataGroupLength;
|
||||
|
||||
//
|
||||
// The msc_dataGroupBuffer is - as the name suggests - used for
|
||||
// assembling the msc_data group.
|
||||
std::vector<uint8_t> msc_dataGroupBuffer;
|
||||
|
@@ -23,26 +23,33 @@
|
||||
#ifndef __MSC_HANDLER__
|
||||
#define __MSC_HANDLER__
|
||||
|
||||
#include <QThread>
|
||||
#include <QWaitCondition>
|
||||
#include <QMutex>
|
||||
#include <QSemaphore>
|
||||
#include <atomic>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
#include <atomic>
|
||||
#include "dab-constants.h"
|
||||
#include "ringbuffer.h"
|
||||
#include "dab-params.h"
|
||||
#include "fft-handler.h"
|
||||
#include "ringbuffer.h"
|
||||
#include "phasetable.h"
|
||||
#include "freq-interleaver.h"
|
||||
|
||||
class RadioInterface;
|
||||
class virtualBackend;
|
||||
|
||||
class mscHandler {
|
||||
class mscHandler: public QThread {
|
||||
public:
|
||||
mscHandler (RadioInterface *,
|
||||
uint8_t,
|
||||
QString);
|
||||
~mscHandler (void);
|
||||
void process_mscBlock (std::vector<int16_t>, int16_t);
|
||||
void processBlock_0 (std::complex<float> *);
|
||||
void process_Msc (std::complex<float> *, int);
|
||||
void set_audioChannel (audiodata *,
|
||||
RingBuffer<int16_t> *);
|
||||
void set_dataChannel (packetdata *,
|
||||
@@ -55,10 +62,17 @@ public:
|
||||
// This function will kill
|
||||
void stop (void);
|
||||
private:
|
||||
void process_mscBlock (std::vector<int16_t>, int16_t);
|
||||
|
||||
RadioInterface *myRadioInterface;
|
||||
RingBuffer<uint8_t> *dataBuffer;
|
||||
QString picturesPath;
|
||||
dabParams params;
|
||||
fftHandler my_fftHandler;
|
||||
std::complex<float> *fft_buffer;
|
||||
std::vector<complex<float>> phaseReference;
|
||||
|
||||
interLeaver myMapper;
|
||||
QMutex locker;
|
||||
bool audioService;
|
||||
std::vector<virtualBackend *>theBackends;
|
||||
@@ -83,9 +97,17 @@ private:
|
||||
int16_t BitsperBlock;
|
||||
int16_t numberofblocksperCIF;
|
||||
int16_t blockCount;
|
||||
|
||||
int16_t **interleaveData;
|
||||
int16_t interleaverIndex;
|
||||
void run (void);
|
||||
std::atomic<bool> running;
|
||||
std::vector<std::vector<std::complex<float>>> command;
|
||||
int16_t amount;
|
||||
int16_t currentBlock;
|
||||
void processBlock_0 (void);
|
||||
void processMsc (int32_t n);
|
||||
QSemaphore bufferSpace;
|
||||
QWaitCondition commandHandler;
|
||||
QMutex helper;
|
||||
int nrBlocks;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
71
includes/ofdm/fic-handler.h
Normal file
71
includes/ofdm/fic-handler.h
Normal file
@@ -0,0 +1,71 @@
|
||||
#
|
||||
/*
|
||||
* Copyright (C) 2013 .. 2017
|
||||
* Jan van Katwijk (J.vanKatwijk@gmail.com)
|
||||
* Lazy Chair Computing
|
||||
*
|
||||
* This file is part of Qt-DAB
|
||||
* Qt-DAB 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.
|
||||
*
|
||||
* Qt-DAB 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 Qt-DAB; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#
|
||||
/*
|
||||
* FIC data
|
||||
*/
|
||||
#ifndef __FIC_HANDLER__
|
||||
#define __FIC_HANDLER__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include "viterbi-768.h"
|
||||
#include <QObject>
|
||||
#include "fib-processor.h"
|
||||
#include "dab-params.h"
|
||||
|
||||
|
||||
class RadioInterface;
|
||||
|
||||
class ficHandler: public fib_processor {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ficHandler (RadioInterface *, uint8_t);
|
||||
~ficHandler (void);
|
||||
void process_ficBlock (std::vector<int16_t>, int16_t);
|
||||
void stop (void);
|
||||
void reset (void);
|
||||
private:
|
||||
viterbi_768 myViterbi;
|
||||
dabParams params;
|
||||
uint8_t bitBuffer_out [768];
|
||||
int16_t ofdm_input [2304];
|
||||
bool punctureTable [3072 + 24];
|
||||
|
||||
void process_ficInput (int16_t);
|
||||
int16_t index;
|
||||
int16_t BitsperBlock;
|
||||
int16_t ficno;
|
||||
int16_t ficBlocks;
|
||||
int16_t ficMissed;
|
||||
int16_t ficRatio;
|
||||
uint16_t convState;
|
||||
uint8_t PRBS [768];
|
||||
uint8_t shiftRegister [9];
|
||||
signals:
|
||||
void show_ficSuccess (bool);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
@@ -41,67 +41,50 @@
|
||||
#include "dab-params.h"
|
||||
|
||||
class RadioInterface;
|
||||
class ficHandler;
|
||||
class mscHandler;
|
||||
|
||||
#ifdef __THREADED_DECODING
|
||||
class ofdmDecoder: public QThread {
|
||||
#else
|
||||
class ofdmDecoder: public QObject {
|
||||
#endif
|
||||
Q_OBJECT
|
||||
public:
|
||||
ofdmDecoder (RadioInterface *,
|
||||
uint8_t,
|
||||
int16_t,
|
||||
ficHandler *,
|
||||
mscHandler *);
|
||||
RingBuffer<std::complex<float>> *ifBuffer = nullptr);
|
||||
|
||||
~ofdmDecoder (void);
|
||||
void processBlock_0 (std::vector<std::complex<float> >);
|
||||
void decodeFICblock (std::vector<std::complex<float> >, int32_t n);
|
||||
void decodeMscblock (std::vector<std::complex<float> >, int32_t n);
|
||||
void decode (std::vector<std::complex<float> >,
|
||||
int32_t n, int16_t *);
|
||||
|
||||
int16_t get_snr (std::complex<float> *);
|
||||
void stop (void);
|
||||
void reset (void);
|
||||
#ifndef __THREADED_DECODING
|
||||
void start (void);
|
||||
#endif
|
||||
private:
|
||||
RadioInterface *myRadioInterface;
|
||||
dabParams params;
|
||||
fftHandler my_fftHandler;
|
||||
ficHandler *my_ficHandler;
|
||||
mscHandler *my_mscHandler;
|
||||
#ifdef __THREADED_DECODING
|
||||
void run (void);
|
||||
std::atomic<bool> running;
|
||||
std::complex<float> **command;
|
||||
int16_t amount;
|
||||
int16_t currentBlock;
|
||||
void processBlock_0 (void);
|
||||
void decodeFICblock (int32_t n);
|
||||
void decodeMscblock (int32_t n);
|
||||
QSemaphore bufferSpace;
|
||||
QWaitCondition commandHandler;
|
||||
QMutex helper;
|
||||
#endif
|
||||
int32_t T_s;
|
||||
int32_t T_u;
|
||||
int32_t T_g;
|
||||
int32_t nrBlocks;
|
||||
int32_t carriers;
|
||||
int16_t getMiddle (void);
|
||||
std::vector<complex<float>> phaseReference;
|
||||
std::vector<int16_t> ibits;
|
||||
std::complex<float> *fft_buffer;
|
||||
interLeaver myMapper;
|
||||
phaseTable *phasetable;
|
||||
int32_t blockIndex;
|
||||
int16_t snrCount;
|
||||
int16_t snr;
|
||||
RadioInterface *myRadioInterface;
|
||||
dabParams params;
|
||||
fftHandler my_fftHandler;
|
||||
interLeaver myMapper;
|
||||
|
||||
RingBuffer<std::complex<float>> *iqBuffer;
|
||||
float computeQuality (std::complex<float> *);
|
||||
int32_t T_s;
|
||||
int32_t T_u;
|
||||
int32_t T_g;
|
||||
int32_t nrBlocks;
|
||||
int32_t carriers;
|
||||
int16_t getMiddle (void);
|
||||
std::vector<complex<float>> phaseReference;
|
||||
std::vector<int16_t> ibits;
|
||||
std::complex<float> *fft_buffer;
|
||||
phaseTable *phasetable;
|
||||
int32_t blockIndex;
|
||||
int16_t snrCount;
|
||||
int16_t snr;
|
||||
int16_t maxSignal;
|
||||
signals:
|
||||
void show_snr (int);
|
||||
void showIQ (int);
|
||||
void showQuality (float);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -38,10 +38,9 @@ Q_OBJECT
|
||||
public:
|
||||
phaseReference (RadioInterface *,
|
||||
uint8_t,
|
||||
#ifdef IMPULSE_RESPONSE
|
||||
RingBuffer<float> *b,
|
||||
#endif
|
||||
int16_t, int16_t);
|
||||
int16_t,
|
||||
int16_t,
|
||||
RingBuffer<float> *b = NULL);
|
||||
~phaseReference (void);
|
||||
int32_t findIndex (std::vector<std::complex<float>>);
|
||||
int16_t estimate_CarrierOffset (std::vector<std::complex<float>>);
|
||||
@@ -52,9 +51,7 @@ public:
|
||||
private:
|
||||
fftHandler my_fftHandler;
|
||||
dabParams params;
|
||||
#ifdef IMPULSE_RESPONSE
|
||||
RingBuffer<float> *response;
|
||||
#endif
|
||||
std::vector<float> phaseDifferences;
|
||||
int16_t threshold;
|
||||
int16_t diff_length;
|
||||
|
@@ -45,7 +45,8 @@ class sampleReader : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
sampleReader (RadioInterface *mr,
|
||||
virtualInput *theRig);
|
||||
virtualInput *theRig
|
||||
,RingBuffer<std::complex<float>> *spectrumBuffer = NULL);
|
||||
|
||||
~sampleReader (void);
|
||||
void setRunning (bool b);
|
||||
@@ -59,6 +60,7 @@ public:
|
||||
private:
|
||||
RadioInterface *myRadioInterface;
|
||||
virtualInput *theRig;
|
||||
RingBuffer<std::complex<float>> *spectrumBuffer;
|
||||
std::vector<std::complex<float>> localBuffer;
|
||||
int32_t localCounter;
|
||||
int32_t bufferSize;
|
||||
|
24
includes/ofdm/timesyncer.h
Normal file
24
includes/ofdm/timesyncer.h
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
#ifndef __TIMESYNCER__
|
||||
#define __TIMESYNCER__
|
||||
|
||||
#include "dab-constants.h"
|
||||
|
||||
#define TIMESYNC_ESTABLISHED 0100
|
||||
#define NO_DIP_FOUND 0101
|
||||
#define NO_END_OF_DIP_FOUND 0102
|
||||
|
||||
class sampleReader;
|
||||
|
||||
class timeSyncer {
|
||||
public:
|
||||
timeSyncer (sampleReader *mr);
|
||||
~timeSyncer (void);
|
||||
int sync (int, int);
|
||||
private:
|
||||
sampleReader *myReader;
|
||||
int32_t syncBufferIndex = 0;
|
||||
const int32_t syncBufferSize = 4096;
|
||||
};
|
||||
#endif
|
||||
|
16
includes/support/dab_tables.h
Normal file
16
includes/support/dab_tables.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
const char * getASCTy (int16_t ASCTy);
|
||||
const char * getDSCTy (int16_t DSCTy);
|
||||
const char * getLanguage (int16_t language);
|
||||
const char * getCountry (uint8_t ecc, uint8_t countryId);
|
||||
const char * getProgramType_Not_NorthAmerica(int16_t programType);
|
||||
const char * getProgramType_For_NorthAmerica(int16_t programType);
|
||||
const char * getProgramType(bool, uint8_t interTabId, int16_t programType);
|
||||
const char * getUserApplicationType(int16_t appType);
|
||||
const char * getFECscheme(int16_t FEC_scheme);
|
||||
const char * getProtectionLevel (bool shortForm, int16_t protLevel);
|
||||
const char * getCodeRate (bool shortForm, int16_t protLevel);
|
||||
|
170
radio.cpp
170
radio.cpp
@@ -29,11 +29,12 @@
|
||||
#include <numeric>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
#include <QMouseEvent>
|
||||
#include "radio.h"
|
||||
#include "band-handler.h"
|
||||
#include "audiosink.h"
|
||||
#include "audio-descriptor.h"
|
||||
#include <mutex>
|
||||
#include "service-display.h"
|
||||
|
||||
/**
|
||||
* We use the creation function merely to set up the
|
||||
@@ -61,11 +62,6 @@ int gain;
|
||||
scanning = false;
|
||||
isSynced = UNSYNCED;
|
||||
audioBuffer = new RingBuffer<int16_t>(16 * 32768);
|
||||
|
||||
/** threshold is used in the phaseReference class
|
||||
* as threshold for checking the validity of the correlation result
|
||||
* 3 is a reasonable value
|
||||
*/
|
||||
threshold =
|
||||
dabSettings -> value ("threshold", 3). toInt ();
|
||||
//
|
||||
@@ -82,7 +78,6 @@ int gain;
|
||||
dabMode = 1;
|
||||
|
||||
dataBuffer = new RingBuffer<uint8_t>(32768);
|
||||
currentName = QString ("");
|
||||
|
||||
saveSlides = dabSettings -> value ("saveSlides", 1). toInt ();
|
||||
showSlides = dabSettings -> value ("showPictures", 1). toInt ();
|
||||
@@ -127,8 +122,9 @@ int gain;
|
||||
|
||||
copyrightLabel -> setToolTip (versionText);
|
||||
|
||||
ensembleDisplay = new serviceList (this, serviceNames);
|
||||
ensembleDisplay = new QListView (NULL);
|
||||
ensembleDisplay -> show ();
|
||||
ensembleDisplay -> setToolTip ("Right clicking on a service name will make some technical details on the selected service visible");
|
||||
|
||||
soundOut = new audioSink (latency);
|
||||
((audioSink *)soundOut) -> setupChannels (streamoutSelector);
|
||||
@@ -167,15 +163,11 @@ int gain;
|
||||
my_dabProcessor = new dabProcessor (this,
|
||||
inputDevice,
|
||||
dabMode,
|
||||
threshold, diff_length,
|
||||
threshold,
|
||||
diff_length,
|
||||
picturesPath);
|
||||
connect (my_dabProcessor, SIGNAL (setSynced (char)),
|
||||
this, SLOT (setSynced (char)));
|
||||
|
||||
//
|
||||
serviceDescriptor *ss = new serviceDescriptor (" ", " ");
|
||||
services. resize (1);
|
||||
services [0] = ss; // a dummy
|
||||
//
|
||||
connect (gainSlider, SIGNAL (valueChanged (int)),
|
||||
this, SLOT (handle_gainSlider (int)));
|
||||
@@ -183,7 +175,14 @@ int gain;
|
||||
this, SLOT (handle_autoButton (void)));
|
||||
|
||||
serviceCharacteristics = NULL;
|
||||
secondsTimer. setInterval (1000);
|
||||
connect (&secondsTimer, SIGNAL (timeout (void)),
|
||||
this, SLOT (updateTime (void)));
|
||||
secondsTimer. start (1000);
|
||||
|
||||
startScanning ();
|
||||
qApp -> installEventFilter (this);
|
||||
serviceDescription = NULL;
|
||||
}
|
||||
|
||||
RadioInterface::~RadioInterface (void) {
|
||||
@@ -199,9 +198,6 @@ void RadioInterface:: startScanning (void) {
|
||||
this, SLOT (nextChannel (void)));
|
||||
disconnect (my_dabProcessor, SIGNAL (No_Signal_Found (void)),
|
||||
this, SLOT (nextChannel (void)));
|
||||
disconnect (ensembleDisplay,
|
||||
SIGNAL (newService (const QString &, const QString &)),
|
||||
this, SLOT (selectService (const QString &, const QString &)));
|
||||
serviceCount = 0;
|
||||
serviceCountDisplay -> display (serviceCount);
|
||||
channelNumber = 0;
|
||||
@@ -222,9 +218,6 @@ void RadioInterface:: startScanning (void) {
|
||||
this, SLOT (nextChannel (void)));
|
||||
disconnect (my_dabProcessor, SIGNAL (No_Signal_Found (void)),
|
||||
this, SLOT (nextChannel (void)));
|
||||
connect (ensembleDisplay,
|
||||
SIGNAL (newService (const QString &, const QString &)),
|
||||
this, SLOT (selectService (const QString &, const QString &)));
|
||||
connect (resetButton, SIGNAL (clicked (void)),
|
||||
this, SLOT (reset (void)));
|
||||
return;
|
||||
@@ -234,10 +227,6 @@ void RadioInterface:: startScanning (void) {
|
||||
QString text = "scanning ch ";
|
||||
text. append (theBand -> channel (channelNumber. load ()));
|
||||
set_ensembleName (text);
|
||||
ensembleDisplay -> reset ();
|
||||
services. resize (1);
|
||||
serviceDescriptor *ss = new serviceDescriptor (" ", " ");
|
||||
services [0] = ss; // a dummy
|
||||
int tunedFrequency =
|
||||
theBand -> Frequency (channelNumber. load ());
|
||||
connect (&signalTimer, SIGNAL (timeout (void)),
|
||||
@@ -275,8 +264,8 @@ void RadioInterface::nextChannel (void) {
|
||||
serviceLabel -> setText ("select a services");
|
||||
serviceLabel -> setStyleSheet ("QLabel {background-color : green}");
|
||||
connect (ensembleDisplay,
|
||||
SIGNAL (newService (const QString &, const QString &)),
|
||||
this, SLOT (selectService (const QString &, const QString &)));
|
||||
SIGNAL (clicked (QModelIndex)),
|
||||
this, SLOT (selectService (QModelIndex)));
|
||||
connect (resetButton, SIGNAL (clicked (void)),
|
||||
this, SLOT (reset (void)));
|
||||
return;
|
||||
@@ -298,14 +287,25 @@ void RadioInterface::nextChannel (void) {
|
||||
void RadioInterface::reset (void) {
|
||||
my_dabProcessor -> stop ();
|
||||
disconnect (ensembleDisplay,
|
||||
SIGNAL (newService (const QString &, const QString &)),
|
||||
this, SLOT (selectService (const QString &, const QString &)));
|
||||
SIGNAL (clicked (QModelIndex)),
|
||||
this, SLOT (selectService (QModelIndex)));
|
||||
disconnect (resetButton, SIGNAL (clicked (void)),
|
||||
this, SLOT (reset (void)));
|
||||
for (int i = 0; i < channels; i ++) {
|
||||
QString channel = theBand -> channel (i);
|
||||
dabSettings -> setValue (channel, 1);
|
||||
}
|
||||
if (serviceDescription != NULL)
|
||||
delete serviceDescription;
|
||||
serviceDescription = NULL;
|
||||
Services = QStringList ();
|
||||
ensemble. setStringList (Services);
|
||||
ensembleDisplay -> setModel (&ensemble);
|
||||
for (std::map<QString, serviceDescriptor *>
|
||||
::iterator it = serviceMap. begin ();
|
||||
it != serviceMap. end (); it ++)
|
||||
delete (it -> second);
|
||||
serviceMap. clear ();
|
||||
startScanning ();
|
||||
}
|
||||
//
|
||||
@@ -314,7 +314,8 @@ void RadioInterface::reset (void) {
|
||||
// when setting the channel for selecting a service in
|
||||
// the large list
|
||||
void RadioInterface::addtoEnsemble (const QString &s) {
|
||||
if (!scanning && (services. size () > 0))
|
||||
if (!scanning)
|
||||
// if (!scanning && (services. size () > 0))
|
||||
return;
|
||||
|
||||
if (scanning) {
|
||||
@@ -329,12 +330,14 @@ void RadioInterface::addtoEnsemble (const QString &s) {
|
||||
new serviceDescriptor (t,
|
||||
channel,
|
||||
&d);
|
||||
services. push_back (service);
|
||||
ensembleDisplay -> addRow (t,
|
||||
channel,
|
||||
QString::number (d. bitRate),
|
||||
service -> programType);
|
||||
Services << s;
|
||||
|
||||
Services. removeDuplicates ();
|
||||
ensemble. setStringList (Services);
|
||||
ensembleDisplay -> setModel (&ensemble);
|
||||
|
||||
dabSettings -> setValue (channel, 1);
|
||||
serviceMap. insert (mapElement (t, service));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -425,6 +428,26 @@ void RadioInterface::show_motHandling (bool b) {
|
||||
setColor (motLabel, b);
|
||||
}
|
||||
|
||||
void RadioInterface::showSpectrum (int s) {
|
||||
(void)s;
|
||||
}
|
||||
|
||||
void RadioInterface::showIQ (int s) {
|
||||
(void)s;
|
||||
}
|
||||
|
||||
void RadioInterface::showQuality (float f) {
|
||||
(void)f;
|
||||
}
|
||||
|
||||
void RadioInterface::show_snr (int s) {
|
||||
(void)s;
|
||||
}
|
||||
|
||||
void RadioInterface::set_CorrectorDisplay (int c) {
|
||||
(void)c;
|
||||
}
|
||||
|
||||
void RadioInterface::show_frameErrors (int e) {
|
||||
emit set_quality (e);
|
||||
}
|
||||
@@ -520,7 +543,10 @@ void RadioInterface::showMOT (QByteArray data,
|
||||
}
|
||||
}
|
||||
//
|
||||
//
|
||||
void RadioInterface::showImpulse (int a) {
|
||||
(void)a;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief changeinConfiguration
|
||||
@@ -571,6 +597,8 @@ void RadioInterface::TerminateProcess (void) {
|
||||
fprintf (stderr, "deleted dabProcessor\n");
|
||||
if (ensembleDisplay != NULL)
|
||||
delete ensembleDisplay;
|
||||
if (serviceDescription != NULL)
|
||||
delete serviceDescription;
|
||||
if (pictureLabel != NULL)
|
||||
delete pictureLabel;
|
||||
pictureLabel = NULL; // signals may be pending, so careful
|
||||
@@ -580,61 +608,59 @@ void RadioInterface::TerminateProcess (void) {
|
||||
fprintf (stderr, ".. end the radio silences\n");
|
||||
}
|
||||
|
||||
|
||||
void RadioInterface::updateTimeDisplay (void) {
|
||||
time_t now = time (0);
|
||||
char * dt = ctime (&now);
|
||||
timeDisplay -> setText (QString (dt));
|
||||
}
|
||||
//
|
||||
// Signals from the GUI
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Selecting a service is easy, the fib is asked to
|
||||
// hand over the relevant data in two steps
|
||||
void RadioInterface::selectService (const QString ¤tProgram,
|
||||
const QString &channel) {
|
||||
void RadioInterface::selectService (QModelIndex ind ) {
|
||||
if (scanning) // be polite, wait until we finished scanning
|
||||
return;
|
||||
|
||||
if (serviceCharacteristics != NULL)
|
||||
delete serviceCharacteristics;
|
||||
QString currentProgram = ensemble. data (ind, Qt::DisplayRole). toString ();
|
||||
|
||||
running. store (true);
|
||||
serviceLabel -> setStyleSheet ("QLabel {background-color : white}");
|
||||
serviceLabel -> setText (currentProgram);
|
||||
services [0] = new serviceDescriptor (currentProgram, channel);
|
||||
|
||||
std::map<QString, serviceDescriptor *>::iterator it;
|
||||
it = serviceMap. find (currentProgram);
|
||||
if (it == serviceMap. end ())
|
||||
return;
|
||||
serviceDescriptor *sd = it -> second;
|
||||
fprintf (stderr, "channel = %s, currentChannel %s\n",
|
||||
channel. toLatin1 (). data (),
|
||||
sd -> channel. toLatin1 (). data (),
|
||||
selectedChannel. toLatin1 (). data ());
|
||||
if (selectedChannel != channel) {
|
||||
if (selectedChannel != sd -> channel) {
|
||||
my_dabProcessor -> stop ();
|
||||
connect (&channelTimer, SIGNAL (timeout (void)),
|
||||
this, SLOT (channelTimer_timeout (void)));
|
||||
channelTimer. start (5000);
|
||||
int tunedFrequency = theBand -> Frequency (channel);
|
||||
int tunedFrequency = theBand -> Frequency (sd -> channel);
|
||||
my_dabProcessor -> start (tunedFrequency, false);
|
||||
selectedChannel = channel;
|
||||
selectedChannel = sd -> channel;
|
||||
fprintf (stderr, "ready to start %s (%s)\n",
|
||||
currentProgram. toLatin1 (). data (),
|
||||
channel. toLatin1 (). data ());
|
||||
(sd -> channel). toLatin1 (). data ());
|
||||
currentService = currentProgram;
|
||||
}
|
||||
else
|
||||
selectService (currentProgram);
|
||||
startService (currentProgram);
|
||||
}
|
||||
|
||||
void RadioInterface::channelTimer_timeout (void) {
|
||||
// so, we were looking for a channel. Let us see if
|
||||
// it has provided us with data
|
||||
QString currentService = services [0] -> name;
|
||||
disconnect (&channelTimer, SIGNAL (timeout (void)),
|
||||
this, SLOT (channelTimer_timeout (void)));
|
||||
if (my_dabProcessor -> kindofService (currentService) !=
|
||||
AUDIO_SERVICE)
|
||||
return;
|
||||
selectService (currentService);
|
||||
startService (currentService);
|
||||
}
|
||||
|
||||
void RadioInterface::selectService (QString currentService) {
|
||||
void RadioInterface::startService (QString currentService) {
|
||||
my_dabProcessor -> reset_msc ();
|
||||
setStereo (false);
|
||||
|
||||
@@ -646,9 +672,6 @@ void RadioInterface::selectService (QString currentService) {
|
||||
return;
|
||||
}
|
||||
|
||||
serviceCharacteristics = new serviceDisplay (&d);
|
||||
connect (this, SIGNAL (set_quality (int)),
|
||||
serviceCharacteristics, SLOT (set_qualityIndicator (int)));
|
||||
my_dabProcessor -> set_audioChannel (&d, audioBuffer, dataBuffer);
|
||||
soundOut -> restart ();
|
||||
showLabel (QString (" "));
|
||||
@@ -712,4 +735,35 @@ QString defaultPath = QDir::tempPath ();
|
||||
testdir. mkdir (picturesPath);
|
||||
}
|
||||
|
||||
void RadioInterface::updateTime (void) {
|
||||
QDateTime currentTime = QDateTime::currentDateTime ();
|
||||
|
||||
timeDisplay -> setText (currentTime.
|
||||
toString (QString ("dd.MM.yy:hh:mm:ss")));
|
||||
}
|
||||
|
||||
|
||||
bool RadioInterface::eventFilter (QObject *obj, QEvent *event) {
|
||||
if ((obj == ensembleDisplay -> viewport ()) &&
|
||||
(event -> type () == QEvent::MouseButtonPress )) {
|
||||
QMouseEvent *ev = static_cast<QMouseEvent *>(event);
|
||||
if (ev -> buttons () & Qt::RightButton) {
|
||||
audiodata ad;
|
||||
QString serviceName =
|
||||
this -> ensembleDisplay -> indexAt (ev -> pos()). data ().toString ();
|
||||
if (serviceDescription != NULL)
|
||||
delete serviceDescription;
|
||||
std::map<QString, serviceDescriptor *>::iterator it;
|
||||
it = serviceMap. find (serviceName);
|
||||
if (it == serviceMap. end ())
|
||||
return true;
|
||||
serviceDescriptor *sd = it -> second;
|
||||
if (sd -> defined) {
|
||||
serviceDescription = new audioDescriptor (sd);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return QMainWindow::eventFilter (obj, event);
|
||||
}
|
||||
|
||||
|
80
radio.h
80
radio.h
@@ -29,22 +29,25 @@
|
||||
#include "dab-constants.h"
|
||||
#include <QMainWindow>
|
||||
#include <QStringList>
|
||||
#include <QStringListModel>
|
||||
#include <QListView>
|
||||
#include <QComboBox>
|
||||
#include <QLabel>
|
||||
#include <QTimer>
|
||||
#include <sndfile.h>
|
||||
#include <atomic>
|
||||
#include <map>
|
||||
#include "ui_dabradio.h"
|
||||
#include "dab-processor.h"
|
||||
#include "ringbuffer.h"
|
||||
#include "band-handler.h"
|
||||
#include "text-mapper.h"
|
||||
#include "service-list.h"
|
||||
#include <atomic>
|
||||
#include "service-descriptor.h"
|
||||
class QSettings;
|
||||
class virtualInput;
|
||||
class audioBase;
|
||||
class common_fft;
|
||||
|
||||
class audioDescriptor;
|
||||
class spectrumhandler;
|
||||
|
||||
/*
|
||||
@@ -52,50 +55,6 @@ class spectrumhandler;
|
||||
* QDialog and the generated form
|
||||
*/
|
||||
|
||||
class serviceDescriptor {
|
||||
public:
|
||||
QString name;
|
||||
QString channel;
|
||||
int32_t serviceId;
|
||||
uint8_t shortForm;
|
||||
uint8_t protLevel;
|
||||
int32_t bitRate;
|
||||
int32_t startAddr;
|
||||
int32_t length;
|
||||
QString language;
|
||||
QString programType;
|
||||
|
||||
serviceDescriptor (QString name, QString channel, audiodata *d) {
|
||||
textMapper the_textMapper;
|
||||
this -> name = name;
|
||||
this -> channel = channel;
|
||||
this -> serviceId = d -> serviceId;
|
||||
this -> shortForm = d -> shortForm;
|
||||
this -> protLevel = d -> protLevel;
|
||||
this -> bitRate = d -> bitRate;
|
||||
this -> startAddr = d -> startAddr;
|
||||
this -> length = d -> length;
|
||||
this -> language = the_textMapper.
|
||||
get_programm_language_string (d -> language);
|
||||
this -> programType = the_textMapper.
|
||||
get_programm_type_string (d -> programType);
|
||||
}
|
||||
serviceDescriptor (QString name, QString channel) {
|
||||
this -> name = name;
|
||||
this -> channel = channel;
|
||||
this -> serviceId = 0;
|
||||
this -> shortForm = 0;
|
||||
this -> protLevel = 0;
|
||||
this -> bitRate = 0;
|
||||
this -> startAddr = 0;
|
||||
this -> length = 0;
|
||||
this -> language = QString ("");
|
||||
this -> programType = QString ("");
|
||||
}
|
||||
~serviceDescriptor (void) {}
|
||||
};
|
||||
|
||||
|
||||
class RadioInterface: public QMainWindow,
|
||||
private Ui_dabradio {
|
||||
Q_OBJECT
|
||||
@@ -116,10 +75,16 @@ private:
|
||||
void setColor (QLabel *l, uint8_t b);
|
||||
void setColor (QPushButton *l, uint8_t b);
|
||||
|
||||
QTimer secondsTimer;
|
||||
|
||||
typedef std::pair <QString, serviceDescriptor *> mapElement;
|
||||
std::map<QString, serviceDescriptor *> serviceMap;
|
||||
std::atomic<int> channelNumber;
|
||||
int serviceCount;
|
||||
QString selectedChannel;
|
||||
std::vector<serviceDescriptor *> services;
|
||||
QStringListModel ensemble;
|
||||
QStringList Services;
|
||||
QListView *ensembleDisplay;
|
||||
uint8_t dabBand;
|
||||
uint8_t dabMode;
|
||||
uint8_t isSynced;
|
||||
@@ -140,11 +105,10 @@ private:
|
||||
bool saveSlides;
|
||||
bool showSlides;
|
||||
QFrame *serviceCharacteristics;
|
||||
serviceList *ensembleDisplay;
|
||||
QTimer displayTimer;
|
||||
QTimer signalTimer;
|
||||
QTimer channelTimer;
|
||||
QString currentName;
|
||||
QString currentService;
|
||||
bool has_presetName;
|
||||
int32_t numberofSeconds;
|
||||
int16_t ficBlocks;
|
||||
@@ -152,10 +116,15 @@ private:
|
||||
|
||||
int autogain;
|
||||
QString picturesPath;
|
||||
void selectService (QString);
|
||||
void startService (QString);
|
||||
void startScanning (void);
|
||||
void TerminateProcess (void);
|
||||
audioDescriptor *serviceDescription;
|
||||
protected:
|
||||
bool eventFilter (QObject *obj, QEvent *event);
|
||||
|
||||
public slots:
|
||||
void set_CorrectorDisplay (int);
|
||||
void addtoEnsemble (const QString &);
|
||||
void nameofEnsemble (int, const QString &);
|
||||
void set_ensembleName (const QString &);
|
||||
@@ -172,19 +141,24 @@ public slots:
|
||||
void set_streamSelector (int);
|
||||
void nextChannel (void);
|
||||
void closeEvent (QCloseEvent *event);
|
||||
void updateTime (void);
|
||||
|
||||
void show_motHandling (bool);
|
||||
void showImpulse (int);
|
||||
void showSpectrum (int);
|
||||
void showIQ (int);
|
||||
void show_frameErrors (int);
|
||||
void show_rsErrors (int);
|
||||
void show_aacErrors (int);
|
||||
void showQuality (float);
|
||||
void show_snr (int);
|
||||
// Somehow, these must be connected to the GUI
|
||||
private slots:
|
||||
void handle_gainSlider (int);
|
||||
void handle_autoButton (void);
|
||||
void reset (void);
|
||||
void updateTimeDisplay (void);
|
||||
void channelTimer_timeout (void);
|
||||
void selectService (const QString &, const QString &);
|
||||
void selectService (QModelIndex);
|
||||
signals:
|
||||
void set_quality (int);
|
||||
};
|
||||
|
34
service-description/audio-descriptor.cpp
Normal file
34
service-description/audio-descriptor.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
#include <QFont>
|
||||
#include "dab_tables.h"
|
||||
#include "audio-descriptor.h"
|
||||
#include "service-descriptor.h"
|
||||
|
||||
audioDescriptor::audioDescriptor (serviceDescriptor *ad):
|
||||
myFrame (NULL) {
|
||||
setupUi (&myFrame);
|
||||
myFrame. show ();
|
||||
serviceLabel -> setText
|
||||
(QString ().number (ad -> serviceId, 16). toUpper ());
|
||||
QFont font = serviceLabel -> font ();
|
||||
font. setBold (true);
|
||||
serviceLabel -> setFont (font);
|
||||
channelLabel -> setText (ad -> channel);
|
||||
serviceName -> setText (ad -> name);
|
||||
subChannelId -> setText (QString::number (ad -> subchId));
|
||||
startAddress -> setText (QString::number (ad -> startAddr));
|
||||
Length -> setText (QString::number (ad -> length));
|
||||
bitrate -> setText (QString::number (ad -> bitRate));
|
||||
QString protL = getProtectionLevel (ad -> shortForm,
|
||||
ad -> protLevel);
|
||||
protectionLevel -> setText (protL);
|
||||
dabType -> setText (ad -> ASCTy == 077 ? "DAB+" : "DAB");
|
||||
Language -> setText (getLanguage (ad -> language));
|
||||
programType ->
|
||||
setText (the_textMapper.
|
||||
get_programm_type_string (ad -> programType));
|
||||
}
|
||||
|
||||
audioDescriptor::~audioDescriptor (void) {
|
||||
}
|
||||
|
25
service-description/audio-descriptor.h
Normal file
25
service-description/audio-descriptor.h
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
#ifndef __AUDIO_DESCRIPTOR__
|
||||
#define __AUDIO_DESCRIPTOR__
|
||||
#include <QObject>
|
||||
#include <QFrame>
|
||||
#include <QSettings>
|
||||
#include <atomic>
|
||||
#include "dab-constants.h"
|
||||
#include "ui_audio-description.h"
|
||||
#include "text-mapper.h"
|
||||
|
||||
class serviceDescriptor;
|
||||
|
||||
class audioDescriptor : public Ui_audioDescription {
|
||||
public:
|
||||
audioDescriptor (serviceDescriptor *ad);
|
||||
~audioDescriptor (void);
|
||||
private:
|
||||
QFrame myFrame;
|
||||
textMapper the_textMapper;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
25
service-description/data-descriptor.cpp
Normal file
25
service-description/data-descriptor.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
#include "dab_tables.h"
|
||||
#include "data-descriptor.h"
|
||||
|
||||
|
||||
dataDescriptor::dataDescriptor (packetdata *pd):
|
||||
myFrame (NULL) {
|
||||
setupUi (&myFrame);
|
||||
myFrame. show ();
|
||||
serviceName -> setText (pd -> serviceName);
|
||||
subChannelId -> setText (QString::number (pd -> subchId));
|
||||
startAddress -> setText (QString::number (pd -> startAddr));
|
||||
Length -> setText (QString::number (pd -> length));
|
||||
bitrate -> setText (QString::number (pd -> bitRate));
|
||||
packetAddress-> setText (QString::number (pd -> packetAddress));
|
||||
QString protL = getProtectionLevel (pd -> shortForm,
|
||||
pd -> protLevel);
|
||||
protectionLevel -> setText (protL);
|
||||
appType -> setText (getDSCTy (pd -> DSCTy));
|
||||
FECscheme -> setText (getFECscheme (pd -> FEC_scheme));
|
||||
}
|
||||
|
||||
dataDescriptor::~dataDescriptor (void) {
|
||||
}
|
||||
|
23
service-description/data-descriptor.h
Normal file
23
service-description/data-descriptor.h
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
#ifndef __DATA_DESCRIPTOR__
|
||||
#define __DATA_DESCRIPTOR__
|
||||
#include <QObject>
|
||||
#include <QFrame>
|
||||
#include <QSettings>
|
||||
#include <atomic>
|
||||
#include "dab-constants.h"
|
||||
#include "service-descriptor.h"
|
||||
#include "ui_data-description.h"
|
||||
#include "text-mapper.h"
|
||||
|
||||
class dataDescriptor : public serviceDescriptor, public Ui_dataDescription {
|
||||
public:
|
||||
dataDescriptor (packetdata *ad);
|
||||
~dataDescriptor (void);
|
||||
private:
|
||||
QFrame myFrame;
|
||||
textMapper the_textMapper;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
24
service-description/service-descriptor.cpp
Normal file
24
service-description/service-descriptor.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
#include "service-descriptor.h"
|
||||
#include "dab-constants.h"
|
||||
|
||||
serviceDescriptor::serviceDescriptor (QString name,
|
||||
QString channel, audiodata *d) {
|
||||
this -> defined = d -> defined;
|
||||
if (d -> defined) {
|
||||
this -> name = name;
|
||||
this -> channel = channel;
|
||||
this -> serviceId = d -> serviceId;
|
||||
this -> subchId = d -> subchId;
|
||||
this -> startAddr = d -> startAddr;
|
||||
this -> shortForm = d -> shortForm;
|
||||
this -> protLevel = d -> protLevel;
|
||||
this -> length = d -> length;
|
||||
this -> bitRate = d -> bitRate;
|
||||
this -> ASCTy = d -> ASCTy;
|
||||
this -> language = d -> language;
|
||||
this -> programType = d -> programType;
|
||||
}
|
||||
}
|
||||
serviceDescriptor::~serviceDescriptor (void) {}
|
||||
|
30
service-description/service-descriptor.h
Normal file
30
service-description/service-descriptor.h
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
#ifndef __SERVICE_DESCRIPTOR__
|
||||
#define __SERVICE_DESCRIPTOR__
|
||||
#include <QString>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "dab-constants.h"
|
||||
|
||||
class serviceDescriptor {
|
||||
public:
|
||||
bool defined;
|
||||
QString name;
|
||||
QString channel;
|
||||
int32_t serviceId;
|
||||
int16_t subchId;
|
||||
int16_t startAddr;
|
||||
bool shortForm;
|
||||
int16_t protLevel;
|
||||
int16_t length;
|
||||
int16_t bitRate;
|
||||
int16_t ASCTy;
|
||||
int16_t language;
|
||||
int16_t programType;
|
||||
|
||||
serviceDescriptor (QString name, QString channel, audiodata *d);
|
||||
~serviceDescriptor (void);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -1,71 +0,0 @@
|
||||
|
||||
|
||||
#include "service-display.h"
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include "text-mapper.h"
|
||||
|
||||
serviceDisplay::serviceDisplay (audiodata *d, QWidget *parent):
|
||||
QFrame (parent) {
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout ();
|
||||
QLabel *nameofService = new QLabel (d -> serviceName);
|
||||
QLabel *bitrateDisplay = new QLabel;
|
||||
QString t1 = "bitrate ";
|
||||
t1. append (QString::number (d -> bitRate));
|
||||
bitrateDisplay -> setText (t1);
|
||||
QLabel *lengthDisplay = new QLabel;
|
||||
t1 = "segment length ";
|
||||
t1. append (QString::number (d -> length));
|
||||
lengthDisplay -> setText (t1);
|
||||
uint16_t h = d -> protLevel;
|
||||
QString protL;
|
||||
if (!d -> shortForm) {
|
||||
protL = "EEP ";
|
||||
protL. append (QString::number ((h & 03) + 1));
|
||||
if ((h & (1 << 2)) == 0)
|
||||
protL. append ("-A");
|
||||
else
|
||||
protL. append ("-B");
|
||||
}
|
||||
else {
|
||||
protL = "UEP ";
|
||||
protL. append (QString::number (h));
|
||||
}
|
||||
QLabel * protectionLabel = new QLabel;
|
||||
t1 = "protection ";
|
||||
t1. append (protL);
|
||||
protectionLabel -> setText (t1);
|
||||
|
||||
QLabel *typeLabel = new QLabel;
|
||||
typeLabel -> setText (d -> ASCTy == 077 ? "DAB+" : "DAB");
|
||||
QLabel *languageLabel = new QLabel;
|
||||
languageLabel ->
|
||||
setText (the_textMapper.
|
||||
get_programm_language_string (d -> language));
|
||||
QLabel *programtypeLabel = new QLabel;
|
||||
programtypeLabel ->
|
||||
setText (the_textMapper.
|
||||
get_programm_type_string (d -> programType));
|
||||
qualityIndicator = new QLabel ("Quality ");
|
||||
|
||||
mainLayout -> addWidget (nameofService);
|
||||
mainLayout -> addWidget (bitrateDisplay);
|
||||
mainLayout -> addWidget (lengthDisplay);
|
||||
mainLayout -> addWidget (protectionLabel);
|
||||
mainLayout -> addWidget (typeLabel);
|
||||
mainLayout -> addWidget (languageLabel);
|
||||
mainLayout -> addWidget (programtypeLabel);
|
||||
mainLayout -> addWidget (qualityIndicator);
|
||||
setLayout (mainLayout);
|
||||
this -> setVisible (true);
|
||||
}
|
||||
|
||||
serviceDisplay::~serviceDisplay (void) {
|
||||
}
|
||||
|
||||
void serviceDisplay::set_qualityIndicator (int q) {
|
||||
QString t = "Quality ";
|
||||
t. append (QString::number (q));
|
||||
qualityIndicator -> setText (t);
|
||||
}
|
||||
|
@@ -1,21 +0,0 @@
|
||||
#ifndef __SERVICE_DISPLAY__
|
||||
#define __SERVICE_DISPLAY__
|
||||
|
||||
#include "dab-constants.h"
|
||||
#include <QFrame>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include "text-mapper.h"
|
||||
|
||||
class serviceDisplay : public QFrame {
|
||||
Q_OBJECT
|
||||
public:
|
||||
serviceDisplay (audiodata *d, QWidget *parent = NULL);
|
||||
~serviceDisplay (void);
|
||||
private:
|
||||
textMapper the_textMapper;
|
||||
QLabel *qualityIndicator;
|
||||
public slots:
|
||||
void set_qualityIndicator (int);
|
||||
};
|
||||
#endif
|
158
service-list.cpp
158
service-list.cpp
@@ -1,158 +0,0 @@
|
||||
#
|
||||
/*
|
||||
* Copyright (C) 2018
|
||||
* Jan van Katwijk (J.vanKatwijk@gmail.com)
|
||||
* Lazy Chair Programming
|
||||
*
|
||||
* This file is part of the dabradio
|
||||
*
|
||||
* dabradio 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.
|
||||
*
|
||||
* dabradio 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
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include <QFile>
|
||||
#include <QDataStream>
|
||||
#include "service-list.h"
|
||||
#include "radio.h"
|
||||
|
||||
serviceList::serviceList (RadioInterface *mr,
|
||||
QString saveName) {
|
||||
this -> saveName = saveName;
|
||||
myWidget = new QScrollArea (NULL);
|
||||
myWidget -> resize (240, 200);
|
||||
myWidget -> setWidgetResizable(true);
|
||||
|
||||
tableWidget = new QTableWidget (0, 4);
|
||||
myWidget -> setWidget(tableWidget);
|
||||
tableWidget -> setHorizontalHeaderLabels (
|
||||
QStringList () << tr ("station") << tr ("channel") << tr ("bitrate") << tr ("program type"));
|
||||
connect (tableWidget, SIGNAL (cellClicked (int, int)),
|
||||
this, SLOT (tableSelect (int, int)));
|
||||
// connect (tableWidget, SIGNAL (cellDoubleClicked (int, int)),
|
||||
// this, SLOT (removeRow (int, int)));
|
||||
// loadTable ();
|
||||
}
|
||||
|
||||
serviceList::~serviceList (void) {
|
||||
int16_t i;
|
||||
int16_t rows = tableWidget -> rowCount ();
|
||||
|
||||
// saveTable ();
|
||||
for (i = rows; i > 0; i --)
|
||||
tableWidget -> removeRow (i);
|
||||
delete tableWidget;
|
||||
delete myWidget;
|
||||
}
|
||||
|
||||
void serviceList::reset (void) {
|
||||
int16_t i;
|
||||
int16_t rows = tableWidget -> rowCount ();
|
||||
|
||||
saveTable ();
|
||||
for (i = rows; i > 0; i --)
|
||||
tableWidget -> removeRow (i - 1);
|
||||
}
|
||||
|
||||
bool serviceList::isEmpty (void) {
|
||||
return tableWidget -> rowCount () < 2;
|
||||
}
|
||||
|
||||
void serviceList::show (void) {
|
||||
myWidget -> show ();
|
||||
}
|
||||
|
||||
void serviceList::hide (void) {
|
||||
myWidget -> hide ();
|
||||
}
|
||||
|
||||
void serviceList::addRow (const QString &name,
|
||||
const QString &channel,
|
||||
QString bitRate,
|
||||
QString programType) {
|
||||
int16_t row = tableWidget -> rowCount ();
|
||||
|
||||
tableWidget -> insertRow (row);
|
||||
QTableWidgetItem *item0 = new QTableWidgetItem;
|
||||
item0 -> setTextAlignment (Qt::AlignRight |Qt::AlignVCenter);
|
||||
tableWidget -> setItem (row, 0, item0);
|
||||
|
||||
QTableWidgetItem *item1 = new QTableWidgetItem;
|
||||
item1 -> setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
||||
tableWidget -> setItem (row, 1, item1);
|
||||
|
||||
QTableWidgetItem *item2 = new QTableWidgetItem;
|
||||
item2 -> setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
||||
tableWidget -> setItem (row, 2, item2);
|
||||
|
||||
QTableWidgetItem *item3 = new QTableWidgetItem;
|
||||
item3 -> setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
||||
tableWidget -> setItem (row, 3, item3);
|
||||
|
||||
tableWidget -> setCurrentItem (item0);
|
||||
tableWidget -> item (row, 0) -> setText (name);
|
||||
tableWidget -> item (row, 1) -> setText (channel);
|
||||
tableWidget -> item (row, 2) -> setText (bitRate);
|
||||
tableWidget -> item (row, 3) -> setText (programType);
|
||||
}
|
||||
// Locally we dispatch the "click" and "translate"
|
||||
// it into a frequency and a call to the main gui to change
|
||||
// the frequency
|
||||
|
||||
void serviceList::tableSelect (int row, int column) {
|
||||
QTableWidgetItem* serviceItem = tableWidget -> item (row, 0);
|
||||
QTableWidgetItem* channelItem = tableWidget -> item (row, 1);
|
||||
|
||||
emit newService (serviceItem -> text (), channelItem -> text ());
|
||||
}
|
||||
|
||||
void serviceList::removeRow (int row, int column) {
|
||||
tableWidget -> removeRow (row);
|
||||
(void)column;
|
||||
}
|
||||
|
||||
void serviceList::saveTable (void) {
|
||||
QFile file (saveName);
|
||||
|
||||
if (file. open (QIODevice::WriteOnly)) {
|
||||
QDataStream stream (&file);
|
||||
int32_t n = tableWidget -> rowCount ();
|
||||
int32_t m = tableWidget -> columnCount ();
|
||||
stream << n << m;
|
||||
|
||||
for (int i = 0; i < n; i ++)
|
||||
for (int j = 0; j < m; j ++)
|
||||
tableWidget -> item (i, j) -> write (stream);
|
||||
file. close ();
|
||||
}
|
||||
}
|
||||
|
||||
void serviceList::loadTable (void) {
|
||||
QFile file (saveName);
|
||||
|
||||
if (file. open (QIODevice::ReadOnly)) {
|
||||
QDataStream stream (&file);
|
||||
int32_t n, m;
|
||||
stream >> n >> m;
|
||||
tableWidget -> setRowCount (n);
|
||||
tableWidget -> setColumnCount (m);
|
||||
|
||||
for (int i = 0; i < n; i ++) {
|
||||
for (int j = 0; j < m; j ++) {
|
||||
QTableWidgetItem *item = new QTableWidgetItem;
|
||||
item -> read (stream);
|
||||
tableWidget -> setItem (i, j, item);
|
||||
}
|
||||
}
|
||||
file. close ();
|
||||
}
|
||||
}
|
||||
|
@@ -1,60 +0,0 @@
|
||||
#
|
||||
/*
|
||||
* Copyright (C) 2014
|
||||
* Jan van Katwijk (J.vanKatwijk@gmail.com)
|
||||
* Lazy Chair Programming
|
||||
*
|
||||
* This file is part of the SDR-J series.
|
||||
*
|
||||
* SDR-J 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.
|
||||
*
|
||||
* SDR-J 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
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef __SERVICE_LIST__
|
||||
#define __SERVICE_LIST__
|
||||
|
||||
#include <QWidget>
|
||||
#include <QScrollArea>
|
||||
#include <QTableWidget>
|
||||
#include <QStringList>
|
||||
#include <QTableWidgetItem>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
class RadioInterface;
|
||||
|
||||
class serviceList:public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
serviceList (RadioInterface *, QString);
|
||||
~serviceList (void);
|
||||
void addRow (const QString &, const QString &,
|
||||
QString, QString);
|
||||
void show (void);
|
||||
void hide (void);
|
||||
void loadTable (void);
|
||||
void saveTable (void);
|
||||
bool isEmpty (void);
|
||||
void reset (void);
|
||||
private slots:
|
||||
void tableSelect (int, int);
|
||||
void removeRow (int, int);
|
||||
signals:
|
||||
void newService (const QString &, const QString &);
|
||||
private:
|
||||
QScrollArea *myWidget;
|
||||
QTableWidget *tableWidget;
|
||||
QString saveName;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -27,43 +27,41 @@
|
||||
/**
|
||||
* This table maps "EBU Latin" charset to corresponding
|
||||
* Unicode (UCS2-encoded) characters.
|
||||
* See ETSI TS 101 756 v1.6.1, Annex C
|
||||
* See ETSI TS 101 756 v1.8.1, Annex C
|
||||
*/
|
||||
static const unsigned short ebuLatinToUcs2[] = {
|
||||
/* 0x00 - 0x07 */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
/* 0x08 - 0x0f */ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
/* 0x10 - 0x17 */ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
/* 0x18 - 0x1f */ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x2d,
|
||||
|
||||
/* 0x20 - 0x27 */ 0x20, 0x21, 0x22, 0x23, 0xa4, 0x25, 0x26, 0x27,
|
||||
/* 0x28 - 0x2f */ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
/* 0x30 - 0x37 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
/* 0x38 - 0x3f */ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
/* 0x40 - 0x47 */ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
|
||||
/* 0x48 - 0x4f */ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||
/* 0x50 - 0x57 */ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
|
||||
/* 0x58 - 0x5f */ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x2015, 0x5f,
|
||||
/* 0x60 - 0x67 */ 0x2551, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
|
||||
/* 0x68 - 0x6f */ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
/* 0x70 - 0x77 */ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
|
||||
/* 0x78 - 0x7f */ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0xaf, 0x7f,
|
||||
|
||||
/* 0x80 - 0x87 */ 0xe1, 0xe0, 0xe9, 0xe8, 0xed, 0xec, 0xf3, 0xf2,
|
||||
/* 0x88 - 0x8f */ 0xfa, 0xf9, 0xd1, 0xc7, 0x015e, 0xdf, 0xa1, 0x0132,
|
||||
/* 0x90 - 0x97 */ 0xe2, 0xe4, 0xea, 0xeb, 0xee, 0xef, 0xf4, 0xf6,
|
||||
/* 0x98 - 0x9f */ 0xfb, 0xfc, 0xf1, 0xe7, 0x015f, 0x011f, 0x0131, 0x0133,
|
||||
/* 0xa0 - 0xa7 */ 0xaa, 0x03b1, 0xa9, 0x2030, 0x011e, 0x011b, 0x0148, 0x0151,
|
||||
/* 0xa8 - 0xaf */ 0x03c0, 0x20ac, 0xa3, 0x24, 0x2190, 0x2191, 0x2192, 0x2193,
|
||||
/* 0xb0 - 0xb7 */ 0xba, 0xb9, 0xb2, 0xb3, 0xb1, 0x0130, 0x0144, 0x0171,
|
||||
/* 0xb8 - 0xbf */ 0xb5, 0xbf, 0xf7, 0xb0, 0xbc, 0xbd, 0xbe, 0xa7,
|
||||
/* 0xc0 - 0xc7 */ 0xc1, 0xc0, 0xc9, 0xc8, 0xcd, 0xcc, 0xd3, 0xd2,
|
||||
/* 0xc8 - 0xcf */ 0xda, 0xd9, 0x0158, 0x010c, 0x0160, 0x017d, 0xd0, 0x13f,
|
||||
/* 0xd0 - 0xd7 */ 0xc2, 0xc4, 0xca, 0xcb, 0xce, 0xcf, 0xd4, 0xd6,
|
||||
/* 0xd8 - 0xdf */ 0xdb, 0xdc, 0x0159, 0x010d, 0x0161, 0x017e, 0x0111, 0x0140,
|
||||
/* 0xe0 - 0xe7 */ 0x00c3, 0x00c5, 0x00c6, 0x0152, 0x0177, 0xdd, 0xd5, 0xd8,
|
||||
/* 0xe8 - 0xef */ 0xde, 0x014a, 0x0154, 0x0106, 0x015a, 0x0179, 0x0166, 0xf0,
|
||||
/* 0xf0 - 0xf7 */ 0xe3, 0xe5, 0xe6, 0x0153, 0x0175, 0xfd, 0xf5, 0xf8,
|
||||
/* 0xf8 - 0xff */ 0xfe, 0x014b, 0x0155, 0x0107, 0x015b, 0x017a, 0x0167, 0xff
|
||||
/* 0x00 - 0x07 */ 0x00, 0x118, 0x12e, 0x172, 0x102, 0x116, 0x10e, 0x218,
|
||||
/* 0x8 - 0xf */ 0x21a, 0x10a, 0xa, 0xb, 0x120, 0x139, 0x17b, 0x143,
|
||||
/* 0x10 - 0x17 */ 0x105, 0x119, 0x12f, 0x173, 0x103, 0x117, 0x10f, 0x219,
|
||||
/* 0x18 - 0x1f */ 0x21b, 0x10b, 0x147, 0x11a, 0x121, 0x13a, 0x17c, 0x82,
|
||||
/* 0x20 - 0x27 */ 0x20, 0x21, 0x22, 0x23, 0x142, 0x25, 0x26, 0x27,
|
||||
/* 0x28 - 0x2f */ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
/* 0x30 - 0x37 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
/* 0x38 - 0x3f */ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
/* 0x40 - 0x47 */ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
|
||||
/* 0x48 - 0x4f */ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||
/* 0x50 - 0x57 */ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
|
||||
/* 0x58 - 0x5f */ 0x58, 0x59, 0x5a, 0x5b, 0x16e, 0x5d, 0x141, 0x5f,
|
||||
/* 0x60 - 0x67 */ 0x104, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
|
||||
/* 0x68 - 0x6f */ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
/* 0x70 - 0x77 */ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
|
||||
/* 0x78 - 0x7f */ 0x78, 0x79, 0x7a, 0xab, 0x16f, 0xbb, 0x13d, 0x126,
|
||||
/* 0x80 - 0x87 */ 0xe1, 0xe0, 0xe9, 0xe8, 0xed, 0xec, 0xf3, 0xf2,
|
||||
/* 0x88 - 0x8f */ 0xfa, 0xf9, 0xd1, 0xc7, 0x15e, 0xdf, 0xa1, 0x178,
|
||||
/* 0x90 - 0x97 */ 0xe2, 0xe4, 0xea, 0xeb, 0xee, 0xef, 0xf4, 0xf6,
|
||||
/* 0x98 - 0x9f */ 0xfb, 0xfc, 0xf1, 0xe7, 0x15f, 0x11f, 0x131, 0xff,
|
||||
/* 0xa0 - 0xa7 */ 0x136, 0x145, 0xa9, 0x122, 0x11e, 0x11b, 0x148, 0x151,
|
||||
/* 0xa8 - 0xaf */ 0x150, 0x20ac, 0xa3, 0x24, 0x100, 0x112, 0x12a, 0x16a,
|
||||
/* 0xb0 - 0xb7 */ 0x137, 0x146, 0x13b, 0x123, 0x13c, 0x130, 0x144, 0x171,
|
||||
/* 0xb8 - 0xbf */ 0x170, 0xbf, 0x13e, 0xb0, 0x101, 0x113, 0x12b, 0x16b,
|
||||
/* 0xc0 - 0xc7 */ 0xc1, 0xc0, 0xc9, 0xc8, 0xcd, 0xcc, 0xd3, 0xd2,
|
||||
/* 0xc8 - 0xcf */ 0xda, 0xd9, 0x158, 0x10c, 0x160, 0x17d, 0xd0, 0x13f,
|
||||
/* 0xd0 - 0xd7 */ 0xc2, 0xc4, 0xca, 0xcb, 0xce, 0xcf, 0xd4, 0xd6,
|
||||
/* 0xd8 - 0xdf */ 0xdb, 0xdc, 0x159, 0x10d, 0x161, 0x17e, 0x111, 0x140,
|
||||
/* 0xe0 - 0xe7 */ 0xc3, 0xc5, 0xc6, 0x152, 0x177, 0xdd, 0xd5, 0xd8,
|
||||
/* 0xe8 - 0xef */ 0xde, 0x14a, 0x154, 0x106, 0x15a, 0x179, 0x164, 0xf0,
|
||||
/* 0xf0 - 0xf7 */ 0xe3, 0xe5, 0xe6, 0x153, 0x175, 0xfd, 0xf5, 0xf8,
|
||||
/* 0xf8 - 0xff */ 0xfe, 0x14b, 0x155, 0x107, 0x15b, 0x17a, 0x165, 0x127
|
||||
};
|
||||
|
||||
QString toQStringUsingCharset (const char* buffer,
|
||||
|
@@ -40,7 +40,7 @@ struct {
|
||||
this -> picturesPath = picturesPath;
|
||||
orderNumber = 0;
|
||||
|
||||
theDirectory = NULL;
|
||||
theDirectory = nullptr;
|
||||
for (int i = 0; i < 15; i ++)
|
||||
motTable [i]. orderNumber = -1;
|
||||
}
|
||||
@@ -51,7 +51,7 @@ int i;
|
||||
for (i = 0; i < 15; i ++)
|
||||
if (motTable [i]. orderNumber > 0)
|
||||
delete motTable [i]. motSlide;
|
||||
if (theDirectory != NULL)
|
||||
if (theDirectory != nullptr)
|
||||
delete theDirectory;
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ int32_t i;
|
||||
case 3:
|
||||
if (segmentNumber == 0) {
|
||||
motObject *h = getHandle (transportId);
|
||||
if (h != NULL)
|
||||
if (h != nullptr)
|
||||
break;
|
||||
h = new motObject (myRadioInterface,
|
||||
picturesPath,
|
||||
@@ -131,7 +131,7 @@ int32_t i;
|
||||
|
||||
case 4: {
|
||||
motObject *h = getHandle (transportId);
|
||||
if (h == NULL)
|
||||
if (h == nullptr)
|
||||
break;
|
||||
h -> addBodySegment (&motVector [2],
|
||||
segmentNumber,
|
||||
@@ -142,11 +142,11 @@ int32_t i;
|
||||
|
||||
case 6:
|
||||
if (segmentNumber == 0) { // MOT directory
|
||||
if (theDirectory != NULL)
|
||||
if (theDirectory != nullptr)
|
||||
if (theDirectory -> get_transportId () == transportId)
|
||||
break; // already existing
|
||||
|
||||
if (theDirectory != NULL) // an old one, replace it
|
||||
if (theDirectory != nullptr) // an old one, replace it
|
||||
delete theDirectory;
|
||||
|
||||
int32_t segmentSize = ((motVector [0] & 0x1F) << 8) |
|
||||
@@ -171,7 +171,7 @@ int32_t i;
|
||||
segment);
|
||||
}
|
||||
else {
|
||||
if ((theDirectory == NULL) ||
|
||||
if ((theDirectory == nullptr) ||
|
||||
(theDirectory -> get_transportId () != transportId))
|
||||
break;
|
||||
theDirectory -> directorySegment (transportId,
|
||||
@@ -194,9 +194,9 @@ int i;
|
||||
if ((motTable [i]. orderNumber >= 0) &&
|
||||
(motTable [i]. transportId == transportId))
|
||||
return motTable [i]. motSlide;
|
||||
if (theDirectory != NULL)
|
||||
if (theDirectory != nullptr)
|
||||
return theDirectory -> getHandle (transportId);
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void motHandler::setHandle (motObject *h, uint16_t transportId) {
|
||||
@@ -213,15 +213,16 @@ int index = 0;
|
||||
}
|
||||
//
|
||||
// if here, the cache is full, so we delete the oldest one
|
||||
index = 0;
|
||||
for (i = 0; i < 15; i ++)
|
||||
if (motTable [i]. orderNumber < oldest) {
|
||||
oldest = motTable [i]. orderNumber;
|
||||
index = i;
|
||||
}
|
||||
|
||||
delete motTable [i]. motSlide;
|
||||
motTable [i]. orderNumber = orderNumber ++;
|
||||
motTable [i]. transportId = transportId;
|
||||
motTable [i]. motSlide = h;
|
||||
delete motTable [index]. motSlide;
|
||||
motTable [index]. orderNumber = orderNumber ++;
|
||||
motTable [index]. transportId = transportId;
|
||||
motTable [index]. motSlide = h;
|
||||
}
|
||||
|
@@ -87,10 +87,6 @@ int32_t pointer = 7;
|
||||
pointer += length;
|
||||
}
|
||||
}
|
||||
//
|
||||
// no segments as yet
|
||||
for (int i = 0; i < 128; i ++)
|
||||
marked [i] = false;
|
||||
}
|
||||
|
||||
motObject::~motObject (void) {
|
||||
@@ -111,17 +107,22 @@ void motObject::addBodySegment (uint8_t *bodySegment,
|
||||
bool lastFlag) {
|
||||
int32_t i;
|
||||
|
||||
if (marked [segmentNumber]) // we already have the segment
|
||||
return;
|
||||
// fprintf (stderr, "adding segment %d\n", segmentNumber);
|
||||
if ((segmentNumber < 0) || (segmentNumber >= 8192))
|
||||
return;
|
||||
|
||||
if (motMap. find (segmentNumber) != motMap. end ())
|
||||
return;
|
||||
|
||||
// Note that the last segment may have a different size
|
||||
if (!lastFlag && (this -> segmentSize == -1))
|
||||
this -> segmentSize = segmentSize;
|
||||
//
|
||||
segments [segmentNumber]. resize (segmentSize);
|
||||
for (i = 0; i < segmentSize; i ++)
|
||||
segments [segmentNumber][i] = bodySegment [i];
|
||||
marked [segmentNumber] = true;
|
||||
|
||||
QByteArray segment;
|
||||
segment. resize (segmentSize);
|
||||
for (i = 0; i < segmentSize; i ++)
|
||||
segment [i] = bodySegment [i];
|
||||
motMap. insert (std::make_pair (segmentNumber, segment));
|
||||
//
|
||||
if (lastFlag)
|
||||
numofSegments = segmentNumber + 1;
|
||||
@@ -131,22 +132,21 @@ int32_t i;
|
||||
//
|
||||
// once we know how many segments there are/should be,
|
||||
// we check for completeness
|
||||
for (i = 0; i < numofSegments; i ++)
|
||||
if (!(marked [i])) {
|
||||
for (i = 0; i < numofSegments; i ++) {
|
||||
if (motMap. find (i) == motMap. end ())
|
||||
return;
|
||||
}
|
||||
//
|
||||
}
|
||||
|
||||
// The motObject is (seems to be) complete
|
||||
handleComplete ();
|
||||
}
|
||||
|
||||
|
||||
void motObject::handleComplete (void) {
|
||||
int i;
|
||||
QByteArray result;
|
||||
|
||||
for (i = 0; i < numofSegments; i ++)
|
||||
result. append (segments [i]);
|
||||
for (const auto &it : motMap)
|
||||
result. append (it. second);
|
||||
|
||||
if (contentType == 7) { // epg data
|
||||
#ifdef TRY_EPG
|
||||
@@ -168,7 +168,7 @@ QByteArray result;
|
||||
realName. toLatin1 (). data ());
|
||||
checkDir (realName);
|
||||
FILE *x = fopen (realName. toLatin1 (). data (), "w+b");
|
||||
if (x == NULL)
|
||||
if (x == nullptr)
|
||||
fprintf (stderr, "cannot write file %s\n",
|
||||
realName. toLatin1 (). data ());
|
||||
else {
|
@@ -35,7 +35,7 @@
|
||||
connect (this, SIGNAL (show_motHandling (bool)),
|
||||
mr, SLOT (show_motHandling (bool)));
|
||||
this -> picturePath = picturesPath;
|
||||
currentSlide = NULL;
|
||||
currentSlide = nullptr;
|
||||
//
|
||||
// mscGroupElement indicates whether we are handling an
|
||||
// msc datagroup or not.
|
||||
@@ -54,7 +54,7 @@
|
||||
}
|
||||
|
||||
padHandler::~padHandler (void) {
|
||||
if (currentSlide != NULL)
|
||||
if (currentSlide != nullptr)
|
||||
delete currentSlide;
|
||||
}
|
||||
|
||||
@@ -65,8 +65,9 @@ void padHandler::processPAD (uint8_t *buffer, int16_t last,
|
||||
uint8_t L1, uint8_t L0) {
|
||||
uint8_t fpadType = (L1 >> 6) & 03;
|
||||
|
||||
if (fpadType != 00)
|
||||
if (fpadType != 00) {
|
||||
return;
|
||||
}
|
||||
//
|
||||
// OK, we'll try
|
||||
|
||||
@@ -90,7 +91,7 @@ uint8_t fpadType = (L1 >> 6) & 03;
|
||||
// on the vector address and the offset of the last element
|
||||
// in that vector
|
||||
//
|
||||
// shortPad's are 4 byte values. If the CI is on, then the type 2
|
||||
// shortPad's are 4 byte values. If the CI is on, then type 2
|
||||
// indicates the start of a segment. Type 3 the continuation.
|
||||
// The start of a message, i.e. segment 0 is (a.o) found by
|
||||
// a (1, 0) value of the firstSegment/lastSegment values.
|
||||
@@ -107,6 +108,7 @@ int16_t i;
|
||||
lastSegment = (b [last - 1] & 0x20) != 0;
|
||||
charSet = b [last - 2] & 0x0F;
|
||||
uint8_t AcTy = CI & 037; // application type
|
||||
|
||||
switch (AcTy) {
|
||||
default:
|
||||
break;
|
||||
@@ -114,6 +116,18 @@ int16_t i;
|
||||
case 0: // end marker
|
||||
break;
|
||||
//
|
||||
case 2: // start of fragment, extract the length
|
||||
if (firstSegment && !lastSegment) {
|
||||
segmentNumber = b [last - 2] >> 4;
|
||||
if (dynamicLabelText. size () > 0)
|
||||
showLabel (dynamicLabelText);
|
||||
dynamicLabelText. clear ();
|
||||
}
|
||||
still_to_go = b [last - 1] & 0x0F;
|
||||
shortpadData. resize (0);
|
||||
shortpadData. push_back (b [last - 3]);
|
||||
break;
|
||||
|
||||
case 3: // continuation of fragment
|
||||
for (i = 0; (i < 3) && (still_to_go > 0); i ++) {
|
||||
still_to_go --;
|
||||
@@ -131,17 +145,6 @@ int16_t i;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // start of fragment, extract the length
|
||||
if (firstSegment && !lastSegment) {
|
||||
segmentNumber = b [last - 2] >> 4;
|
||||
if (dynamicLabelText. size () > 0)
|
||||
showLabel (dynamicLabelText);
|
||||
dynamicLabelText. clear ();
|
||||
}
|
||||
still_to_go = b [last - 1] & 0x0F;
|
||||
shortpadData. resize (0);
|
||||
shortpadData. push_back (b [last - 3]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else { // No CI flag
|
||||
@@ -215,12 +218,14 @@ std::vector<uint8_t> data; // for the local addition
|
||||
for (i = 0; i < CI_Index; i ++)
|
||||
xpadLength += lengthTable [CI_table [i] >> 5];
|
||||
xpadLength += CI_Index == 4 ? 4 : CI_Index + 1;
|
||||
// fprintf (stderr, "xpadLength set to %d\n", xpadLength);
|
||||
}
|
||||
//
|
||||
|
||||
// Handle the contents
|
||||
for (i = 0; i < CI_Index; i ++) {
|
||||
uint8_t appType = CI_table [i] & 037;
|
||||
int16_t length = lengthTable [CI_table [i] >> 5];
|
||||
|
||||
if (appType == 1) {
|
||||
dataGroupLength = ((b [base] & 077) << 8) | b [base - 1];
|
||||
base -= 4;
|
||||
@@ -244,7 +249,7 @@ std::vector<uint8_t> data; // for the local addition
|
||||
break;
|
||||
|
||||
case 12: // MOT, start of X-PAD data group
|
||||
new_MSC_element (data, dataGroupLength);
|
||||
new_MSC_element (data);
|
||||
break;
|
||||
|
||||
case 13: // MOT, continuation of X-PAD data group
|
||||
@@ -349,43 +354,62 @@ int16_t dataLength = 0;
|
||||
//
|
||||
// Called at the start of the msc datagroupfield,
|
||||
// the msc_length was given by the preceding appType "1"
|
||||
void padHandler::new_MSC_element (std::vector<uint8_t> data,
|
||||
int msc_length) {
|
||||
void padHandler::new_MSC_element (std::vector<uint8_t> data) {
|
||||
|
||||
// if (mscGroupElement) {
|
||||
//// if (msc_dataGroupBuffer. size () < dataGroupLength)
|
||||
//// fprintf (stderr, "short ? %d %d\n",
|
||||
//// msc_dataGroupBuffer. size (),
|
||||
//// dataGroupLength);
|
||||
// msc_dataGroupBuffer. clear ();
|
||||
// build_MSC_segment (data);
|
||||
// mscGroupElement = true;
|
||||
// show_motHandling (true);
|
||||
// }
|
||||
|
||||
if (data. size () >= dataGroupLength) { // msc element is single item
|
||||
msc_dataGroupBuffer. clear ();
|
||||
build_MSC_segment (data);
|
||||
mscGroupElement = false;
|
||||
show_motHandling (true);
|
||||
// fprintf (stderr, "msc element is single\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mscGroupElement = true;
|
||||
msc_dataGroupBuffer. clear ();
|
||||
msc_dataGroupBuffer = data;
|
||||
msc_dataGroupLength = msc_length;
|
||||
show_motHandling (true);
|
||||
}
|
||||
|
||||
//
|
||||
void padHandler::add_MSC_element (std::vector<uint8_t> data) {
|
||||
int16_t i;
|
||||
int16_t currentLength = msc_dataGroupBuffer. size ();
|
||||
int32_t currentLength = msc_dataGroupBuffer. size ();
|
||||
//
|
||||
// just to ensure that, when a "12" appType is missing, the
|
||||
// data of "13" appType elements is not endlessly collected.
|
||||
if (currentLength == 0)
|
||||
if (currentLength == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
msc_dataGroupBuffer. insert (std::end (msc_dataGroupBuffer),
|
||||
std::begin (data), std::end (data));
|
||||
if (msc_dataGroupBuffer. size () >= msc_dataGroupLength) {
|
||||
build_MSC_segment (msc_dataGroupBuffer, msc_dataGroupLength);
|
||||
if (msc_dataGroupBuffer. size () >= dataGroupLength) {
|
||||
build_MSC_segment (msc_dataGroupBuffer);
|
||||
msc_dataGroupBuffer. clear ();
|
||||
// mscGroupElement = false;
|
||||
xpadLength = -1;
|
||||
show_motHandling (false);
|
||||
}
|
||||
}
|
||||
|
||||
void padHandler::build_MSC_segment (std::vector<uint8_t> data,
|
||||
int msc_length) {
|
||||
void padHandler::build_MSC_segment (std::vector<uint8_t> data) {
|
||||
// we have a MOT segment, let us look what is in it
|
||||
// according to DAB 300 401 (page 37) the header (MSC data group)
|
||||
// is
|
||||
int16_t size = data. size ();
|
||||
|
||||
int32_t size = data. size () < dataGroupLength ? data. size () :
|
||||
dataGroupLength;
|
||||
|
||||
uint8_t groupType = data [0] & 0xF;
|
||||
uint8_t continuityIndex = (data [1] & 0xF0) >> 4;
|
||||
uint8_t repetitionIndex = data [1] & 0xF;
|
||||
@@ -395,26 +419,29 @@ int16_t size = data. size ();
|
||||
uint16_t index;
|
||||
|
||||
if ((data [0] & 0x40) != 0) {
|
||||
bool res = check_crc_bytes (data. data (), msc_length - 2);
|
||||
bool res = check_crc_bytes (data. data (), size - 2);
|
||||
if (!res) {
|
||||
// fprintf (stderr, "build_MSC_segment fails on crc check\n");
|
||||
return;
|
||||
}
|
||||
// else
|
||||
// fprintf (stderr, "crc success ");
|
||||
}
|
||||
|
||||
if ((groupType != 3) && (groupType != 4))
|
||||
if ((groupType != 3) && (groupType != 4)) {
|
||||
return; // do not know yet
|
||||
|
||||
}
|
||||
// extensionflag
|
||||
bool extensionFlag = (data [0] & 0x80) != 0;
|
||||
// if the segmentflag is on, then a lastflag and segmentnumber are
|
||||
// available, i.e. 2 bytes more
|
||||
// available, i.e. 2 bytes more.
|
||||
// Theoretically, the segment number can be as large as 16384
|
||||
index = extensionFlag ? 4 : 2;
|
||||
bool segmentFlag = (data [0] & 0x20) != 0;
|
||||
if ((segmentFlag) != 0) {
|
||||
lastFlag = data [index] & 0x80;
|
||||
segmentNumber = ((data [index] & 0x7F) << 8) | data [index + 1];
|
||||
segmentNumber = ((data [index] & 0x7F) << 8) |
|
||||
data [index + 1];
|
||||
index += 2;
|
||||
}
|
||||
|
||||
@@ -427,20 +454,25 @@ int16_t size = data. size ();
|
||||
index += 3;
|
||||
}
|
||||
else {
|
||||
fprintf (stderr, "sorry no transportId\n");
|
||||
// fprintf (stderr, "sorry no transportId\n");
|
||||
return;
|
||||
}
|
||||
index += (lengthIndicator - 2);
|
||||
}
|
||||
|
||||
if (transportId == 0) // no idea wat it means
|
||||
return;
|
||||
|
||||
uint32_t segmentSize = ((data [index + 0] & 0x1F) << 8) |
|
||||
data [index + 1];
|
||||
// fprintf (stderr, "segmentSize = %d (transportId = %d)\n",
|
||||
// segmentSize, transportId);
|
||||
//
|
||||
// handling MOT in the PAD, we only deal here with type 3/4
|
||||
switch (groupType) {
|
||||
case 3:
|
||||
if (currentSlide == NULL) {
|
||||
if (currentSlide == nullptr) {
|
||||
// fprintf (stderr, "creating %d\n", transportId);
|
||||
currentSlide = new motObject (myRadioInterface,
|
||||
picturePath,
|
||||
false,
|
||||
@@ -452,7 +484,9 @@ int16_t size = data. size ();
|
||||
else {
|
||||
if (currentSlide -> get_transportId () == transportId)
|
||||
break;
|
||||
|
||||
// fprintf (stderr, "out goes %d, in comes %d\n",
|
||||
// currentSlide -> get_transportId (),
|
||||
// transportId);
|
||||
delete currentSlide;
|
||||
currentSlide = new motObject (myRadioInterface,
|
||||
picturePath,
|
||||
@@ -465,17 +499,19 @@ int16_t size = data. size ();
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (currentSlide == NULL)
|
||||
break; // no header yet
|
||||
if (currentSlide -> get_transportId () == transportId)
|
||||
if (currentSlide == nullptr)
|
||||
return;
|
||||
if (currentSlide -> get_transportId () == transportId) {
|
||||
// fprintf (stderr, "add segment %d of %d\n",
|
||||
// segmentNumber, transportId);
|
||||
currentSlide -> addBodySegment (&data [index + 2],
|
||||
segmentNumber,
|
||||
segmentSize,
|
||||
lastFlag);
|
||||
}
|
||||
break;
|
||||
|
||||
default: // cannot happen
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -33,59 +33,144 @@
|
||||
// a service is selected or not.
|
||||
|
||||
#define CUSize (4 * 16)
|
||||
static int cifTable [] = {18, 72, 0, 36};
|
||||
|
||||
// Note CIF counts from 0 .. 3
|
||||
//
|
||||
mscHandler::mscHandler (RadioInterface *mr,
|
||||
uint8_t mode,
|
||||
uint8_t dabMode,
|
||||
QString picturesPath) :
|
||||
params (mode) {
|
||||
params (dabMode),
|
||||
my_fftHandler (dabMode),
|
||||
myMapper (dabMode),
|
||||
bufferSpace (params. get_L ()){
|
||||
myRadioInterface = mr;
|
||||
this -> picturesPath = picturesPath;
|
||||
cifVector. resize (55296);
|
||||
theBackends. push_back (new virtualBackend (0, 0));
|
||||
BitsperBlock = 2 * params. get_carriers ();
|
||||
switch (mode) {
|
||||
case 4: // 2 CIFS per 76 blocks
|
||||
numberofblocksperCIF = 36;
|
||||
break;
|
||||
nrBlocks = params. get_L ();
|
||||
|
||||
case 1: // 4 CIFS per 76 blocks
|
||||
numberofblocksperCIF = 18;
|
||||
break;
|
||||
command. resize (nrBlocks);
|
||||
for (int i = 0; i < nrBlocks; i ++)
|
||||
command [i]. resize (params. get_T_u ());
|
||||
amount = 0;
|
||||
fft_buffer = my_fftHandler. getVector ();
|
||||
phaseReference .resize (params. get_T_u ());
|
||||
|
||||
case 2: // 1 CIF per 76 blocks
|
||||
numberofblocksperCIF = 72;
|
||||
break;
|
||||
|
||||
default:
|
||||
numberofblocksperCIF = 18;
|
||||
break;
|
||||
}
|
||||
numberofblocksperCIF = cifTable [(dabMode - 1) & 03];
|
||||
work_to_be_done. store (false);
|
||||
}
|
||||
|
||||
mscHandler::~mscHandler (void) {
|
||||
reset ();
|
||||
running. store (false);
|
||||
while (isRunning ())
|
||||
usleep (100);
|
||||
locker. lock ();
|
||||
work_to_be_done. store (false);
|
||||
for (auto const &b : theBackends) {
|
||||
b -> stopRunning ();
|
||||
delete b;
|
||||
}
|
||||
locker. unlock ();
|
||||
theBackends. resize (0);
|
||||
}
|
||||
|
||||
//
|
||||
// Input is put into a buffer, a the code in a separate thread
|
||||
// will handle the data from the buffer
|
||||
void mscHandler::processBlock_0 (std::complex<float> *b) {
|
||||
bufferSpace. acquire (1);
|
||||
memcpy (command [0]. data (), b,
|
||||
params. get_T_u () * sizeof (std::complex<float>));
|
||||
helper. lock ();
|
||||
amount ++;
|
||||
commandHandler. wakeOne ();
|
||||
helper. unlock ();
|
||||
}
|
||||
|
||||
void mscHandler::process_Msc (std::complex<float> *b, int blkno) {
|
||||
bufferSpace. acquire (1);
|
||||
memcpy (command [blkno]. data (), b,
|
||||
params. get_T_u () * sizeof (std::complex<float>));
|
||||
helper. lock ();
|
||||
amount ++;
|
||||
commandHandler. wakeOne ();
|
||||
helper. unlock ();
|
||||
}
|
||||
|
||||
void mscHandler::run (void) {
|
||||
int currentBlock = 0;
|
||||
std::vector<int16_t> ibits;
|
||||
|
||||
running. store (true);
|
||||
ibits. resize (BitsperBlock);
|
||||
while (running. load ()) {
|
||||
helper. lock ();
|
||||
commandHandler. wait (&helper, 100);
|
||||
helper. unlock ();
|
||||
while ((amount > 0) && running. load ()) {
|
||||
memcpy (fft_buffer, command [currentBlock]. data (),
|
||||
params. get_T_u () * sizeof (std::complex<float>));
|
||||
//
|
||||
// block 3 and up are needed as basis for demodulation the "mext" block
|
||||
// "our" msc blocks start with blkno 4
|
||||
my_fftHandler. do_FFT ();
|
||||
if (currentBlock >= 4) {
|
||||
for (int i = 0; i < params. get_carriers (); i ++) {
|
||||
int16_t index = myMapper. mapIn (i);
|
||||
if (index < 0)
|
||||
index += params. get_T_u ();
|
||||
|
||||
std::complex<float> r1 = fft_buffer [index] *
|
||||
conj (phaseReference [index]);
|
||||
float ab1 = jan_abs (r1);
|
||||
// Recall: the viterbi decoder wants 127 max pos, - 127 max neg
|
||||
// we make the bits into softbits in the range -127 .. 127
|
||||
ibits [i] = - real (r1) / ab1 * 127.0;
|
||||
ibits [params. get_carriers () + i]
|
||||
= - imag (r1) / ab1 * 127.0;
|
||||
}
|
||||
|
||||
process_mscBlock (ibits, currentBlock);
|
||||
}
|
||||
memcpy (phaseReference. data (), fft_buffer,
|
||||
params. get_T_u () * sizeof (std::complex<float>));
|
||||
bufferSpace. release (1);
|
||||
helper. lock ();
|
||||
currentBlock = (currentBlock + 1) % (nrBlocks);
|
||||
amount -= 1;
|
||||
helper. unlock ();
|
||||
}
|
||||
}
|
||||
}
|
||||
// This function is to be called between invocations of
|
||||
// services
|
||||
// It might be called several times, so ...
|
||||
void mscHandler::reset (void) {
|
||||
int i;
|
||||
locker. lock ();
|
||||
work_to_be_done. store (false);
|
||||
for (i = 0; i < theBackends. size (); i ++) {
|
||||
theBackends [i] -> stopRunning ();
|
||||
delete theBackends [i];
|
||||
}
|
||||
theBackends. resize (0);
|
||||
locker. unlock ();
|
||||
void mscHandler::reset (void) {
|
||||
int i;
|
||||
running. store (false);
|
||||
while (isRunning ())
|
||||
usleep (100);
|
||||
locker. lock ();
|
||||
work_to_be_done. store (false);
|
||||
for (auto const &b : theBackends) {
|
||||
b -> stopRunning ();
|
||||
delete b;
|
||||
}
|
||||
theBackends. resize (0);
|
||||
|
||||
bufferSpace. release (nrBlocks - bufferSpace. available ());
|
||||
locker. unlock ();
|
||||
start ();
|
||||
}
|
||||
|
||||
void mscHandler::stop (void) {
|
||||
reset ();
|
||||
}
|
||||
//
|
||||
// Note, the set_xxx functions are called from within a
|
||||
// different thread than the process_mscBlock method,
|
||||
// different thread than the process_mscBlock method is,
|
||||
// so, a little bit of locking seems wise while
|
||||
// the actual changing of the settings is done in the
|
||||
// thread executing process_mscBlock
|
||||
@@ -93,7 +178,7 @@ void mscHandler::set_audioChannel (audiodata *d,
|
||||
RingBuffer<int16_t> *audioBuffer) {
|
||||
locker. lock ();
|
||||
//
|
||||
// we could assert here that theBackend == NULL
|
||||
// we could assert here that theBackend == nullptr
|
||||
theBackends. push_back (new audioBackend (myRadioInterface,
|
||||
d,
|
||||
audioBuffer,
|
||||
@@ -114,10 +199,11 @@ void mscHandler::set_dataChannel (packetdata *d,
|
||||
}
|
||||
|
||||
//
|
||||
// add blocks. First is (should be) block 5, last is (should be) 76
|
||||
// add blocks. First is (should be) block 4, last is (should be)
|
||||
// nrBlocks -1.
|
||||
// Note that this method is called from within the ofdm-processor thread
|
||||
// while the set_xxx methods are called from within the
|
||||
// gui thread
|
||||
// gui thread, so some locking is added
|
||||
//
|
||||
// Any change in the selected service will only be active
|
||||
// during te next process_mscBlock call.
|
||||
@@ -140,21 +226,17 @@ int16_t i;
|
||||
// be done. We assume that the backend itself
|
||||
// does the work in a separate thread.
|
||||
locker. lock ();
|
||||
for (i = 0; i < theBackends. size (); i ++) {
|
||||
int16_t startAddr = theBackends [i] -> startAddr ();
|
||||
int16_t Length = theBackends [i] -> Length ();
|
||||
for (auto const& b: theBackends) {
|
||||
int16_t startAddr = b -> startAddr ();
|
||||
int16_t Length = b -> Length ();
|
||||
if (Length > 0) { // Length = 0? virtual Backend
|
||||
int16_t temp [Length * CUSize];
|
||||
memcpy (temp, &cifVector [startAddr * CUSize],
|
||||
Length * CUSize * sizeof (int16_t));
|
||||
(void) theBackends [i] -> process (temp, Length * CUSize);
|
||||
(void) b -> process (temp, Length * CUSize);
|
||||
}
|
||||
}
|
||||
locker. unlock ();
|
||||
}
|
||||
//
|
||||
|
||||
void mscHandler::stop (void) {
|
||||
reset ();
|
||||
}
|
||||
|
||||
|
@@ -48,176 +48,49 @@
|
||||
ofdmDecoder::ofdmDecoder (RadioInterface *mr,
|
||||
uint8_t dabMode,
|
||||
int16_t bitDepth,
|
||||
ficHandler *my_ficHandler,
|
||||
mscHandler *my_mscHandler):
|
||||
RingBuffer<std::complex<float>> *iqBuffer) :
|
||||
params (dabMode),
|
||||
my_fftHandler (dabMode),
|
||||
#ifdef __THREADED_DECODING
|
||||
bufferSpace (params. get_L ()),
|
||||
#endif
|
||||
myMapper (dabMode) {
|
||||
int16_t i;
|
||||
this -> myRadioInterface = mr;
|
||||
this -> iqBuffer = iqBuffer;
|
||||
connect (this, SIGNAL (showIQ (int)),
|
||||
myRadioInterface, SLOT (showIQ (int)));
|
||||
connect (this, SIGNAL (showQuality (float)),
|
||||
myRadioInterface, SLOT (showQuality (float)));
|
||||
//
|
||||
this -> my_ficHandler = my_ficHandler;
|
||||
this -> my_mscHandler = my_mscHandler;
|
||||
this -> T_s = params. get_T_s ();
|
||||
this -> T_u = params. get_T_u ();
|
||||
this -> nrBlocks = params. get_L ();
|
||||
this -> carriers = params. get_carriers ();
|
||||
ibits. resize (2 * this -> carriers);
|
||||
|
||||
this -> T_g = T_s - T_u;
|
||||
fft_buffer = my_fftHandler. getVector ();
|
||||
phaseReference .resize (T_u);
|
||||
|
||||
connect (this, SIGNAL (show_snr (int)),
|
||||
mr, SLOT (show_snr (int)));
|
||||
|
||||
snrCount = 0;
|
||||
snr = 0;
|
||||
|
||||
#ifdef __THREADED_DECODING
|
||||
/**
|
||||
* When implemented in a thread, the thread controls the
|
||||
* reading in of the data and processing the data through
|
||||
* functions for handling block 0, FIC blocks and MSC blocks.
|
||||
*
|
||||
* We just create a large buffer where index i refers to block i.
|
||||
*
|
||||
*/
|
||||
command = new std::complex<float> * [nrBlocks];
|
||||
for (i = 0; i < nrBlocks; i ++)
|
||||
command [i] = new std::complex<float> [T_u];
|
||||
amount = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
ofdmDecoder::~ofdmDecoder (void) {
|
||||
int16_t i;
|
||||
#ifdef __THREADED_DECODING
|
||||
running. store (false);
|
||||
while (isRunning ()) {
|
||||
commandHandler. wakeAll ();
|
||||
usleep (1000);
|
||||
}
|
||||
for (i = 0; i < nrBlocks; i ++)
|
||||
delete[] command [i];
|
||||
delete[] command;
|
||||
#endif
|
||||
|
||||
}
|
||||
//
|
||||
// the client of this class should not know whether
|
||||
// we run with a separate thread or not,
|
||||
#ifndef __THREADED_DECODING
|
||||
void ofdmDecoder::start (void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void ofdmDecoder::stop (void) {
|
||||
#ifdef __THREADED_DECODING
|
||||
running. store (false);
|
||||
while (isRunning ()) {
|
||||
commandHandler. wakeAll ();
|
||||
usleep (1000);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ofdmDecoder::reset (void) {
|
||||
#ifdef __THREADED_DECODING
|
||||
stop ();
|
||||
usleep (10000);
|
||||
start ();
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
#ifdef __THREADED_DECODING
|
||||
/**
|
||||
* The code in the thread executes a simple loop,
|
||||
* waiting for the next block and executing the interpretation
|
||||
* operation for that block.
|
||||
* In our original code the block count was 1 higher than
|
||||
* our count here.
|
||||
*/
|
||||
void ofdmDecoder::run (void) {
|
||||
int16_t currentBlock = 0;
|
||||
|
||||
running. store (true);
|
||||
while (running. load ()) {
|
||||
helper. lock ();
|
||||
commandHandler. wait (&helper, 100);
|
||||
helper. unlock ();
|
||||
while ((amount > 0) && running. load ()) {
|
||||
if (currentBlock == 0)
|
||||
processBlock_0 ();
|
||||
else
|
||||
if (currentBlock < 4)
|
||||
decodeFICblock (currentBlock);
|
||||
else
|
||||
decodeMscblock (currentBlock);
|
||||
bufferSpace. release (1);
|
||||
helper. lock ();
|
||||
currentBlock = (currentBlock + 1) % (nrBlocks);
|
||||
amount -= 1;
|
||||
helper. unlock ();
|
||||
}
|
||||
}
|
||||
fprintf (stderr, "ofdm decoder is closing down now\n");
|
||||
}
|
||||
/**
|
||||
* We need some functions to enter the ofdmProcessor data
|
||||
* in the buffer.
|
||||
*/
|
||||
void ofdmDecoder::processBlock_0 (std::vector<std::complex<float>>vi) {
|
||||
bufferSpace. acquire (1);
|
||||
memcpy (command [0], vi. data (), sizeof (std::complex<float>) * T_u);
|
||||
helper. lock ();
|
||||
amount ++;
|
||||
commandHandler. wakeOne ();
|
||||
helper. unlock ();
|
||||
void ofdmDecoder::stop (void) {
|
||||
}
|
||||
|
||||
void ofdmDecoder::decodeFICblock (std::vector<std::complex<float>> vi,
|
||||
int32_t blkno) {
|
||||
bufferSpace. acquire (1);
|
||||
memcpy (command [blkno], &((vi. data ()) [T_g]),
|
||||
sizeof (std::complex<float>) * T_u);
|
||||
helper. lock ();
|
||||
amount ++;
|
||||
commandHandler. wakeOne ();
|
||||
helper. unlock ();
|
||||
void ofdmDecoder::reset (void) {
|
||||
}
|
||||
|
||||
void ofdmDecoder::decodeMscblock (std::vector<std::complex<float> > vi,
|
||||
int32_t blkno) {
|
||||
bufferSpace. acquire (1);
|
||||
memcpy (command [blkno], &((vi. data ()) [T_g]),
|
||||
sizeof (std::complex<float>) * T_u);
|
||||
helper. lock ();
|
||||
amount ++;
|
||||
commandHandler. wakeOne ();
|
||||
helper. unlock ();
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* Note that the distinction, made in the ofdmProcessor class
|
||||
* does not add much here, iff we decide to choose the multi core
|
||||
* option definitely, then code may be simplified there.
|
||||
*/
|
||||
|
||||
/**
|
||||
* handle block 0 as collected from the buffer
|
||||
*/
|
||||
#ifdef __THREADED_DECODING
|
||||
void ofdmDecoder::processBlock_0 (void) {
|
||||
|
||||
memcpy (fft_buffer, command [0], T_u * sizeof (std::complex<float>));
|
||||
#else
|
||||
void ofdmDecoder::processBlock_0 (std::vector <std::complex<float> > buffer) {
|
||||
memcpy (fft_buffer, buffer. data (),
|
||||
T_u * sizeof (std::complex<float>));
|
||||
#endif
|
||||
|
||||
my_fftHandler. do_FFT ();
|
||||
/**
|
||||
@@ -226,6 +99,11 @@ void ofdmDecoder::processBlock_0 (std::vector <std::complex<float> > buffer) {
|
||||
* It is just an indication
|
||||
*/
|
||||
|
||||
if (++snrCount > 10) {
|
||||
snr = 0.8 * snr + 0.2 * get_snr (fft_buffer);
|
||||
// show_snr (snr);
|
||||
snrCount = 0;
|
||||
}
|
||||
/**
|
||||
* we are now in the frequency domain, and we keep the carriers
|
||||
* as coming from the FFT as phase reference.
|
||||
@@ -234,25 +112,50 @@ void ofdmDecoder::processBlock_0 (std::vector <std::complex<float> > buffer) {
|
||||
T_u * sizeof (std::complex<float>));
|
||||
}
|
||||
//
|
||||
// Just interested. In the ideal case the constellation of the
|
||||
// decoded symbols is precisely in the four points
|
||||
// k * (1, 1), k * (1, -1), k * (-1, -1), k * (-1, 1)
|
||||
// To ease computation, we map all incoming values onto quadrant 1
|
||||
float ofdmDecoder::computeQuality (std::complex<float> *v) {
|
||||
int16_t i;
|
||||
std::complex<float> avgPoint = std::complex<float> (0, 0);
|
||||
std::complex<float> x [T_u];
|
||||
float avg = 0;
|
||||
float S = 0;
|
||||
|
||||
for (i = 0; i < carriers; i ++) {
|
||||
x [i] = std::complex<float> (abs (real (v [T_u / 2 - carriers / 2 + i])), abs (imag (v [T_u / 2 - carriers / 2 + i])));
|
||||
avgPoint += x [i];
|
||||
}
|
||||
|
||||
avg = arg (avgPoint * conj (std::complex<float> (1, 1)));
|
||||
|
||||
for (i = 0; i < carriers; i ++) {
|
||||
float f = arg (x [i] * conj (std::complex<float> (1, 1))) - avg;
|
||||
f = f / M_PI * 360;
|
||||
S += f * f;
|
||||
}
|
||||
|
||||
S /= (carriers - 1);
|
||||
|
||||
return sqrt (S);
|
||||
}
|
||||
|
||||
/**
|
||||
* for the other blocks of data, the first step is to go from
|
||||
* time to frequency domain, to get the carriers.
|
||||
* we distinguish between FIC blocks and other blocks,
|
||||
* only to spare a test. The mapping code is the same
|
||||
*/
|
||||
static
|
||||
int cnt = 0;
|
||||
#ifdef __THREADED_DECODING
|
||||
void ofdmDecoder::decodeFICblock (int32_t blkno) {
|
||||
int16_t i;
|
||||
memcpy (fft_buffer, command [blkno], T_u * sizeof (std::complex<float>));
|
||||
#else
|
||||
void ofdmDecoder::decodeFICblock (std::vector <std::complex<float>> buffer,
|
||||
int32_t blkno) {
|
||||
|
||||
static int cnt = 0;
|
||||
void ofdmDecoder::decode (std::vector <std::complex<float>> buffer,
|
||||
int32_t blkno, int16_t *ibits) {
|
||||
int16_t i;
|
||||
memcpy (fft_buffer, &((buffer. data ()) [T_g]),
|
||||
T_u * sizeof (std::complex<float>));
|
||||
#endif
|
||||
std::complex<float> conjVector [T_u];
|
||||
std::complex<float> freqOff = std::complex<float> (0, 0);
|
||||
|
||||
|
||||
fftlabel:
|
||||
@@ -268,9 +171,8 @@ fftlabel:
|
||||
toBitsLabel:
|
||||
/**
|
||||
* Note that from here on, we are only interested in the
|
||||
* "carriers" useful carriers of the FFT output
|
||||
* "carriers", the useful carriers of the FFT output
|
||||
*/
|
||||
|
||||
for (i = 0; i < carriers; i ++) {
|
||||
int16_t index = myMapper. mapIn (i);
|
||||
if (index < 0)
|
||||
@@ -283,6 +185,7 @@ toBitsLabel:
|
||||
*/
|
||||
std::complex<float> r1 = fft_buffer [index] *
|
||||
conj (phaseReference [index]);
|
||||
conjVector [index] = r1;
|
||||
float ab1 = jan_abs (r1);
|
||||
// split the real and the imaginary part and scale it
|
||||
// we make the bits into softbits in the range -127 .. 127
|
||||
@@ -291,55 +194,17 @@ toBitsLabel:
|
||||
}
|
||||
memcpy (phaseReference. data (), fft_buffer,
|
||||
T_u * sizeof (std::complex<float>));
|
||||
|
||||
handlerLabel:
|
||||
my_ficHandler -> process_ficBlock (ibits, blkno);
|
||||
}
|
||||
/**
|
||||
* Msc block decoding is equal to FIC block decoding,
|
||||
* further processing is different though
|
||||
*/
|
||||
#ifdef __THREADED_DECODING
|
||||
void ofdmDecoder::decodeMscblock (int32_t blkno) {
|
||||
int16_t i;
|
||||
|
||||
memcpy (fft_buffer, command [blkno], T_u * sizeof (std::complex<float>));
|
||||
#else
|
||||
void ofdmDecoder::decodeMscblock (std::vector <std::complex<float>>buffer,
|
||||
int32_t blkno) {
|
||||
int16_t i;
|
||||
memcpy (fft_buffer, &((buffer. data ())[T_g]), T_u * sizeof (std::complex<float>));
|
||||
#endif
|
||||
|
||||
fftLabel:
|
||||
my_fftHandler. do_FFT ();
|
||||
//
|
||||
// Note that "mapIn" maps to -carriers / 2 .. carriers / 2
|
||||
// we did not set the fft output to low .. high
|
||||
toBitsLabel:
|
||||
for (i = 0; i < carriers; i ++) {
|
||||
int16_t index = myMapper. mapIn (i);
|
||||
if (index < 0)
|
||||
index += T_u;
|
||||
|
||||
std::complex<float> r1 = fft_buffer [index] *
|
||||
conj (phaseReference [index]);
|
||||
float ab1 = jan_abs (r1);
|
||||
// Recall: the viterbi decoder wants 127 max pos, - 127 max neg
|
||||
// we make the bits into softbits in the range -127 .. 127
|
||||
ibits [i] = - real (r1) / ab1 * 127.0;
|
||||
ibits [carriers + i] = - imag (r1) / ab1 * 127.0;
|
||||
// From time to time we show the constellation of symbol 2.
|
||||
if ((blkno == 2) && (iqBuffer != nullptr)) {
|
||||
if (++cnt > 7) {
|
||||
iqBuffer -> putDataIntoBuffer (&conjVector [T_u / 2 - carriers / 2],
|
||||
carriers);
|
||||
showIQ (carriers);
|
||||
showQuality (computeQuality (conjVector));
|
||||
cnt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy (phaseReference. data (), fft_buffer,
|
||||
T_u * sizeof (std::complex<float>));
|
||||
|
||||
handlerLabel:;
|
||||
my_mscHandler -> process_mscBlock (ibits, blkno);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
/**
|
||||
* for the snr we have a full T_u wide vector, with in the middle
|
||||
* K carriers.
|
||||
|
@@ -32,20 +32,16 @@
|
||||
|
||||
phaseReference::phaseReference (RadioInterface *mr,
|
||||
uint8_t dabMode,
|
||||
#ifdef IMPULSE_RESPONSE
|
||||
RingBuffer<float> *b,
|
||||
#endif
|
||||
int16_t threshold,
|
||||
int16_t diff_length):
|
||||
int16_t diff_length,
|
||||
RingBuffer<float> *b):
|
||||
phaseTable (dabMode),
|
||||
params (dabMode),
|
||||
my_fftHandler (dabMode) {
|
||||
int32_t i;
|
||||
float Phi_k;
|
||||
|
||||
#ifdef IMPULSE_RESPONSE
|
||||
this -> response = b;
|
||||
#endif
|
||||
this -> threshold = threshold;
|
||||
this -> diff_length = diff_length;
|
||||
this -> T_u = params. get_T_u ();
|
||||
@@ -73,10 +69,9 @@ float Phi_k;
|
||||
for (i = 1; i <= diff_length; i ++)
|
||||
phaseDifferences [i - 1] = abs (arg (refTable [(T_u + i) % T_u] *
|
||||
conj (refTable [(T_u + i + 1) % T_u])));
|
||||
#ifdef IMPULSE_RESPONSE
|
||||
|
||||
connect (this, SIGNAL (showImpulse (int)),
|
||||
mr, SLOT (showImpulse (int)));
|
||||
#endif
|
||||
}
|
||||
|
||||
phaseReference::~phaseReference (void) {
|
||||
@@ -120,13 +115,13 @@ float lbuf [T_u];
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef IMPULSE_RESPONSE
|
||||
if (++displayCounter > framesperSecond / 4) {
|
||||
response -> putDataIntoBuffer (lbuf, T_u);
|
||||
showImpulse (T_u);
|
||||
displayCounter = 0;
|
||||
if (response != NULL) {
|
||||
if (++displayCounter > framesperSecond / 4) {
|
||||
response -> putDataIntoBuffer (lbuf, T_u);
|
||||
showImpulse (T_u);
|
||||
displayCounter = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* that gives us a basis for defining the actual threshold value
|
||||
*/
|
||||
|
@@ -32,11 +32,18 @@ int16_t res = 1;
|
||||
}
|
||||
|
||||
sampleReader::sampleReader (RadioInterface *mr,
|
||||
virtualInput *theRig) {
|
||||
virtualInput *theRig,
|
||||
RingBuffer<std::complex<float>>*spectrumBuffer) {
|
||||
int i;
|
||||
this -> theRig = theRig;
|
||||
this -> spectrumBuffer = spectrumBuffer;
|
||||
bufferSize = 32768;
|
||||
localCounter = 0;
|
||||
connect (this, SIGNAL (show_Spectrum (int)),
|
||||
mr, SLOT (showSpectrum (int)));
|
||||
localBuffer. resize (bufferSize);
|
||||
localCounter = 0;
|
||||
connect (this, SIGNAL (show_Corrector (int)),
|
||||
mr, SLOT (set_CorrectorDisplay (int)));
|
||||
currentPhase = 0;
|
||||
sLevel = 0;
|
||||
sampleCount = 0;
|
||||
@@ -48,7 +55,7 @@ int i;
|
||||
|
||||
bufferContent = 0;
|
||||
corrector = 0;
|
||||
dumpfilePointer. store (NULL);
|
||||
dumpfilePointer. store (nullptr);
|
||||
dumpIndex = 0;
|
||||
dumpScale = valueFor (theRig -> bitDepth ());
|
||||
}
|
||||
@@ -69,7 +76,7 @@ std::complex<float> sampleReader::getSample (int32_t phaseOffset) {
|
||||
std::complex<float> temp;
|
||||
|
||||
corrector = phaseOffset;
|
||||
if (!running. load ())
|
||||
if (!running. load ())
|
||||
throw 21;
|
||||
|
||||
/// bufferContent is an indicator for the value of ... -> Samples ()
|
||||
@@ -87,7 +94,7 @@ std::complex<float> temp;
|
||||
// so here, bufferContent > 0
|
||||
theRig -> getSamples (&temp, 1);
|
||||
bufferContent --;
|
||||
if (dumpfilePointer. load () != NULL) {
|
||||
if (dumpfilePointer. load () != nullptr) {
|
||||
dumpBuffer [2 * dumpIndex ] = real (temp) * dumpScale;
|
||||
dumpBuffer [2 * dumpIndex + 1] = imag (temp) * dumpScale;
|
||||
if ( ++dumpIndex >= DUMPSIZE / 2) {
|
||||
@@ -97,6 +104,9 @@ std::complex<float> temp;
|
||||
}
|
||||
}
|
||||
|
||||
if (localCounter < bufferSize)
|
||||
localBuffer [localCounter ++] = temp;
|
||||
|
||||
// OK, we have a sample!!
|
||||
// first: adjust frequency. We need Hz accuracy
|
||||
currentPhase -= phaseOffset;
|
||||
@@ -109,6 +119,12 @@ std::complex<float> temp;
|
||||
if (++ sampleCount > INPUT_RATE / N) {
|
||||
show_Corrector (corrector);
|
||||
sampleCount = 0;
|
||||
if (spectrumBuffer != nullptr) {
|
||||
spectrumBuffer -> putDataIntoBuffer (localBuffer. data (),
|
||||
localCounter);
|
||||
emit show_Spectrum (bufferSize);
|
||||
}
|
||||
localCounter = 0;
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
@@ -133,8 +149,10 @@ int32_t i;
|
||||
//
|
||||
// so here, bufferContent >= n
|
||||
n = theRig -> getSamples (v, n);
|
||||
if (!running. load ())
|
||||
throw 20;
|
||||
bufferContent -= n;
|
||||
if (dumpfilePointer. load () != NULL) {
|
||||
if (dumpfilePointer. load () != nullptr) {
|
||||
for (i = 0; i < n; i ++) {
|
||||
dumpBuffer [2 * dumpIndex ] = real (v [i]) * dumpScale;
|
||||
dumpBuffer [2 * dumpIndex + 1] = imag (v [i]) * dumpScale;
|
||||
@@ -153,6 +171,8 @@ int32_t i;
|
||||
//
|
||||
// Note that "phase" itself might be negative
|
||||
currentPhase = (currentPhase + INPUT_RATE) % INPUT_RATE;
|
||||
if (localCounter < bufferSize)
|
||||
localBuffer [localCounter ++] = v [i];
|
||||
v [i] *= oscillatorTable [currentPhase];
|
||||
sLevel = 0.00001 * jan_abs (v [i]) + (1 - 0.00001) * sLevel;
|
||||
}
|
||||
@@ -160,7 +180,11 @@ int32_t i;
|
||||
sampleCount += n;
|
||||
if (sampleCount > INPUT_RATE / N) {
|
||||
show_Corrector (corrector);
|
||||
localCounter = 0;
|
||||
if (spectrumBuffer != nullptr) {
|
||||
spectrumBuffer -> putDataIntoBuffer (localBuffer. data (),
|
||||
bufferSize);
|
||||
emit show_Spectrum (bufferSize);
|
||||
}
|
||||
sampleCount = 0;
|
||||
}
|
||||
}
|
||||
@@ -170,6 +194,6 @@ void sampleReader::startDumping (SNDFILE *f) {
|
||||
}
|
||||
|
||||
void sampleReader::stopDumping (void) {
|
||||
dumpfilePointer. store (NULL);
|
||||
dumpfilePointer. store (nullptr);
|
||||
}
|
||||
|
||||
|
65
src/ofdm/timesyncer.cpp
Normal file
65
src/ofdm/timesyncer.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
|
||||
#include "timesyncer.h"
|
||||
#include "sample-reader.h"
|
||||
|
||||
#define C_LEVEL_SIZE 50
|
||||
|
||||
timeSyncer::timeSyncer (sampleReader *mr) {
|
||||
myReader = mr;
|
||||
}
|
||||
|
||||
timeSyncer::~timeSyncer (void) {}
|
||||
|
||||
int timeSyncer::sync (int T_null, int T_F) {
|
||||
float cLevel = 0;
|
||||
int counter = 0;
|
||||
float envBuffer [syncBufferSize];
|
||||
const
|
||||
int syncBufferMask = syncBufferSize - 1;
|
||||
int i;
|
||||
|
||||
syncBufferIndex = 0;
|
||||
for (i = 0; i < C_LEVEL_SIZE; i ++) {
|
||||
std::complex<float> sample = myReader -> getSample (0);
|
||||
envBuffer [syncBufferIndex] = jan_abs (sample);
|
||||
cLevel += envBuffer [syncBufferIndex];
|
||||
syncBufferIndex ++;
|
||||
}
|
||||
//SyncOnNull:
|
||||
counter = 0;
|
||||
while (cLevel / C_LEVEL_SIZE > 0.50 * myReader -> get_sLevel ()) {
|
||||
std::complex<float> sample =
|
||||
myReader -> getSample (0);
|
||||
// myReader. getSample (coarseOffset + fineCorrector);
|
||||
envBuffer [syncBufferIndex] = jan_abs (sample);
|
||||
// update the levels
|
||||
cLevel += envBuffer [syncBufferIndex] -
|
||||
envBuffer [(syncBufferIndex - C_LEVEL_SIZE) & syncBufferMask];
|
||||
syncBufferIndex = (syncBufferIndex + 1) & syncBufferMask;
|
||||
counter ++;
|
||||
if (counter > T_F) { // hopeless
|
||||
return NO_DIP_FOUND;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* It seemed we found a dip that started app 65/100 * 50 samples earlier.
|
||||
* We now start looking for the end of the null period.
|
||||
*/
|
||||
counter = 0;
|
||||
//SyncOnEndNull:
|
||||
while (cLevel / C_LEVEL_SIZE < 0.75 * myReader -> get_sLevel ()) {
|
||||
std::complex<float> sample =
|
||||
myReader -> getSample (0);
|
||||
envBuffer [syncBufferIndex] = jan_abs (sample);
|
||||
// update the levels
|
||||
cLevel += envBuffer [syncBufferIndex] -
|
||||
envBuffer [(syncBufferIndex - C_LEVEL_SIZE) & syncBufferMask];
|
||||
syncBufferIndex = (syncBufferIndex + 1) & syncBufferMask;
|
||||
counter ++;
|
||||
if (counter > T_null + 50) { // hopeless
|
||||
return NO_END_OF_DIP_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
return TIMESYNC_ESTABLISHED;
|
||||
}
|
673
src/support/dab_tables.cpp
Normal file
673
src/support/dab_tables.cpp
Normal file
@@ -0,0 +1,673 @@
|
||||
#
|
||||
/*
|
||||
* Copyright (C) 2018
|
||||
* Hayati Ayguen (h_ayguen@web.de)
|
||||
*
|
||||
* DAB-library 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.
|
||||
*
|
||||
* DAB-library 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 DAB-library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "dab_tables.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
// ETSI TS 101 756 V2.2.1: Registered Tables
|
||||
// for Extended Country Code, Country Id, Language Code,
|
||||
// Program Type, User Application Type, Content Type
|
||||
// https://www.etsi.org/deliver/etsi_ts/101700_101799/101756/02.02.01_60/ts_101756v020201p.pdf
|
||||
|
||||
// ETSI TR 101 496-3 V1.1.2
|
||||
// protection level/classes, ..
|
||||
// https://www.etsi.org/deliver/etsi_tr/101400_101499/10149603/01.01.02_60/tr_10149603v010102p.pdf
|
||||
|
||||
static const char *uep_rates [] = {"7/20", "2/5", "1/2", "3/5"};
|
||||
static const char *eep_Arates[] = {"1/4", "3/8", "1/2", "3/4"}; // see ETSI EN 300 401 V1.3.2 (2000-09), Table 8, page 46
|
||||
static const char *eep_Brates[] = {"4/9", "4/7", "4/6", "4/5"}; // see ETSI EN 300 401 V1.3.2 (2000-09), Table 9, page 46
|
||||
|
||||
|
||||
struct country_codes {
|
||||
uint8_t ecc;
|
||||
uint8_t countryId;
|
||||
const char *countryName;
|
||||
};
|
||||
|
||||
// following countryTable[] is sorted over all regions to make
|
||||
// it easier to find "missing" / "old" but still unused entries.
|
||||
// achieved by searching old standard tables document for each ECC code.
|
||||
// Table 3: ITU Region 1 - European broadcasting area
|
||||
// Table 4: ITU Region 1 - African broadcasting area
|
||||
// Table 6: ITU Region 2 - North and South Americas
|
||||
// Table 7: ITU Region 3 - Asia and Pacific
|
||||
|
||||
static country_codes countryTable[] = {
|
||||
{0xA0, 0x1, "United States of America"},
|
||||
{0xA0, 0x2, "United States of America"},
|
||||
{0xA0, 0x3, "United States of America"},
|
||||
{0xA0, 0x4, "United States of America"},
|
||||
{0xA0, 0x5, "United States of America"},
|
||||
{0xA0, 0x6, "United States of America"},
|
||||
{0xA0, 0x7, "United States of America"},
|
||||
{0xA0, 0x8, "United States of America"},
|
||||
{0xA0, 0x9, "United States of America"},
|
||||
{0xA0, 0xA, "United States of America"},
|
||||
{0xA0, 0xB, "United States of America"},
|
||||
{0xA0, 0xC, "United States of America"},
|
||||
{0xA0, 0xD, "United States of America"},
|
||||
{0xA0, 0xE, "United States of America"},
|
||||
|
||||
{0xA1, 0xC, "Canada"},
|
||||
{0xA1, 0xF, "Greenland"},
|
||||
|
||||
{0xA2, 0x1, "Anguilla"},
|
||||
{0xA2, 0x2, "Antigua and Barbuda"},
|
||||
{0xA2, 0x3, "Equador"},
|
||||
{0xA2, 0x4, "Falkland Islands"},
|
||||
{0xA2, 0x5, "Barbados"},
|
||||
{0xA2, 0x6, "Belize"},
|
||||
{0xA2, 0x7, "Cayman Islands"},
|
||||
{0xA2, 0x8, "Costa Rica"},
|
||||
{0xA2, 0x9, "Cuba"},
|
||||
{0xA2, 0xA, "Argentina"},
|
||||
{0xA2, 0xB, "Brazil"},
|
||||
{0xA2, 0xC, "Bermuda"},
|
||||
{0xA2, 0xD, "Netherlands Antilles"},
|
||||
{0xA2, 0xE, "Guadeloupe"},
|
||||
{0xA2, 0xF, "Bahamas"},
|
||||
|
||||
{0xA3, 0x1, "Bolivia"},
|
||||
{0xA3, 0x2, "Colombia"},
|
||||
{0xA3, 0x3, "Jamaica"},
|
||||
{0xA3, 0x4, "Martinique"},
|
||||
{0xA3, 0x6, "Paraguay"},
|
||||
{0xA3, 0x7, "Nicaragua"},
|
||||
{0xA3, 0x8, "Puerto Rico"},
|
||||
{0xA3, 0x9, "Panama"},
|
||||
{0xA3, 0xA, "Dominica"},
|
||||
{0xA3, 0xB, "Dominican Republic"},
|
||||
{0xA3, 0xC, "Chile"},
|
||||
{0xA3, 0xD, "Grenada"},
|
||||
{0xA3, 0xE, "Turks and Caicos islands"},
|
||||
{0xA3, 0xF, "Guyana"},
|
||||
|
||||
{0xA4, 0x1, "Guatemala"},
|
||||
{0xA4, 0x2, "Honduras"},
|
||||
{0xA4, 0x3, "Aruba"},
|
||||
{0xA4, 0x5, "Montserrat"},
|
||||
{0xA4, 0x6, "Trinidad and Tobago"},
|
||||
{0xA4, 0x7, "Peru"},
|
||||
{0xA4, 0x8, "Surinam"},
|
||||
{0xA4, 0x9, "Uruguay"},
|
||||
{0xA4, 0xA, "St. Kitts"},
|
||||
{0xA4, 0xB, "St. Lucia"},
|
||||
{0xA4, 0xC, "El Salvador"},
|
||||
{0xA4, 0xD, "Haiti"},
|
||||
{0xA4, 0xE, "Venezuela"},
|
||||
{0xA4, 0xF, "Mexico"},
|
||||
|
||||
{0xA5, 0xC, "St. Vincent"},
|
||||
{0xA5, 0xF, "Virgin islands (British or USA)"}, // British and USA have same IDs! amended "or USA"
|
||||
{0xA5, 0xF, "Virgin islands (USA)"}, // keep this entry .. doesn't hurt
|
||||
|
||||
{0xA6, 0xF, "St. Pierre and Miquelon"},
|
||||
|
||||
{0xD0, 0x1, "Cameroon"},
|
||||
{0xD0, 0x2, "Central African Republic"},
|
||||
{0xD0, 0x3, "Djibouti"},
|
||||
{0xD0, 0x4, "Madagascar"},
|
||||
{0xD0, 0x5, "Mali"},
|
||||
{0xD0, 0x6, "Angola"},
|
||||
{0xD0, 0x7, "Equatorial Guinea"},
|
||||
{0xD0, 0x8, "Gabon"},
|
||||
{0xD0, 0x9, "Republic of Guinea"},
|
||||
{0xD0, 0xA, "South Africa"},
|
||||
{0xD0, 0xB, "Burkina Faso"},
|
||||
{0xD0, 0xC, "Congo"},
|
||||
{0xD0, 0xD, "Togo"},
|
||||
{0xD0, 0xE, "Benin"},
|
||||
{0xD0, 0xF, "Malawi"},
|
||||
|
||||
{0xD1, 0x1, "Namibia"},
|
||||
{0xD1, 0x2, "Liberia"},
|
||||
{0xD1, 0x3, "Ghana"},
|
||||
{0xD1, 0x4, "Mauritania"},
|
||||
{0xD1, 0x5, "Sao Tome & Principe"},
|
||||
{0xD1, 0x6, "Cape Verde"},
|
||||
{0xD1, 0x7, "Senegal"},
|
||||
{0xD1, 0x8, "Gambia"},
|
||||
{0xD1, 0x9, "Burundi"},
|
||||
{0xD1, 0xA, "Ascension island"},
|
||||
{0xD1, 0xB, "Botswana"},
|
||||
{0xD1, 0xC, "Comoros"},
|
||||
{0xD1, 0xD, "Tanzania"},
|
||||
{0xD1, 0xE, "Ethiopia"},
|
||||
{0xD1, 0xF, "Nigeria"},
|
||||
|
||||
{0xD2, 0x1, "Sierra Leone"},
|
||||
{0xD2, 0x2, "Zimbabwe"},
|
||||
{0xD2, 0x3, "Mozambique"},
|
||||
{0xD2, 0x4, "Uganda"},
|
||||
{0xD2, 0x5, "Swaziland"},
|
||||
{0xD2, 0x6, "Kenya"},
|
||||
{0xD2, 0x7, "Somalia"},
|
||||
{0xD2, 0x8, "Niger"},
|
||||
{0xD2, 0x9, "Chad"},
|
||||
{0xD2, 0xA, "Guinea-Bissau"},
|
||||
{0xD2, 0xB, "Zaire"},
|
||||
{0xD2, 0xC, "Cote d'Ivoire"},
|
||||
{0xD2, 0xD, "Zanzibar"},
|
||||
{0xD2, 0xE, "Zambia"},
|
||||
|
||||
{0xD3, 0x3, "Western Sahara"},
|
||||
{0xD3, 0x4, "Cabinda"}, // was in V1.4.1. was removed later. but IDs are unused .. so keep it here
|
||||
{0xD3, 0x5, "Rwanda"},
|
||||
{0xD3, 0x6, "Lesotho"},
|
||||
{0xD3, 0x8, "Seychelles"},
|
||||
{0xD3, 0xA, "Mauritius"},
|
||||
{0xD3, 0xC, "Sudan"},
|
||||
|
||||
{0xE0, 0x1, "Germany"},
|
||||
{0xE0, 0x2, "Algeria"},
|
||||
{0xE0, 0x3, "Andorra"},
|
||||
{0xE0, 0x4, "Israel"},
|
||||
{0xE0, 0x5, "Italy"},
|
||||
{0xE0, 0x6, "Belgium"},
|
||||
{0xE0, 0x7, "Russian Federation"},
|
||||
{0xE0, 0x8, "Azores (Portugal)"}, // was in V1.4.1. was removed later. but IDs are unused .. so keep it here
|
||||
{0xE0, 0x9, "Albania"},
|
||||
{0xE0, 0xA, "Austria"},
|
||||
{0xE0, 0xB, "Hungary"},
|
||||
{0xE0, 0xC, "Malta"},
|
||||
{0xE0, 0xD, "Germany"},
|
||||
{0xE0, 0xE, "Canary Islands (Spain)"}, // amended "(Spain)"
|
||||
{0xE0, 0xF, "Egypt"},
|
||||
|
||||
{0xE1, 0x1, "Greece"},
|
||||
{0xE1, 0x2, "Cyprus"},
|
||||
{0xE1, 0x3, "San Marino"},
|
||||
{0xE1, 0x4, "Switzerland"},
|
||||
{0xE1, 0x5, "Jordan"},
|
||||
{0xE1, 0x6, "Finland"},
|
||||
{0xE1, 0x7, "Luxembourg"},
|
||||
{0xE1, 0x8, "Bulgaria"},
|
||||
{0xE1, 0x9, "Faroe (Denmark)"},
|
||||
{0xE1, 0xA, "Gibraltar (UK)"}, // amended "(UK)"
|
||||
{0xE1, 0xB, "Iraq"},
|
||||
{0xE1, 0xC, "United Kingdom"},
|
||||
{0xE1, 0xD, "Libya"},
|
||||
{0xE1, 0xE, "Romania"},
|
||||
{0xE1, 0xF, "France"},
|
||||
|
||||
{0xE2, 0x1, "Marocco"},
|
||||
{0xE2, 0x2, "Czech Republic"},
|
||||
{0xE2, 0x3, "Poland"},
|
||||
{0xE2, 0x4, "Vatican"},
|
||||
{0xE2, 0x5, "Slovak Republic"},
|
||||
{0xE2, 0x6, "Syria"},
|
||||
{0xE2, 0x7, "Tunisia"},
|
||||
{0xE2, 0x8, "Madeira"}, // was in V1.4.1. was removed later. but IDs are unused .. so keep it here
|
||||
{0xE2, 0x9, "Liechtenstein"},
|
||||
{0xE2, 0xA, "Iceland"},
|
||||
{0xE2, 0xB, "Monaco"},
|
||||
{0xE2, 0xC, "Lithuania"},
|
||||
{0xE2, 0xD, "Serbia"},
|
||||
{0xE2, 0xE, "Spain"},
|
||||
{0xE2, 0xF, "Norway"},
|
||||
|
||||
{0xE3, 0x1, "Montenegro"},
|
||||
{0xE3, 0x2, "Ireland"},
|
||||
{0xE3, 0x3, "Turkey"},
|
||||
{0xE3, 0x4, "Macedonia"},
|
||||
{0xE3, 0x5, "Tajikistan"}, // was in V1.4.1. was removed later. but IDs are unused .. so keep it here
|
||||
{0xE3, 0x8, "Netherlands"},
|
||||
{0xE3, 0x9, "Latvia"},
|
||||
{0xE3, 0xA, "Lebanon"},
|
||||
{0xE3, 0xB, "Azerbaijan"}, // was in V1.4.1. was removed later. but IDs are unused .. so keep it here
|
||||
{0xE3, 0xC, "Croatia"},
|
||||
{0xE3, 0xD, "Kazakhstan"}, // was in V1.4.1. was removed later. but IDs are unused .. so keep it here
|
||||
{0xE3, 0xE, "Sweden"},
|
||||
{0xE3, 0xF, "Belarus"},
|
||||
|
||||
{0xE4, 0x1, "Moldova"},
|
||||
{0xE4, 0x2, "Estonia"},
|
||||
{0xE4, 0x3, "Macedonia / Kyrghyzstan"}, // amended "/ Kyrghyzstan" double used Id
|
||||
{0xE4, 0x3, "Kyrghyzstan"}, // keep this entry .. doesn't hurt
|
||||
{0xE4, 0x6, "Ukraine"},
|
||||
{0xE4, 0x7, "Kosovo"},
|
||||
{0xE4, 0x8, "Portugal"},
|
||||
{0xE4, 0x9, "Slovenia"},
|
||||
{0xE4, 0xA, "Armenia"},
|
||||
{0xE4, 0xB, "Uzbekistan"},
|
||||
{0xE4, 0xC, "Georgia"},
|
||||
{0xE4, 0xE, "Turkmenistan"},
|
||||
{0xE4, 0xF, "Bosnia Herzegovina"},
|
||||
|
||||
{0xF0, 0x1, "Australia: Capital Cities (commercial and community)"},
|
||||
{0xF0, 0x2, "Australia: New South Wales and ACT"},
|
||||
{0xF0, 0x3, "Australia: Capital Cities (national broadcasters, was Victoria)"},
|
||||
{0xF0, 0x4, "Australia: Queensland"},
|
||||
{0xF0, 0x5, "Australia: South and Northern Territory"},
|
||||
{0xF0, 0x6, "Australia: Western"},
|
||||
{0xF0, 0x7, "Australia: Victoria and Tasmania"},
|
||||
{0xF0, 0x8, "Australia: (future, was Northern Territory)"},
|
||||
{0xF0, 0x9, "Saudi Arabia"},
|
||||
{0xF0, 0xA, "Afghanistan"},
|
||||
{0xF0, 0xB, "Myanmar (Burma)"},
|
||||
{0xF0, 0xC, "China"},
|
||||
{0xF0, 0xD, "Korea (North)"},
|
||||
{0xF0, 0xE, "Bahrain"},
|
||||
{0xF0, 0xF, "Malaysia"},
|
||||
|
||||
{0xF1, 0x1, "Kiribati"},
|
||||
{0xF1, 0x2, "Bhutan"},
|
||||
{0xF1, 0x3, "Bangladesh"},
|
||||
{0xF1, 0x4, "Pakistan"},
|
||||
{0xF1, 0x5, "Fiji"},
|
||||
{0xF1, 0x6, "Oman"},
|
||||
{0xF1, 0x7, "Nauru"},
|
||||
{0xF1, 0x8, "Iran"},
|
||||
{0xF1, 0x9, "New Zealand"},
|
||||
{0xF1, 0xA, "Solomon Islands"},
|
||||
{0xF1, 0xB, "Brunei Darussalam"},
|
||||
{0xF1, 0xC, "Sri Lanka"},
|
||||
{0xF1, 0xD, "Taiwan"},
|
||||
{0xF1, 0xE, "Korea (South)"},
|
||||
{0xF1, 0xF, "Hong Kong"},
|
||||
|
||||
{0xF2, 0x1, "Kuwait"},
|
||||
{0xF2, 0x2, "Qatar"},
|
||||
{0xF2, 0x3, "Cambodia"},
|
||||
{0xF2, 0x4, "Western Samoa"},
|
||||
{0xF2, 0x5, "India"},
|
||||
{0xF2, 0x6, "Macau"},
|
||||
{0xF2, 0x7, "Vietnam"},
|
||||
{0xF2, 0x8, "Philippines"},
|
||||
{0xF2, 0x9, "Japan"},
|
||||
{0xF2, 0xA, "Singapore"},
|
||||
{0xF2, 0xB, "Maldives"},
|
||||
{0xF2, 0xC, "Indonesia"},
|
||||
{0xF2, 0xD, "United Arab Emirates"},
|
||||
{0xF2, 0xE, "Nepal"},
|
||||
{0xF2, 0xF, "Vanuatu"},
|
||||
|
||||
{0xF3, 0x1, "Laos"},
|
||||
{0xF3, 0x2, "Thailand"},
|
||||
{0xF3, 0x3, "Tonga"},
|
||||
{0xF3, 0x9, "Papua New Guinea"},
|
||||
{0xF3, 0xB, "Yemen"},
|
||||
{0xF3, 0xE, "Micronesia"},
|
||||
{0xF3, 0xF, "Mongolia"},
|
||||
|
||||
{0x00, 0x0, nullptr }
|
||||
};
|
||||
|
||||
// from Table 2a
|
||||
const char * getASCTy (int16_t ASCTy) {
|
||||
switch (ASCTy) {
|
||||
case 0: return "DAB";
|
||||
case 63: return "DAB+";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
// from Table 2b
|
||||
const char * getDSCTy (int16_t DSCTy) {
|
||||
switch (DSCTy) {
|
||||
case 1: return "Traffic Message CHannel (TMC)";
|
||||
case 2: return "Emergency Warning System (EWS)";
|
||||
case 3: return "Interactive Text Transmission System (ITTS)";
|
||||
case 4: return "Paging";
|
||||
case 5: return "Transparent Data Channel (TDC)";
|
||||
case 24: return "MPEG-2 Transport Stream";
|
||||
case 59: return "Embedded IP packets";
|
||||
case 60: return "Multimedia Object Transfer (MOT)";
|
||||
case 61: return "Proprietary service";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
// from Table 9 and 10
|
||||
const char * getLanguage (int16_t language) {
|
||||
switch (language) {
|
||||
case 0x00: return "Unknown/not applicable";
|
||||
case 0x01: return "Albanian";
|
||||
case 0x02: return "Breton";
|
||||
case 0x03: return "Catalan";
|
||||
case 0x04: return "Croatian";
|
||||
case 0x05: return "Welsh";
|
||||
case 0x06: return "Czech";
|
||||
case 0x07: return "Danish";
|
||||
case 0x08: return "German";
|
||||
case 0x09: return "English";
|
||||
case 0x0A: return "Spanish";
|
||||
case 0x0B: return "Esperanto";
|
||||
case 0x0C: return "Estonian";
|
||||
case 0x0D: return "Basque";
|
||||
case 0x0E: return "Faroese";
|
||||
case 0x0F: return "French";
|
||||
case 0x10: return "Frisian";
|
||||
case 0x11: return "Irish";
|
||||
case 0x12: return "Gaelic";
|
||||
case 0x13: return "Galician";
|
||||
case 0x14: return "Icelandic";
|
||||
case 0x15: return "Italian";
|
||||
case 0x16: return "Sami";
|
||||
case 0x17: return "Latin";
|
||||
case 0x18: return "Latvian";
|
||||
case 0x19: return "Luxembourgian";
|
||||
case 0x1A: return "Lithuanian";
|
||||
case 0x1B: return "Hungarian";
|
||||
case 0x1C: return "Maltese";
|
||||
case 0x1D: return "Dutch";
|
||||
case 0x1E: return "Norwegian";
|
||||
case 0x1F: return "Occitan";
|
||||
case 0x20: return "Polish";
|
||||
case 0x21: return "Portuguese";
|
||||
case 0x22: return "Romanian";
|
||||
case 0x23: return "Romansh";
|
||||
case 0x24: return "Serbian";
|
||||
case 0x25: return "Slovak";
|
||||
case 0x26: return "Slovene";
|
||||
case 0x27: return "Finnish";
|
||||
case 0x28: return "Swedish";
|
||||
case 0x29: return "Turkish";
|
||||
case 0x2A: return "Flemish";
|
||||
case 0x2B: return "Walloon";
|
||||
case 0x30: // no break
|
||||
case 0x31: // no break
|
||||
case 0x32: // no break
|
||||
case 0x33: // no break
|
||||
case 0x34: // no break
|
||||
case 0x35: // no break
|
||||
case 0x36: // no break
|
||||
case 0x37: // no break
|
||||
case 0x38: // no break
|
||||
case 0x39: // no break
|
||||
case 0x3A: // no break
|
||||
case 0x3B: // no break
|
||||
case 0x3C: // no break
|
||||
case 0x3D: // no break
|
||||
case 0x3E: // no break
|
||||
case 0x3F: return "Reserved for national assignment";
|
||||
case 0x7F: return "Amharic";
|
||||
case 0x7E: return "Arabic";
|
||||
case 0x7D: return "Armenian";
|
||||
case 0x7C: return "Assamese";
|
||||
case 0x7B: return "Azerbaijani";
|
||||
case 0x7A: return "Bambora";
|
||||
case 0x79: return "Belorussian";
|
||||
case 0x78: return "Bengali";
|
||||
case 0x77: return "Bulgarian";
|
||||
case 0x76: return "Burmese";
|
||||
case 0x75: return "Chinese";
|
||||
case 0x74: return "Chuvash";
|
||||
case 0x73: return "Dari";
|
||||
case 0x72: return "Fulani";
|
||||
case 0x71: return "Georgian";
|
||||
case 0x70: return "Greek";
|
||||
case 0x6F: return "Gujurati";
|
||||
case 0x6E: return "Gurani";
|
||||
case 0x6D: return "Hausa";
|
||||
case 0x6C: return "Hebrew";
|
||||
case 0x6B: return "Hindi";
|
||||
case 0x6A: return "Indonesian";
|
||||
case 0x69: return "Japanese";
|
||||
case 0x68: return "Kannada";
|
||||
case 0x67: return "Kazakh";
|
||||
case 0x66: return "Khmer";
|
||||
case 0x65: return "Korean";
|
||||
case 0x64: return "Laotian";
|
||||
case 0x63: return "Macedonian";
|
||||
case 0x62: return "Malagasay";
|
||||
case 0x61: return "Malaysian";
|
||||
case 0x60: return "Moldavian";
|
||||
case 0x5F: return "Marathi";
|
||||
case 0x5E: return "Ndebele";
|
||||
case 0x5D: return "Nepali";
|
||||
case 0x5C: return "Oriya";
|
||||
case 0x5B: return "Papiamento";
|
||||
case 0x5A: return "Persian";
|
||||
case 0x59: return "Punjabi";
|
||||
case 0x58: return "Pushtu";
|
||||
case 0x57: return "Quechua";
|
||||
case 0x56: return "Russian";
|
||||
case 0x55: return "Rusyn";
|
||||
case 0x54: return "Serbo-Croat";
|
||||
case 0x53: return "Shona";
|
||||
case 0x52: return "Sinhalese";
|
||||
case 0x51: return "Somali";
|
||||
case 0x50: return "Sranan Tongo";
|
||||
case 0x4F: return "Swahili";
|
||||
case 0x4E: return "Tadzhik";
|
||||
case 0x4D: return "Tamil";
|
||||
case 0x4C: return "Tatar";
|
||||
case 0x4B: return "Telugu";
|
||||
case 0x4A: return "Thai";
|
||||
case 0x49: return "Ukranian";
|
||||
case 0x48: return "Urdu";
|
||||
case 0x47: return "Uzbek";
|
||||
case 0x46: return "Vietnamese";
|
||||
case 0x45: return "Zulu";
|
||||
case 0x40: return "Background sound/clean feed";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
const char *getCountry (uint8_t ecc, uint8_t countryId) {
|
||||
int16_t i = 0;
|
||||
|
||||
while (countryTable [i].ecc != 0) {
|
||||
if ((countryTable[i].ecc == ecc) &&
|
||||
(countryTable[i].countryId == countryId) )
|
||||
return countryTable[i].countryName;
|
||||
++i;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// from Table 12
|
||||
const char *getProgramType_Not_NorthAmerica (int16_t programType) {
|
||||
|
||||
switch (programType) {
|
||||
case 0: return "No programme type";
|
||||
case 1: return "News";
|
||||
case 2: return "Current Affairs";
|
||||
case 3: return "Information";
|
||||
case 4: return "Sport";
|
||||
case 5: return "Education";
|
||||
case 6: return "Drama";
|
||||
case 7: return "Culture";
|
||||
case 8: return "Science";
|
||||
case 9: return "Varied"; //Talk
|
||||
case 10: return "Pop Music";
|
||||
case 11: return "Rock Music";
|
||||
case 12: return "Easy Listening Music";
|
||||
case 13: return "Light Classical";
|
||||
case 14: return "Serious Classical";
|
||||
case 15: return "Other Music";
|
||||
case 16: return "Weather/meteorology";
|
||||
case 17: return "Finance/Business";
|
||||
case 18: return "Children's programmes";
|
||||
case 19: return "Social Affairs"; //Factual
|
||||
case 20: return "Religion";
|
||||
case 21: return "Phone In";
|
||||
case 22: return "Travel";
|
||||
case 23: return "Leisure";
|
||||
case 24: return "Jazz Music";
|
||||
case 25: return "Country Music";
|
||||
case 26: return "National Music";
|
||||
case 27: return "Oldies Music";
|
||||
case 28: return "Folk Music";
|
||||
case 29: return "Documentary";
|
||||
case 30: return "unknown programme type 30";
|
||||
case 31: return "unknown programme type 31";
|
||||
default: return "unknown programme type";
|
||||
}
|
||||
}
|
||||
|
||||
// from Table 13
|
||||
const char *getProgramType_For_NorthAmerica (int16_t programType) {
|
||||
switch (programType) {
|
||||
case 0: return "No programme type";
|
||||
case 1: return "News";
|
||||
case 2: return "Information";
|
||||
case 3: return "Sports";
|
||||
case 4: return "Talk";
|
||||
case 5: return "Rock";
|
||||
case 6: return "Classic Rock";
|
||||
case 7: return "Adult Hits";
|
||||
case 8: return "Soft Rock";
|
||||
case 9: return "Top 40";
|
||||
case 10: return "Country";
|
||||
case 11: return "Oldies";
|
||||
case 12: return "Soft";
|
||||
case 13: return "Nostalgia";
|
||||
case 14: return "Jazz";
|
||||
case 15: return "Classical";
|
||||
case 16: return "Rhythm and Blues";
|
||||
case 17: return "Soft Rhythm and Blues";
|
||||
case 18: return "Foreign Language";
|
||||
case 19: return "Religious Music";
|
||||
case 20: return "Religious Talk";
|
||||
case 21: return "Personality";
|
||||
case 22: return "Public";
|
||||
case 23: return "College";
|
||||
case 24: return "unknown programme type 24";
|
||||
case 25: return "unknown programme type 25";
|
||||
case 26: return "unknown programme type 26";
|
||||
case 27: return "unknown programme type 27";
|
||||
case 28: return "unknown programme type 28";
|
||||
case 29: return "Weather";
|
||||
case 30: return "unknown programme type 30";
|
||||
case 31: return "unknown programme type 31";
|
||||
default: return "unknown programme type";
|
||||
}
|
||||
}
|
||||
|
||||
const char *getProgramType (bool gotInterTabId,
|
||||
uint8_t interTabId, int16_t programType) {
|
||||
if (gotInterTabId && (interTabId == 1))
|
||||
return getProgramType_Not_NorthAmerica (programType);
|
||||
else
|
||||
if (gotInterTabId && (interTabId == 2))
|
||||
return getProgramType_For_NorthAmerica (programType);
|
||||
else {
|
||||
switch (programType) {
|
||||
case 0: return "unknown programme type 0";
|
||||
case 1: return "unknown programme type 1";
|
||||
case 2: return "unknown programme type 2";
|
||||
case 3: return "unknown programme type 3";
|
||||
case 4: return "unknown programme type 4";
|
||||
case 5: return "unknown programme type 5";
|
||||
case 6: return "unknown programme type 6";
|
||||
case 7: return "unknown programme type 7";
|
||||
case 8: return "unknown programme type 8";
|
||||
case 9: return "unknown programme type 9";
|
||||
case 10: return "unknown programme type 10";
|
||||
case 11: return "unknown programme type 11";
|
||||
case 12: return "unknown programme type 12";
|
||||
case 13: return "unknown programme type 13";
|
||||
case 14: return "unknown programme type 14";
|
||||
case 15: return "unknown programme type 15";
|
||||
case 16: return "unknown programme type 16";
|
||||
case 17: return "unknown programme type 17";
|
||||
case 18: return "unknown programme type 18";
|
||||
case 19: return "unknown programme type 19";
|
||||
case 20: return "unknown programme type 20";
|
||||
case 21: return "unknown programme type 21";
|
||||
case 22: return "unknown programme type 22";
|
||||
case 23: return "unknown programme type 23";
|
||||
case 24: return "unknown programme type 24";
|
||||
case 25: return "unknown programme type 25";
|
||||
case 26: return "unknown programme type 26";
|
||||
case 27: return "unknown programme type 27";
|
||||
case 28: return "unknown programme type 28";
|
||||
case 29: return "unknown programme type 29";
|
||||
case 30: return "unknown programme type 30";
|
||||
case 31: return "unknown programme type 31";
|
||||
default: return "unknown programme type";
|
||||
}
|
||||
}
|
||||
return "unknown programme type";
|
||||
}
|
||||
|
||||
// 11-bit from HandleFIG0Extension13, see ETSI TS 101 756 table 16
|
||||
const char *getUserApplicationType (int16_t appType) {
|
||||
switch (appType) {
|
||||
case 1: return "Dynamic labels (X-PAD only)";
|
||||
case 2: return "MOT Slide Show";
|
||||
case 3: return "MOT Broadcast Web Site";
|
||||
case 4: return "TPEG";
|
||||
case 5: return "DGPS";
|
||||
case 6: return "TMC";
|
||||
case 7: return "SPI, was EPG";
|
||||
case 8: return "DAB Java";
|
||||
case 9: return "DMB";
|
||||
case 0x00a: return "IPDC services";
|
||||
case 0x00b: return "Voice applications";
|
||||
case 0x00c: return "Middleware";
|
||||
case 0x00d: return "Filecasting";
|
||||
case 0x44a: return "Journaline";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
const char * getFECscheme (int16_t FEC_scheme) {
|
||||
switch (FEC_scheme) {
|
||||
case 0: return "no FEC";
|
||||
case 1: return "FEC";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char * getProtectionLevel (bool shortForm, int16_t protLevel) {
|
||||
if (!shortForm) {
|
||||
switch (protLevel) {
|
||||
case 0: return "EEP 1-A";
|
||||
case 1: return "EEP 2-A";
|
||||
case 2: return "EEP 3-A";
|
||||
case 3: return "EEP 4-A";
|
||||
case 4: return "EEP 1-B";
|
||||
case 5: return "EEP 2-B";
|
||||
case 6: return "EEP 3-B";
|
||||
case 7: return "EEP 4-B";
|
||||
default: return "EEP unknown";
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (protLevel) {
|
||||
case 1: return "UEP 1";
|
||||
case 2: return "UEP 2";
|
||||
case 3: return "UEP 3";
|
||||
case 4: return "UEP 4";
|
||||
case 5: return "UEP 5";
|
||||
default: return "UEP unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char *getCodeRate (bool shortForm, int16_t protLevel) {
|
||||
int h = protLevel;
|
||||
|
||||
if (!shortForm)
|
||||
return ((h & (1 << 2)) == 0) ?
|
||||
eep_Arates [h & 03] :
|
||||
eep_Brates [h & 03]; // EEP -A/-B
|
||||
else
|
||||
return uep_rates [h & 03]; // UEP
|
||||
}
|
||||
|
Reference in New Issue
Block a user