From 7284422f3a907724af91de827b2d32220d0d4ba1 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 7 Mar 2014 10:46:36 +0100 Subject: alsa-dabplus compiles --- src/AlsaDabplus.cpp | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++- src/AlsaInput.cpp | 8 ++-- src/AlsaInput.h | 3 +- src/SampleQueue.h | 6 +-- 4 files changed, 132 insertions(+), 11 deletions(-) (limited to 'src') 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 #include #include +#include +#include #include "libAACenc/include/aacenc_lib.h" +extern "C" { +#include +} + 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 -#include #include #include #include "AlsaInput.h" +#include 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 -#include #include #include @@ -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; -- cgit v1.2.3