diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2014-06-26 20:16:37 +0200 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2014-06-26 20:16:37 +0200 |
commit | 45613a2ac14272c3e4779dd9aa971b5160bb060e (patch) | |
tree | ffec3e9f2e213415a3755849f0feaa53ea5101ad /src/JackInput.cpp | |
parent | c0ec1e01c7dd84ce694bc5268916cc43870f00cf (diff) | |
download | ODR-AudioEnc-45613a2ac14272c3e4779dd9aa971b5160bb060e.tar.gz ODR-AudioEnc-45613a2ac14272c3e4779dd9aa971b5160bb060e.tar.bz2 ODR-AudioEnc-45613a2ac14272c3e4779dd9aa971b5160bb060e.zip |
Add JACK input support
Diffstat (limited to 'src/JackInput.cpp')
-rw-r--r-- | src/JackInput.cpp | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/src/JackInput.cpp b/src/JackInput.cpp new file mode 100644 index 0000000..f39bf14 --- /dev/null +++ b/src/JackInput.cpp @@ -0,0 +1,139 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 2011 Martin Storsjo + * Copyright (C) 2013,2014 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. + * ------------------------------------------------------------------- + */ + +#include <cstdio> +#include <string> +#include "config.h" + +#if HAVE_JACK + +extern "C" { +#include <jack/jack.h> +} + +#include "JackInput.h" +#include <sys/time.h> + +using namespace std; + +int JackInput::prepare() +{ + jack_options_t options = JackNullOption; + jack_status_t status; + const char *server_name = NULL; + + m_client = jack_client_open(m_jack_name.c_str(), options, &status, server_name); + if (m_client == NULL) { + fprintf(stderr, "jack_client_open() failed, " + "status = 0x%2.0x\n", status); + if (status & JackServerFailed) { + fprintf(stderr, "Unable to connect to JACK server\n"); + } + return -1; + } + + if (status & JackServerStarted) { + fprintf(stderr, "JACK server started\n"); + } + + if (status & JackNameNotUnique) { + fprintf(stderr, "JACK name '%s' not unique!\n", m_jack_name.c_str()); + return -1; + } + + /* Set up real-time process callback */ + jack_set_process_callback(m_client, process_cb, this); + + /* tell the JACK server to call `shutdown_cb' if + it ever shuts down, either entirely, or if it + just decides to stop calling us. */ + jack_on_shutdown(m_client, shutdown_cb, this); + + if (m_rate != jack_get_sample_rate(m_client)) { + fprintf(stderr, "JACK uses different sample_rate %d " + "than requested (%d)!\n", + jack_get_sample_rate(m_client), + m_rate); + return -1; + } + + /* create ports */ + for (int i = 0; i < m_channels; i++) { + std::stringstream port_name; + port_name << "input" << i; + + jack_port_t* input_port = jack_port_register(m_client, + port_name.str().c_str(), + JACK_DEFAULT_AUDIO_TYPE, + JackPortIsInput, + 0); + + if (input_port == NULL) { + fprintf(stderr, "no more JACK ports available\n"); + return -1; + } + + m_input_ports.push_back(input_port); + } + + /* Tell the JACK server that we are ready to roll. Our + * process() callback will start running now. */ + if (jack_activate(m_client)) { + fprintf (stderr, "JACK: cannot activate client"); + return -1; + } +} + +void JackInput::jack_process(jack_nframes_t nframes) +{ + // Convert samples to shorts + std::vector<int16_t> buffer(m_channels * nframes); + + for (int chan = 0; chan < m_channels; chan++) { + // start offset interleaving + int i = chan; + + const int dst_skip = m_channels; + + jack_default_audio_sample_t* src = + (jack_default_audio_sample_t*)jack_port_get_buffer(m_input_ports[chan], nframes); + + jack_nframes_t n = nframes; + while (n--) { + if (*src <= -1.0f) { + buffer[i] = 32767; + } + else if (*src >= 1.0f) { + buffer[i] = -32768; + } + else { + buffer[i] = + (int16_t)lrintf(*src * 32768.0f); + } + + i += dst_skip; + src++; + } + } + + m_queue.push((uint8_t*)&buffer.front(), buffer.size() * sizeof(uint16_t)); +} + +#endif // HAVE_JACK + |