diff options
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | alsa-dabplus-zmq.c | 19 | ||||
-rw-r--r-- | src/AlsaDabplus.cpp | 100 | ||||
-rw-r--r-- | src/AlsaInput.cpp | 2 | ||||
-rw-r--r-- | src/SampleQueue.h | 8 |
5 files changed, 81 insertions, 49 deletions
diff --git a/Makefile.am b/Makefile.am index 5e2e8b2..3adedd0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -50,6 +50,7 @@ mot_encoder_SOURCES = mot-encoder.c contrib/lib_crc.c alsa_dabplus_zmq_LDADD = libfdk-aac.la -lfec -lzmq -lasound alsa_dabplus_zmq_SOURCES = alsa-dabplus-zmq.c +dabplus_zmq_LDFLAGS = -no-install dabplus_zmq_LDADD = libfdk-aac.la -lfec -lzmq -lasound \ -lrt -lboost_thread diff --git a/alsa-dabplus-zmq.c b/alsa-dabplus-zmq.c index b1b301d..efe66c1 100644 --- a/alsa-dabplus-zmq.c +++ b/alsa-dabplus-zmq.c @@ -399,30 +399,33 @@ int main(int argc, char *argv[]) { int in_size, in_elem_size; int out_identifier = OUT_BITSTREAM_DATA; int out_size, out_elem_size; - int read=0, i; + int i; int send_error; void *in_ptr, *out_ptr; AACENC_ERROR err; - read = alsa_read(input_buf, info.frameLength); - if (read != info.frameLength) { + int readframes = alsa_read(input_buf, info.frameLength); + if (readframes != info.frameLength) { fprintf(stderr, "Unable to read enough data from input!\n"); break; } - for (i = 0; i < read/2; i++) { + readframes*=2; +#if 1 + for (i = 0; i < readframes; i++) { const uint8_t* in = &input_buf[2*i]; convert_buf[i] = in[0] | (in[1] << 8); } +#endif - if (read <= 0) { + if (readframes <= 0) { in_args.numInSamples = -1; } else { - in_ptr = convert_buf; - in_size = read; + in_ptr = input_buf; + in_size = readframes*2; in_elem_size = 2; - in_args.numInSamples = read/2; + in_args.numInSamples = readframes; in_buf.numBufs = 1; in_buf.bufs = &in_ptr; in_buf.bufferIdentifiers = &in_identifier; diff --git a/src/AlsaDabplus.cpp b/src/AlsaDabplus.cpp index ea81bda..50dcddc 100644 --- a/src/AlsaDabplus.cpp +++ b/src/AlsaDabplus.cpp @@ -160,7 +160,6 @@ int prepare_aac_encoder( int main(int argc, char *argv[]) { int subchannel_index = 8; //64kbps subchannel int ch=0; - int err; const char *alsa_device = "default"; const char *outuri = NULL; int sample_rate=48000, channels=2; @@ -238,16 +237,25 @@ int main(int argc, char *argv[]) { return 1; } - fprintf(stderr, "DAB+ Encoding: framelen=%d\n", info.frameLength); - // Each DAB+ frame will need input_size audio bytes - int input_size = channels * bytes_per_sample * info.frameLength; + const int input_size = channels * bytes_per_sample * info.frameLength; + fprintf(stderr, "DAB+ Encoding: framelen=%d (%dB)\n", + info.frameLength, + input_size); + uint8_t input_buf[input_size]; int max_size = input_size + NUM_SAMPLES_PER_CALL; SampleQueue<uint8_t> queue(BYTES_PER_SAMPLE, channels, max_size); + /* symsize=8, gfpoly=0x11d, fcr=0, prim=1, nroots=10, pad=135 */ + rs_handler = init_rs_char(8, 0x11d, 0, 1, 10, 135); + if (rs_handler == NULL) { + perror("init_rs_char failed"); + return 1; + } + AlsaInput alsa_in(alsa_device, channels, sample_rate, queue); if (alsa_in.prepare() != 0) { @@ -277,6 +285,7 @@ int main(int argc, char *argv[]) { struct timespec tp; clock_gettime(CLOCK_MONOTONIC, &tp); + int calls; while (1) { int in_identifier = IN_AUDIO_DATA; int out_identifier = OUT_BITSTREAM_DATA; @@ -299,7 +308,7 @@ int main(int argc, char *argv[]) { // -------------- AAC Encoding in_ptr = input_buf; - in_size = input_size; + in_size = read; in_elem_size = BYTES_PER_SAMPLE; in_args.numInSamples = input_size; in_buf.numBufs = 1; @@ -317,6 +326,7 @@ int main(int argc, char *argv[]) { out_buf.bufSizes = &out_size; out_buf.bufElSizes = &out_elem_size; + AACENC_ERROR err; if ((err = aacEncEncode(encoder, &in_buf, &out_buf, &in_args, &out_args)) != AACENC_OK) { if (err == AACENC_ENCODE_EOF) @@ -324,59 +334,69 @@ int main(int argc, char *argv[]) { 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); + calls++; - for(col=110; col<120; col++) { - outbuf[subchannel_index * col + row] = rs_enc[col-110]; - assert(subchannel_index * col + row < outbuf_size); + /* Check if the encoder has generated output data */ + if (out_args.numOutBytes != 0) + { + fprintf(stderr, "data out after %d calls\n", calls); + calls = 0; + // ----------- 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 ++; - } + // ------------ 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 (send_error_count > 10) + { + fprintf(stderr, "ZeroMQ send failed ten times, aborting!\n"); + break; + } - if (out_args.numOutBytes + row*10 == outbuf_size) - fprintf(stderr, "."); + if (out_args.numOutBytes + row*10 == outbuf_size) + fprintf(stderr, "."); + } - // -------------- wait 120ms (one DAB+ superframe) - tp.tv_nsec += 120000000; + // -------------- wait the right amount of time + tp.tv_nsec += 60000000; if (tp.tv_nsec > 1000000000L) { tp.tv_nsec -= 1000000000L; tp.tv_sec += 1; } + fprintf(stderr, "sleep %ld.%ld\n", tp.tv_sec, tp.tv_nsec); struct timespec tp_now; do { - usleep(10000); - clock_gettime(CLOCK_MONOTONIC, &tp); + usleep(1000); + clock_gettime(CLOCK_MONOTONIC, &tp_now); } while (tp_now.tv_sec < tp.tv_sec || ( tp_now.tv_sec == tp.tv_sec && tp_now.tv_nsec < tp.tv_nsec) ); + tp.tv_sec = tp_now.tv_sec; + tp.tv_nsec = tp_now.tv_nsec; + } zmq_sock.close(); diff --git a/src/AlsaInput.cpp b/src/AlsaInput.cpp index fd1feec..8b6f790 100644 --- a/src/AlsaInput.cpp +++ b/src/AlsaInput.cpp @@ -133,7 +133,7 @@ void AlsaInput::process() while (m_running) { size_t n = read(samplebuf, NUM_SAMPLES_PER_CALL); - m_queue.push(samplebuf, n); + m_queue.push(samplebuf, BYTES_PER_SAMPLE*m_channels*n); } } diff --git a/src/SampleQueue.h b/src/SampleQueue.h index d00b8f9..eabc301 100644 --- a/src/SampleQueue.h +++ b/src/SampleQueue.h @@ -12,6 +12,8 @@ #include <boost/thread.hpp> #include <queue> +#include <stdio.h> + /* 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. @@ -37,6 +39,9 @@ public: boost::mutex::scoped_lock lock(m_mutex); if (m_queue.size() >= m_max_size) { + /*fprintf(stderr, "######## push overrun %zu, %zu\n", + len, + m_queue.size()); // */ return 0; } @@ -65,6 +70,9 @@ public: size_t pop(T* buf, size_t len) { boost::mutex::scoped_lock lock(m_mutex); + fprintf(stderr, "######## pop %zu (%zu)\n", + len, + m_queue.size()); size_t ret = 0; |