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) {
113 (
const char*)
buffer.pointer()->extended_data[
i],
118std::unique_ptr<AudioFrame>
121 if (in_ringbuffers_.empty())
124 size_t toRead {std::numeric_limits<size_t>::max()};
125 for (
unsigned i = 0;
i < in_ringbuffers_.size(); ++
i) {
135 for (
unsigned i = 0;
i < in_ringbuffers_.size(); ++
i) {
137 (
char*)
buffer->pointer()->extended_data[
i],
147JackLayer::ringbuffer_worker()
153 std::unique_lock lock(ringbuffer_thread_mutex_);
160 std::this_thread::sleep_for(std::chrono::milliseconds(20));
169 data_ready_.wait(lock, [&] {
177 std::vector<jack_port_t*>&
ports,
201 throw std::runtime_error(
"Unable to register JACK output port");
204 static const unsigned RB_SIZE = 16384;
207 throw std::runtime_error(
"Unable to create JACK ringbuffer");
209 throw std::runtime_error(
"Unable to lock JACK ringbuffer in memory");
223 if (!playbackClient_)
224 throw std::runtime_error(
"Unable to open JACK client");
230 throw std::runtime_error(
"Unable to open JACK client");
235 createPorts(playbackClient_, out_ports_,
true, out_ringbuffers_);
236 createPorts(captureClient_, in_ports_,
false, in_ringbuffers_);
251 for (
auto p : out_ports_)
253 for (
auto p : in_ports_)
257 JAMI_ERR(
"Unable to close JACK client");
259 JAMI_ERR(
"Unable to close JACK client");
261 for (
auto r : out_ringbuffers_)
263 for (
auto r : in_ringbuffers_)
271std::vector<std::string>
272JackLayer::getCaptureDeviceList()
const
274 return std::vector<std::string>();
277std::vector<std::string>
278JackLayer::getPlaybackDeviceList()
const
280 return std::vector<std::string>();
284JackLayer::getAudioDeviceIndex(
const std::string& ,
AudioDeviceType )
const
296JackLayer::getIndexCapture()
const
302JackLayer::getIndexPlayback()
const
308JackLayer::getIndexRingtone()
const
318 for (
unsigned i = 0;
i < context->in_ringbuffers_.size(); ++
i) {
340 if (context->ringbuffer_thread_mutex_.try_lock()) {
341 context->data_ready_.notify_one();
342 context->ringbuffer_thread_mutex_.unlock();
353 for (
unsigned i = 0;
i < context->out_ringbuffers_.size(); ++
i) {
378 std::lock_guard lock(
mutex_);
384 JAMI_ERR(
"Unable to activate JACK client");
387 ringbuffer_thread_ = std::thread(&JackLayer::ringbuffer_worker,
this);
393JackLayer::onShutdown(
void* )
404 std::lock_guard lock(
mutex_);
408 data_ready_.notify_one();
411 JAMI_ERR(
"Unable to deactivate JACK client");
414 if (ringbuffer_thread_.joinable())
415 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