diff options
-rw-r--r-- | Makefile.am | 4 | ||||
-rw-r--r-- | configure.ac | 6 | ||||
-rw-r--r-- | src/AlsaDabplus.cpp | 126 | ||||
-rw-r--r-- | src/AlsaInput.cpp | 8 | ||||
-rw-r--r-- | src/AlsaInput.h | 3 | ||||
-rw-r--r-- | src/SampleQueue.h | 6 |
6 files changed, 141 insertions, 12 deletions
diff --git a/Makefile.am b/Makefile.am index 8914d87..1691a47 100644 --- a/Makefile.am +++ b/Makefile.am @@ -48,7 +48,9 @@ aac_enc_dabplus_zmq_SOURCES = aac-enc-dabplus-zmq.c wavreader.c alsa_dabplus_zmq_LDADD = libfdk-aac.la -lfec -lzmq -lasound alsa_dabplus_zmq_SOURCES = alsa-dabplus-zmq.c -dabplus_zmq_LDADD = libfdk-aac.la -lfec -lzmq -lasound +dabplus_zmq_LDADD = libfdk-aac.la -lfec -lzmq -lasound \ + -lrt -lboost_thread + dabplus_zmq_SOURCES = src/AlsaDabplus.cpp \ src/AlsaInput.cpp \ src/AlsaInput.h \ diff --git a/configure.ac b/configure.ac index 04252ce..39704d6 100644 --- a/configure.ac +++ b/configure.ac @@ -24,6 +24,12 @@ LT_INIT AC_CHECK_LIB([m], [sin]) +AX_BOOST_BASE([1.41.0], [], AC_MSG_ERROR([BOOST 1.41 or later is required])) +AC_CHECK_LIB([boost_system], [main], [], [AC_MSG_ERROR([library boost_system is missing])]) +AC_CHECK_LIB([boost_thread], [main], [], [AC_MSG_ERROR([library boost_thread is missing])]) + +AC_CHECK_LIB([rt], [clock_gettime], [], [AC_MSG_ERROR([library rt is missing])]) + # fdk-aac-dabplus-zmq needs ZeroMQ AC_ARG_ENABLE([zmq], [AS_HELP_STRING([--enable-zmq], [Enable fdk-aac-dabplus-zmq with ZeroMQ output])] diff --git a/src/AlsaDabplus.cpp b/src/AlsaDabplus.cpp index e94f00a..758d96e 100644 --- a/src/AlsaDabplus.cpp +++ b/src/AlsaDabplus.cpp @@ -25,9 +25,15 @@ #include <getopt.h> #include <cstdio> #include <stdint.h> +#include <time.h> +#include <unistd.h> #include "libAACenc/include/aacenc_lib.h" +extern "C" { +#include <fec.h> +} + using namespace std; void usage(const char* name) { @@ -160,7 +166,6 @@ int main(int argc, char *argv[]) { const int bytes_per_sample = 2; void *rs_handler = NULL; int afterburner = 0; - HANDLE_AACENCODER handle; AACENC_InfoStruct info = { 0 }; const struct option longopts[] = { @@ -227,7 +232,7 @@ int main(int argc, char *argv[]) { return 2; } - if (aacEncInfo(handle, &info) != AACENC_OK) { + if (aacEncInfo(encoder, &info) != AACENC_OK) { fprintf(stderr, "Unable to get the encoder info\n"); return 1; } @@ -249,4 +254,121 @@ int main(int argc, char *argv[]) { return 1; } + fprintf(stderr, "Start ALSA capture thread\n"); + alsa_in.start(); + + fprintf(stderr, "Starting queue preroll\n"); + // Preroll until queue full + while (queue.size() < input_size) { + usleep(1000); + } + + int outbuf_size = subchannel_index*120; + uint8_t outbuf[20480]; + + if(outbuf_size % 5 != 0) { + fprintf(stderr, "(outbuf_size mod 5) = %d\n", outbuf_size % 5); + } + + fprintf(stderr, "Starting encoding\n"); + + int send_error_count = 0; + struct timespec tp; + clock_gettime(CLOCK_MONOTONIC, &tp); + + while (1) { + int in_identifier = IN_AUDIO_DATA; + int out_identifier = OUT_BITSTREAM_DATA; + + AACENC_BufDesc in_buf = { 0 }, out_buf = { 0 }; + AACENC_InArgs in_args = { 0 }; + AACENC_OutArgs out_args = { 0 }; + void *in_ptr, *out_ptr; + int in_size, in_elem_size; + int out_size, out_elem_size; + + memset(outbuf, 0x00, outbuf_size); + + int read = queue.pop(input_buf, input_size); + + if (read != input_size) { + fprintf(stderr, "Short read\n"); + } + + // -------------- AAC Encoding + + in_ptr = input_buf; + in_size = input_size; + in_elem_size = BYTES_PER_SAMPLE; + in_args.numInSamples = input_size; + in_buf.numBufs = 1; + in_buf.bufs = &in_ptr; + in_buf.bufferIdentifiers = &in_identifier; + in_buf.bufSizes = &in_size; + in_buf.bufElSizes = &in_elem_size; + + out_ptr = outbuf; + out_size = sizeof(outbuf); + out_elem_size = 1; + out_buf.numBufs = 1; + out_buf.bufs = &out_ptr; + out_buf.bufferIdentifiers = &out_identifier; + out_buf.bufSizes = &out_size; + out_buf.bufElSizes = &out_elem_size; + + if ((err = aacEncEncode(encoder, &in_buf, &out_buf, &in_args, &out_args)) + != AACENC_OK) { + if (err == AACENC_ENCODE_EOF) + break; + fprintf(stderr, "Encoding failed\n"); + break; + } + if (out_args.numOutBytes == 0) + continue; + + // ----------- RS encoding + int row, col; + unsigned char buf_to_rs_enc[110]; + unsigned char rs_enc[10]; + for(row=0; row < subchannel_index; row++) { + for(col=0;col < 110; col++) { + buf_to_rs_enc[col] = outbuf[subchannel_index * col + row]; + } + + encode_rs_char(rs_handler, buf_to_rs_enc, rs_enc); + + for(col=110; col<120; col++) { + outbuf[subchannel_index * col + row] = rs_enc[col-110]; + assert(subchannel_index * col + row < outbuf_size); + } + } + + // ------------ ZeroMQ transmit + try { + zmq_sock.send(outbuf, outbuf_size, ZMQ_DONTWAIT); + } + catch (zmq::error_t& e) { + fprintf(stderr, "ZeroMQ send error !\n"); + send_error_count ++; + } + + if (send_error_count > 10) + { + fprintf(stderr, "ZeroMQ send failed ten times, aborting!\n"); + break; + } + + if (out_args.numOutBytes + row*10 == outbuf_size) + fprintf(stderr, "."); + + // -------------- wait 120ms (one DAB+ superframe) + + } + + zmq_sock.close(); + free_rs_char(rs_handler); + + aacEncClose(&encoder); + +} diff --git a/src/AlsaInput.cpp b/src/AlsaInput.cpp index 4c141a1..fd1feec 100644 --- a/src/AlsaInput.cpp +++ b/src/AlsaInput.cpp @@ -18,12 +18,12 @@ */ #include <cstdio> -#include <cstdint> #include <string> #include <alsa/asoundlib.h> #include "AlsaInput.h" +#include <sys/time.h> using namespace std; @@ -36,10 +36,10 @@ int AlsaInput::prepare() const int open_mode = 0; //|= SND_PCM_NONBLOCK; - if ((err = snd_pcm_open(&m_alsa_handle, alsa_dev, + if ((err = snd_pcm_open(&m_alsa_handle, m_alsa_dev.c_str(), SND_PCM_STREAM_CAPTURE, open_mode)) < 0) { fprintf (stderr, "cannot open audio device %s (%s)\n", - alsa_dev, snd_strerror(err)); + m_alsa_dev.c_str(), snd_strerror(err)); return 1; } @@ -121,7 +121,7 @@ size_t AlsaInput::read(uint8_t* buf, snd_pcm_uframes_t length) return err; } -int AlsaInput::start() +void AlsaInput::start() { m_running = true; m_thread = boost::thread(&AlsaInput::process, this); diff --git a/src/AlsaInput.h b/src/AlsaInput.h index b43ad7d..c1e3e9b 100644 --- a/src/AlsaInput.h +++ b/src/AlsaInput.h @@ -20,7 +20,6 @@ #ifndef __ALSA_H_ #define __ALSA_H_ #include <cstdio> -#include <stdint.h> #include <string> #include <alsa/asoundlib.h> @@ -66,7 +65,7 @@ class AlsaInput int prepare(); - int start(); + void start(); private: AlsaInput(const AlsaInput& other) : m_queue(other.m_queue) {} diff --git a/src/SampleQueue.h b/src/SampleQueue.h index fddc3a4..d00b8f9 100644 --- a/src/SampleQueue.h +++ b/src/SampleQueue.h @@ -52,10 +52,10 @@ public: return new_size; } - bool empty() const + size_t size() const { boost::mutex::scoped_lock lock(m_mutex); - return m_queue.empty(); + return m_queue.size(); } /* Get len elements, place them into the buf array @@ -89,7 +89,7 @@ public: ret = len; - m_queue.erase(m_queue.front(), m_queue.front() + len); + m_queue.erase(m_queue.begin(), m_queue.begin() + len); } return ret; |