diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/AlsaInput.cpp | 2 | ||||
-rw-r--r-- | src/AlsaInput.h | 15 | ||||
-rw-r--r-- | src/FileInput.cpp | 2 | ||||
-rw-r--r-- | src/FileInput.h | 20 | ||||
-rw-r--r-- | src/JackInput.cpp | 7 | ||||
-rw-r--r-- | src/JackInput.h | 18 | ||||
-rw-r--r-- | src/SampleQueue.h | 53 | ||||
-rw-r--r-- | src/VLCInput.cpp | 33 | ||||
-rw-r--r-- | src/VLCInput.h | 55 | ||||
-rw-r--r-- | src/charset.h | 16 | ||||
-rw-r--r-- | src/dabplus-enc.cpp | 77 | ||||
-rw-r--r-- | src/encryption.h | 1 | ||||
-rw-r--r-- | src/mot-encoder.cpp | 65 | ||||
-rw-r--r-- | src/utils.h | 5 |
14 files changed, 267 insertions, 102 deletions
diff --git a/src/AlsaInput.cpp b/src/AlsaInput.cpp index e5fd420..293232f 100644 --- a/src/AlsaInput.cpp +++ b/src/AlsaInput.cpp @@ -35,7 +35,7 @@ int AlsaInput::prepare() fprintf(stderr, "Initialising ALSA...\n"); - const int open_mode = 0; //|= SND_PCM_NONBLOCK; + const int open_mode = 0; if ((err = snd_pcm_open(&m_alsa_handle, m_alsa_dev.c_str(), SND_PCM_STREAM_CAPTURE, open_mode)) < 0) { diff --git a/src/AlsaInput.h b/src/AlsaInput.h index 34886df..a17134b 100644 --- a/src/AlsaInput.h +++ b/src/AlsaInput.h @@ -16,6 +16,10 @@ * and limitations under the License. * ------------------------------------------------------------------- */ +/*! \section ALSA Input + * + * This input uses libasound to get audio data. + */ #ifndef __ALSA_H_ #define __ALSA_H_ @@ -34,8 +38,9 @@ #include "SampleQueue.h" #include "common.h" -/* Common functionality for the direct alsa input and the - * threaded alsa input +/*! Common functionality for the direct alsa input and the + * threaded alsa input. The threaded one is used for + * drift compensation. */ class AlsaInput { @@ -80,10 +85,10 @@ class AlsaInputDirect : public AlsaInput unsigned int rate) : AlsaInput(alsa_dev, channels, rate) { } - /* Read length Bytes from from the alsa device. + /*! Read length Bytes from from the alsa device. * length must be a multiple of channels * bytes_per_sample. * - * Returns the number of bytes read. + * \return the number of bytes read. */ ssize_t read(uint8_t* buf, size_t length); @@ -112,7 +117,7 @@ class AlsaInputThreaded : public AlsaInput } } - /* Start the ALSA thread that fills the queue */ + /*! Start the ALSA thread that fills the queue */ virtual void start(); bool fault_detected() { return m_fault; }; diff --git a/src/FileInput.cpp b/src/FileInput.cpp index eae484f..d6c33cf 100644 --- a/src/FileInput.cpp +++ b/src/FileInput.cpp @@ -1,5 +1,5 @@ /* ------------------------------------------------------------------ - * Copyright (C) 2014 Matthias P. Braendli + * Copyright (C) 2016 Matthias P. Braendli * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/FileInput.h b/src/FileInput.h index 57cc5a0..937cbd4 100644 --- a/src/FileInput.h +++ b/src/FileInput.h @@ -1,5 +1,5 @@ /* ------------------------------------------------------------------ - * Copyright (C) 2014 Matthias P. Braendli + * Copyright (C) 2016 Matthias P. Braendli * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,16 @@ * and limitations under the License. * ------------------------------------------------------------------- */ +/*! \section File Input + * + * This input reads a wav or raw file. + * + * The raw input needs to be signed 16-bit per sample data, with + * the number of channels corresponding to the command line. + * + * The wav input must also correspond to the parameters on the command + * line (number of channels, rate) + */ #ifndef _FILE_INPUT_H_ #define _FILE_INPUT_H_ @@ -35,15 +45,15 @@ class FileInput ~FileInput(); - /* Open the file and prepare the wav decoder. + /*! Open the file and prepare the wav decoder. * - * Returns nonzero on error + * \return nonzero on error */ int prepare(void); - /* Read length bytes into buf. + /*! Read length bytes into buf. * - * Returns the number of bytes read. + * \return the number of bytes read. */ ssize_t read(uint8_t* buf, size_t length); int eof(); diff --git a/src/JackInput.cpp b/src/JackInput.cpp index 51de6e4..a94f2e7 100644 --- a/src/JackInput.cpp +++ b/src/JackInput.cpp @@ -1,6 +1,6 @@ /* ------------------------------------------------------------------ * Copyright (C) 2011 Martin Storsjo - * Copyright (C) 2013,2014 Matthias P. Braendli + * Copyright (C) 2016 Matthias P. Braendli * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -104,7 +104,10 @@ int JackInput::prepare() void JackInput::jack_process(jack_nframes_t nframes) { - // Convert samples to shorts + /*! JACK works with float samples, we need to convert + * them to shorts first. This is done using a saturated + * conversion to avoid glitches. + */ std::vector<int16_t> buffer(m_channels * nframes); for (int chan = 0; chan < m_channels; chan++) { diff --git a/src/JackInput.h b/src/JackInput.h index 36cd34f..ba4834e 100644 --- a/src/JackInput.h +++ b/src/JackInput.h @@ -1,6 +1,6 @@ /* ------------------------------------------------------------------ * Copyright (C) 2011 Martin Storsjo - * Copyright (C) 2013,2014 Matthias P. Braendli + * Copyright (C) 2016 Matthias P. Braendli * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,11 @@ * and limitations under the License. * ------------------------------------------------------------------- */ +/*! \section JACK Input + * + * This input uses JACK to get audio data. This always uses drift + * compensation, because there is no blocking way to read from JACK. + */ #ifndef __JACK_INPUT_H #define __JACK_INPUT_H @@ -53,13 +58,16 @@ class JackInput } } - /* Prepare the audio input */ + /*! Prepare the audio input + * + * \return 0 on success + */ int prepare(); private: JackInput(const JackInput& other); - jack_client_t* m_client; + jack_client_t *m_client; std::vector<jack_port_t*> m_input_ports; @@ -82,13 +90,13 @@ class JackInput SampleQueue<uint8_t>& m_queue; // Static functions for JACK callbacks - static int process_cb(jack_nframes_t nframes, void* arg) + static int process_cb(jack_nframes_t nframes, void *arg) { ((JackInput*)arg)->jack_process(nframes); return 0; } - static void shutdown_cb(void* arg) + static void shutdown_cb(void *arg) { ((JackInput*)arg)->jack_shutdown(); } diff --git a/src/SampleQueue.h b/src/SampleQueue.h index 09b67c7..994672f 100644 --- a/src/SampleQueue.h +++ b/src/SampleQueue.h @@ -1,10 +1,28 @@ /* - Copyright (C) 2013, 2014, 2015 - Matthias P. Braendli, matthias.braendli@mpb.li + * Copyright (C) 2016 Matthias P. Braendli + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * Matthias P. Braendli, matthias.braendli@mpb.li + */ - An implementation for a threadsafe queue using the C++11 thread library - for audio samples. -*/ +/*! + * \section SampleQueue + * + * An implementation for a threadsafe queue using the C++11 thread library + * for audio samples. + */ #ifndef _SAMPLE_QUEUE_H_ #define _SAMPLE_QUEUE_H_ @@ -21,7 +39,7 @@ #include <cstdio> #include <cmath> -/* This queue is meant to be used by two threads. One producer +/*! This queue is meant to be used by two threads. One producer * that pushes elements into the queue, and one consumer that * retrieves the elements. * @@ -55,7 +73,10 @@ public: m_overruns(0) {} - /* Push a bunch of samples into the buffer */ + /*! Push a bunch of samples into the buffer + * + * \return size of the queue after the push + */ size_t push(const T *val, size_t len) { size_t new_size = 0; @@ -97,11 +118,11 @@ public: return m_queue.size(); } - /* Wait until len elements in the queue are available, + /*! Wait until len elements in the queue are available, * and then fill the buf. If the timeout_ms (expressed in milliseconds * expires), fill the available number of elements. - * Returns the number - * of elemets written into buf + * + * \return the number of elemets written into buf */ size_t pop_wait(T* buf, size_t len, int timeout_ms) { @@ -158,8 +179,9 @@ public: return num_to_copy; } - /* Get up to len elements, place them into the buf array - * Returns the number of elements it was able to take + /*! Get up to len elements, place them into the buf array + * + * \return the number of elements it was able to take * from the queue */ size_t pop(T* buf, size_t len) @@ -168,10 +190,11 @@ public: return pop(buf, len, ovr); } - /* Get up to len elements, place them into the buf array. + /*! Get up to len elements, place them into the buf array. * Also update the overrun variable with the information * of how many overruns we saw since the last pop. - * Returns the number of elements it was able to take + * + * \return the number of elements it was able to take * from the queue */ size_t pop(T* buf, size_t len, size_t* overruns) @@ -243,7 +266,7 @@ private: unsigned int m_bytes_per_sample; size_t m_max_size; - /* Counter to keep track of number of overruns between calls + /*! Counter to keep track of number of overruns between calls * to pop() */ size_t m_overruns; diff --git a/src/VLCInput.cpp b/src/VLCInput.cpp index 33c4594..4831915 100644 --- a/src/VLCInput.cpp +++ b/src/VLCInput.cpp @@ -34,7 +34,11 @@ int check_vlc_uses_size_t(); using namespace std; -// VLC Audio prerender callback +/*! VLC callback functions have to be C functions. + * These wrappers call the VLCInput functions + */ + +//! VLC Audio prerender callback void prepareRender_size_t( void* p_audio_data, uint8_t** pp_pcm_buffer, @@ -45,6 +49,7 @@ void prepareRender_size_t( in->preRender_cb(pp_pcm_buffer, size); } +//! VLC Audio prepare render callback void prepareRender( void* p_audio_data, uint8_t** pp_pcm_buffer, @@ -56,7 +61,7 @@ void prepareRender( } -// Audio postrender callback +//! Audio postrender callback for VLC versions that use size_t void handleStream_size_t( void* p_audio_data, uint8_t* p_pcm_buffer, @@ -79,7 +84,9 @@ void handleStream_size_t( in->postRender_cb(); } -// convert from unsigned int size to size_t size +/*! Audio postrender callback for VLC versions that use unsigned int. + * Convert from unsigned int size to size_t size + */ void handleStream( void* p_audio_data, uint8_t* p_pcm_buffer, @@ -101,7 +108,7 @@ void handleStream( pts); } -// VLC Exit callback +/*! VLC Exit callback */ void handleVLCExit(void* opaque) { ((VLCInput*)opaque)->exit_cb(); @@ -109,7 +116,6 @@ void handleVLCExit(void* opaque) int VLCInput::prepare() { - int err; fprintf(stderr, "Initialising VLC...\n"); long long int handleStream_address; @@ -330,10 +336,11 @@ ssize_t VLCInput::m_read(uint8_t* buf, size_t length) } /* Write the corresponding text to a file readable by mot-encoder, with optional - * DL+ information. The text is passed as a copy because we actually use the m_nowplaying - * variable which is also accessed in another thread, so better make a copy. + * DL+ information. The text is passed as a copy because we actually use the + * m_nowplaying variable which is also accessed in another thread, so better + * make a copy. * - * Returns false on failure + * \return false on failure */ bool write_icy_to_file(const std::string text, const std::string& filename, bool dl_plus) { @@ -379,6 +386,9 @@ void VLCInput::write_icy_text(const std::string& filename, bool dl_plus) std::lock_guard<std::mutex> lock(m_nowplaying_mutex); if (m_nowplaying_previous != m_nowplaying) { + /*! We write the ICY text in a separate task because + * we do not want to have a delay due to IO + */ icy_text_written = std::async(std::launch::async, std::bind(write_icy_to_file, m_nowplaying, filename, dl_plus)); @@ -400,8 +410,9 @@ void VLCInput::start() } } -// How many samples we insert into the queue each call -// 10 samples @ 32kHz = 3.125ms +/*! How many samples we insert into the queue each call + * 10 samples @ 32kHz = 3.125ms + */ #define NUM_BYTES_PER_CALL (10 * BYTES_PER_SAMPLE) void VLCInput::process() @@ -424,7 +435,7 @@ void VLCInput::process() -/* VLC up to version 2.1.0 used a different callback function signature. +/*! VLC up to version 2.1.0 used a different callback function signature. * VLC 2.2.0 uses size_t * * \return 1 if the callback with size_t size should be used. diff --git a/src/VLCInput.h b/src/VLCInput.h index 1ea0bee..6f91e89 100644 --- a/src/VLCInput.h +++ b/src/VLCInput.h @@ -15,6 +15,11 @@ * and limitations under the License. * ------------------------------------------------------------------- */ +/*! \section VLC Input + * + * This input uses libvlc to get audio data. It is extremely useful, and allows + * the encoder to use all inputs VLC supports. + */ #ifndef __VLC_INPUT_H_ #define __VLC_INPUT_H_ @@ -41,8 +46,8 @@ extern "C" { #include "utils.h" } -/* Common functionality for the direct libvlc input and the - * threaded libvlc input +/*! Common functionality for the direct libvlc input and the + * threaded libvlc input */ class VLCInput { @@ -80,28 +85,31 @@ class VLCInput cleanup(); } - /* Prepare the audio input */ + /*! Prepare the audio input + * + * \return 0 on success + */ int prepare(); - /* Start the libVLC thread that fills the samplequeue */ + /*! Start the libVLC thread that fills m_samplequeue */ void start(); - /* Write the last received ICY-Text to the + /*! Write the last received ICY-Text to the * file. */ void write_icy_text(const std::string& filename, bool dl_plus); - // Callbacks for VLC + //! Callbacks for VLC - /* Notification of VLC exit */ + /*! Notification of VLC exit */ void exit_cb(void); - /* Prepare a buffer for VLC */ + /*! Prepare a buffer for VLC */ void preRender_cb( uint8_t** pp_pcm_buffer, size_t size); - /* Notification from VLC that the buffer is now filled + /*! Notification from VLC that the buffer is now filled */ void postRender_cb(); @@ -112,14 +120,23 @@ class VLCInput bool fault_detected() { return m_fault; }; private: + /*! Stop the player and release resources + */ void cleanup(void); - // Fill exactly length bytes into buf. Blocking. + /*! Fill exactly length bytes into buf. Blocking. + * + * \return number of bytes written into buf, or + * -1 in case of error + */ ssize_t m_read(uint8_t* buf, size_t length); + /*! Buffer used in the callback functions for VLC */ std::vector<uint8_t> m_current_buf; std::mutex m_queue_mutex; + + /*! Buffer containing all available samples from VLC */ std::deque<uint8_t> m_queue; std::string m_uri; @@ -127,16 +144,20 @@ class VLCInput unsigned m_channels; int m_rate; - // Whether to enable network caching in VLC or not + //! Whether to enable network caching in VLC or not std::string m_cache; - // Given as-is to libvlc + //! Given as-is to libvlc, useful for additional arguments std::vector<std::string> m_additional_opts; - // value for the VLC compressor filter + /*! value for the VLC compressor filter --compressor-makeup + * setting. Many more compressor settings could be set. + */ std::string m_gain; - + /*! VLC can give us the ICY-Text from an Icecast stream, + * which we optionnally write into a text file for mot-encoder + */ std::future<bool> icy_text_written; std::mutex m_nowplaying_mutex; std::string m_nowplaying; @@ -148,12 +169,16 @@ class VLCInput // For the thread - /* The function runnin in the thread */ + /* The thread running process takes samples from m_queue and writes + * them into m_samplequeue. This decouples m_queue from m_samplequeue + * which is directly used by dabplus-enc.cpp + */ void process(); std::atomic<bool> m_fault; std::atomic<bool> m_running; std::thread m_thread; + SampleQueue<uint8_t>& m_samplequeue; }; diff --git a/src/charset.h b/src/charset.h index 82d81cf..8d1e1a2 100644 --- a/src/charset.h +++ b/src/charset.h @@ -13,13 +13,13 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +/*! + \file charset.h + \brief Define the EBU charset according to ETSI TS 101 756v1.8.1 for DLS encoding - charset.h - Define the EBU charset according to ETSI TS 101 756v1.8.1 for DLS encoding - - Authors: - Matthias P. Braendli <matthias@mpb.li> - Lindsay Cornell + \author Matthias P. Braendli <matthias@mpb.li> + \author Lindsay Cornell */ #ifndef __CHARSET_H_ @@ -65,7 +65,7 @@ class CharsetConverter { public: CharsetConverter() { - /* Build the converstion table that contains the known code points, + /*! Build the converstion table that contains the known code points, * at the indices corresponding to the EBU Latin table */ using namespace std; @@ -77,7 +77,7 @@ class CharsetConverter } } - /* Convert a UTF-8 encoded text line into an EBU Latin encoded byte stream + /*! Convert a UTF-8 encoded text line into an EBU Latin encoded byte stream */ std::string convert(std::string line_utf8) { using namespace std; diff --git a/src/dabplus-enc.cpp b/src/dabplus-enc.cpp index 5b2b403..953073d 100644 --- a/src/dabplus-enc.cpp +++ b/src/dabplus-enc.cpp @@ -17,6 +17,33 @@ * ------------------------------------------------------------------- */ +/*! \mainpage Introduction + * The ODR-mmbTools FDK-AAC-DABplus Audio encoder can encode audio for + * ODR-DabMux, both DAB and DAB+. The DAB encoder is based on toolame. The + * DAB+ encoder uses a modified library of the Fraunhofer FDK AAC code from + * Android, patched for 960-transform to do DAB+ broadcast encoding. + * + * This document describes some internals of the encoder, and is intended + * to help developers understand and improve the software package. + * + * User documentation is available in the README and in the ODR-mmbTools + * Guide, available on the www.opendigitalradio.org website. + * + * The readme for the whole package is \ref md_README + * + * Interesting starting points for the encoder + * - \ref dabplus-enc.cpp + * - \ref VLC Input + * - \ref Alsa Input + * - \ref JACK Input + * - \ref SampleQueue + * - \ref charset.h + * - \ref libtoolame API + * + * For the mot-encoder: + * - \ref mot-encoder.cpp + */ + #include "config.h" #include "AlsaInput.h" #include "FileInput.h" @@ -56,7 +83,7 @@ extern "C" { -// Enumerate which encoder we can use +//! Enumeration of encoders we can use enum class encoder_selection_t { fdk_dabplus, toolame_dab @@ -166,6 +193,10 @@ void usage(const char* name) { } +/*! Setup the FDK AAC encoder + * + * \return 0 on success + */ int prepare_aac_encoder( HANDLE_AACENCODER *encoder, int subchannel_index, @@ -262,6 +293,9 @@ int prepare_aac_encoder( chrono::steady_clock::time_point timepoint_last_compensation; +/*! Wait the proper amount of time to throttle down to nominal encoding + * rate, if drift compensation is enabled. + */ void drift_compensation_delay(int sample_rate, int channels, size_t bytes) { const size_t bytes_per_second = sample_rate * BYTES_PER_SAMPLE * channels; @@ -726,6 +760,9 @@ int main(int argc, char *argv[]) int max_size = 8*input_buf.size() + NUM_SAMPLES_PER_CALL; + /*! The SampleQueue \c queue is given to the inputs, so that they + * can fill it. + */ SampleQueue<uint8_t> queue(BYTES_PER_SAMPLE, channels, max_size); /* symsize=8, gfpoly=0x11d, fcr=0, prim=1, nroots=10, pad=135 */ @@ -867,6 +904,18 @@ int main(int argc, char *argv[]) memset(&outbuf[0], 0x00, outbuf_size); memset(&input_buf[0], 0x00, input_buf.size()); + /*! \section Data input + * We read data input either in a blocking way (file input, VLC or ALSA + * without drift compensation) or in a non-blocking way (VLC or ALSA + * with drift compensation, JACK). + * + * The file input doesn't need the queue at all. But the other inputs + * do, and either use \c pop() or \c pop_wait() depending on if it's blocking or not + * + * In non-blocking, the \c queue makes the data available without delay, and the + * \c drift_compensation_delay() function handles rate throttling. + */ + if (infile) { read_bytes = file_in.read(&input_buf[0], input_buf.size()); if (read_bytes < 0) { @@ -911,6 +960,10 @@ int main(int argc, char *argv[]) else { const int timeout_ms = 1000; read_bytes = input_buf.size(); + + /*! pop_wait() must return after a timeout, otherwise the silence detector cannot do + * its job. + */ size_t bytes_from_queue = queue.pop_wait(&input_buf[0], read_bytes, timeout_ms); // returns bytes if (bytes_from_queue < read_bytes) { @@ -960,6 +1013,12 @@ int main(int argc, char *argv[]) #endif } + /*! Audio level measurement is always done assuming we have two + * channels, and is formally wrong in mono, but still gives + * numbers one can use. + * + * \todo fix level measurement in mono + */ for (int i = 0; i < read_bytes; i+=4) { int16_t l = input_buf[i] | (input_buf[i+1] << 8); int16_t r = input_buf[i+2] | (input_buf[i+3] << 8); @@ -967,7 +1026,12 @@ int main(int argc, char *argv[]) peak_right = MAX(peak_right, r); } - /* Silence detection */ + /*! Silence detection, looks at the audio level and is + * only useful if the connection dropped, or if no data is available. It is not + * useful if the source is nearly silent (some noise present), because the + * threshold is 0, and not configurable. The rationale is that we want to + * guard against connection issues, not source level issues + */ if (die_on_silence && MAX(peak_left, peak_right) == 0) { const unsigned int frame_time_msec = 1000ul * read_bytes / (BYTES_PER_SAMPLE * channels * sample_rate); @@ -1050,6 +1114,9 @@ int main(int argc, char *argv[]) } } + /*! toolame expects the audio to be in another shape as + * we have in input_buf, and we need to convert first + */ short input_buffers[2][1152]; if (channels == 1) { @@ -1076,7 +1143,10 @@ int main(int argc, char *argv[]) } } - /* Check if the encoder has generated output data */ + /*! Check if the encoder has generated output data. + * DAB+ requires RS encoding, which is not done in ODR-DabMux and not necessary + * for DAB. + */ if (numOutBytes != 0 and selected_encoder == encoder_selection_t::fdk_dabplus) { @@ -1088,7 +1158,6 @@ int main(int argc, char *argv[]) } calls = 0; - // ----------- RS encoding int row, col; unsigned char buf_to_rs_enc[110]; unsigned char rs_enc[10]; diff --git a/src/encryption.h b/src/encryption.h index 936578b..bfe1fc3 100644 --- a/src/encryption.h +++ b/src/encryption.h @@ -15,6 +15,7 @@ * and limitations under the License. * ------------------------------------------------------------------- */ +/* \brief Helper functions for the ZMQ encryption */ #ifndef _ENCRYPTION_H_ #define _ENCRYPTION_H_ diff --git a/src/mot-encoder.cpp b/src/mot-encoder.cpp index 8d8d9ce..00757f6 100644 --- a/src/mot-encoder.cpp +++ b/src/mot-encoder.cpp @@ -17,14 +17,14 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +/*! + \file mot-encoder.c + \brief Generete PAD data for MOT Slideshow and DLS - mot-encoder.c - Generete PAD data for MOT Slideshow and DLS - - Authors: - Sergio Sagliocco <sergio.sagliocco@csp.it> - Matthias P. Braendli <matthias@mpb.li> - Stefan Pöschel <odr@basicmaster.de> + \author Sergio Sagliocco <sergio.sagliocco@csp.it> + \author Matthias P. Braendli <matthias@mpb.li> + \author Stefan Pöschel <odr@basicmaster.de> */ #include <cstdio> @@ -82,12 +82,12 @@ extern "C" { #define MINQUALITY 40 // Charsets from TS 101 756 -#define CHARSET_COMPLETE_EBU_LATIN 0 // Complete EBU Latin based repertoire -#define CHARSET_EBU_LATIN_CY_GR 1 // EBU Latin based common core, Cyrillic, Greek -#define CHARSET_EBU_LATIN_AR_HE_CY_GR 2 // EBU Latin based core, Arabic, Hebrew, Cyrillic and Greek -#define CHARSET_ISO_LATIN_ALPHABET_2 3 // ISO Latin Alphabet No 2 -#define CHARSET_UCS2_BE 6 // ISO/IEC 10646 using UCS-2 transformation format, big endian byte order -#define CHARSET_UTF8 15 // ISO Latin Alphabet No 2 +#define CHARSET_COMPLETE_EBU_LATIN 0 //!< Complete EBU Latin based repertoire +#define CHARSET_EBU_LATIN_CY_GR 1 //!< EBU Latin based common core, Cyrillic, Greek +#define CHARSET_EBU_LATIN_AR_HE_CY_GR 2 //!< EBU Latin based core, Arabic, Hebrew, Cyrillic and Greek +#define CHARSET_ISO_LATIN_ALPHABET_2 3 //!< ISO Latin Alphabet No 2 +#define CHARSET_UCS2_BE 6 //!< ISO/IEC 10646 using UCS-2 transformation format, big endian byte order +#define CHARSET_UTF8 15 //!< ISO Latin Alphabet No 2 typedef std::vector<uint8_t> uint8_vector_t; @@ -121,7 +121,7 @@ struct MSCDG { unsigned short int crc; // 16 bits }; -/* Between collection of slides and transmission, the slide data is saved +/*! Between collection of slides and transmission, the slide data is saved * in this structure. */ struct slide_metadata_t { @@ -138,7 +138,7 @@ struct slide_metadata_t { } }; -/* A simple fingerprint for each slide transmitted. +/*! A simple fingerprint for each slide transmitted. * Allows us to reuse the same fidx if the same slide * is transmitted more than once. */ @@ -153,8 +153,9 @@ struct fingerprint_t { // assigned fidx, -1 means invalid int fidx; - // The comparison is not done on fidx, only - // on the file-specific data + /*! The comparison is not done on fidx, only + * on the file-specific data + */ bool operator==(const fingerprint_t& other) const { return (((s_name == other.s_name && s_size == other.s_size) && @@ -183,6 +184,13 @@ struct fingerprint_t { } }; +/*! We keep track of transmitted files so that we can retransmit + * identical slides with the same index, in case the receivers cache + * them. + * + * \c MAXHISTORYLEN defines for how how many slides we want to keep this + * history. + */ class History { public: History(size_t hist_size) : @@ -594,7 +602,7 @@ void PADPacketizer::AddCI(int apptype, int len_index) { int PADPacketizer::OptimalSubFieldSizeIndex(size_t available_bytes) { - /* Return the index of the optimal sub-field size by stepwise search (regards only Variable Size X-PAD): + /*! Return the index of the optimal sub-field size by stepwise search (regards only Variable Size X-PAD): * - find the smallest sub-field able to hold (at least) all available bytes * - find the biggest regarding sub-field we have space for (which definitely exists - otherwise previously the PAD would have been flushed) * - if the wasted space is at least as big as the smallest possible sub-field, use a sub-field one size smaller @@ -620,7 +628,7 @@ int PADPacketizer::WriteDGToSubField(DATA_GROUP* dg, size_t len) { bool PADPacketizer::AppendDG(DATA_GROUP* dg) { - /* use X-PAD w/o CIs instead of X-PAD w/ CIs, if we can save some bytes or at least do not waste additional bytes + /*! use X-PAD w/o CIs instead of X-PAD w/ CIs, if we can save some bytes or at least do not waste additional bytes * * Omit CI list in case: * 1. no pending data sub-fields @@ -1051,12 +1059,13 @@ void warnOnSmallerImage(size_t height, size_t width, std::string& fname) { } -// Scales the image down if needed, -// so that it is 320x240 pixels. -// Automatically reduces the quality to make sure the -// blobsize is not too large. -// -// Returns: the blobsize +/*! Scales the image down if needed, + * so that it is 320x240 pixels. + * Automatically reduces the quality to make sure the + * blobsize is not too large. + * + * \return the blobsize + */ #if HAVE_MAGICKWAND size_t resizeImage(MagickWand* m_wand, unsigned char** blob, std::string& fname) { @@ -1127,17 +1136,17 @@ int encodeFile(int output_fd, std::string& fname, int fidx, bool raw_slides) size_t orig_quality; char* orig_format = NULL; - /* We handle JPEG differently, because we want to avoid recompressing the + /*! We handle JPEG differently, because we want to avoid recompressing the * image if it is suitable as is */ bool orig_is_jpeg = false; - /* If the original is a PNG, we transmit it as is, if the resolution is correct + /*! If the original is a PNG, we transmit it as is, if the resolution is correct * and the file is not too large. Otherwise it gets resized and sent as JPEG. */ bool orig_is_png = false; - /* By default, we do resize the image to 320x240, with a quality such that + /*! By default, we do resize the image to 320x240, with a quality such that * the blobsize is at most MAXSLIDESIZE. * * For JPEG input files that are already at the right resolution and at the diff --git a/src/utils.h b/src/utils.h index e411963..83b3e4d 100644 --- a/src/utils.h +++ b/src/utils.h @@ -12,12 +12,13 @@ #define linear_to_dB(x) (log10(x) * 20) -/* Calculate the little string containing a bargraph +/*! Calculate the little string containing a bargraph * 'VU-meter' from the peak value measured */ const char* level(int channel, int peak); -/* This defines the on-wire representation of a ZMQ message header. +/*! This defines the on-wire representation of a ZMQ message header. + * It must be compatible with the definition in ODR-DabMux. * * The data follows right after this header */ struct zmq_frame_header_t |