89 if (
auto buf = read())
94JackLayer::writeSpace()
96 if (out_ringbuffers_.empty())
98 size_t toWrite {std::numeric_limits<size_t>::max()};
99 for (
unsigned i = 0;
i < out_ringbuffers_.size(); ++
i) {
110 auto channels = std::min<size_t>(out_ringbuffers_.size(),
buffer.pointer()->ch_layout.nb_channels);
111 for (
size_t i = 0;
i < channels; ++
i) {
116std::unique_ptr<AudioFrame>
119 if (in_ringbuffers_.empty())
122 size_t toRead {std::numeric_limits<size_t>::max()};
123 for (
unsigned i = 0;
i < in_ringbuffers_.size(); ++
i) {
133 for (
unsigned i = 0;
i < in_ringbuffers_.size(); ++
i) {
143JackLayer::ringbuffer_worker()
149 std::unique_lock lock(ringbuffer_thread_mutex_);
156 std::this_thread::sleep_for(std::chrono::milliseconds(20));
165 data_ready_.wait(lock,
172 std::vector<jack_port_t*>&
ports,
195 throw std::runtime_error(
"Unable to register JACK output port");
198 static const unsigned RB_SIZE = 16384;
201 throw std::runtime_error(
"Unable to create JACK ringbuffer");
203 throw std::runtime_error(
"Unable to lock JACK ringbuffer in memory");
215 if (!playbackClient_)
216 throw std::runtime_error(
"Unable to open JACK client");
220 throw std::runtime_error(
"Unable to open JACK client");
225 createPorts(playbackClient_, out_ports_,
true, out_ringbuffers_);
226 createPorts(captureClient_, in_ports_,
false, in_ringbuffers_);
241 for (
auto p : out_ports_)
243 for (
auto p : in_ports_)
247 JAMI_ERR(
"Unable to close JACK client");
249 JAMI_ERR(
"Unable to close JACK client");
251 for (
auto r : out_ringbuffers_)
253 for (
auto r : in_ringbuffers_)
261std::vector<std::string>
262JackLayer::getCaptureDeviceList()
const
264 return std::vector<std::string>();
267std::vector<std::string>
268JackLayer::getPlaybackDeviceList()
const
270 return std::vector<std::string>();
274JackLayer::getAudioDeviceIndex(
const std::string& ,
AudioDeviceType )
const
286JackLayer::getIndexCapture()
const
292JackLayer::getIndexPlayback()
const
298JackLayer::getIndexRingtone()
const
308 for (
unsigned i = 0;
i < context->in_ringbuffers_.size(); ++
i) {
328 if (context->ringbuffer_thread_mutex_.try_lock()) {
329 context->data_ready_.notify_one();
330 context->ringbuffer_thread_mutex_.unlock();
341 for (
unsigned i = 0;
i < context->out_ringbuffers_.size(); ++
i) {
365 std::lock_guard lock(
mutex_);
371 JAMI_ERR(
"Unable to activate JACK client");
374 ringbuffer_thread_ = std::thread(&JackLayer::ringbuffer_worker,
this);
380JackLayer::onShutdown(
void* )
392 std::lock_guard lock(
mutex_);
396 data_ready_.notify_one();
399 JAMI_ERR(
"Unable to deactivate JACK client");
402 if (ringbuffer_thread_.joinable())
403 ringbuffer_thread_.join();
std::shared_ptr< RingBuffer > mainRingBuffer_
Buffers for audio processing.
std::mutex mutex_
Lock for the entire audio layer.
std::atomic< Status > status_
Whether or not the audio layer's playback stream is started.
std::shared_ptr< AudioFrame > getPlayback(AudioFormat format, size_t samples)
void notifyIncomingCall()
Emit an audio notification (beep) on incoming calls.
void hardwareFormatAvailable(AudioFormat playback, size_t bufSize=0)
Callback to be called by derived classes when the audio output is opened.
void flushUrgent()
Flush urgent buffer.
void hardwareInputFormatAvailable(AudioFormat capture)
Set the input format on necessary objects.
AudioFormat audioFormat_
Sample Rate that should be sent to the sound card.
void flushMain()
Flush main buffer.
AudioFormat audioInputFormat_
Sample Rate for input.
JackLayer(const AudioPreference &)
void createPorts(jack_client_t *client, std::vector< jack_port_t * > &ports, bool playback, std::vector< jack_ringbuffer_t * > &ringbuffers)
void emitSignal(Args... args)
libjami::AudioFrame AudioFrame