Ring Daemon 16.0.0
Loading...
Searching...
No Matches
audiolayer.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2004-2025 Savoir-faire Linux Inc.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17#pragma once
18
19#include "ringbuffer.h"
20#include "noncopyable.h"
21#include "audio_frame_resizer.h"
23
24#include <chrono>
25#include <mutex>
26#include <vector>
27#include <atomic>
28#include <condition_variable>
29#include <array>
30
31extern "C" {
32struct SpeexEchoState_;
33typedef struct SpeexEchoState_ SpeexEchoState;
34}
35
41// Define the audio api
42#define OPENSL_API_STR "opensl"
43#define PULSEAUDIO_API_STR "pulseaudio"
44#define ALSA_API_STR "alsa"
45#define JACK_API_STR "jack"
46#define COREAUDIO_API_STR "coreaudio"
47#define PORTAUDIO_API_STR "portaudio"
48
49#define PCM_DEFAULT "default" // Default ALSA plugin
50#define PCM_DSNOOP "plug:dsnoop" // Alsa plugin for microphone sharing
51#define PCM_DMIX_DSNOOP "dmix/dsnoop" // Audio profile using Alsa dmix/dsnoop
52
53namespace jami {
54
55class AudioPreference;
56class Resampler;
57
58enum class AudioDeviceType { ALL = -1, PLAYBACK = 0, CAPTURE, RINGTONE };
59
61{
62private:
64
65protected:
66 enum class Status { Idle, Starting, Started };
67
68public:
70 virtual ~AudioLayer();
71
77
83
84 virtual std::vector<std::string> getCaptureDeviceList() const = 0;
85 virtual std::vector<std::string> getPlaybackDeviceList() const = 0;
86
87 virtual int getAudioDeviceIndex(const std::string& name, AudioDeviceType type) const = 0;
88 virtual std::string getAudioDeviceName(int index, AudioDeviceType type) const = 0;
89 virtual int getIndexCapture() const = 0;
90 virtual int getIndexPlayback() const = 0;
91 virtual int getIndexRingtone() const = 0;
92
96 inline bool isStarted() const { return status_ == Status::Started; }
97
98 template<class Rep, class Period>
99 bool waitForStart(const std::chrono::duration<Rep, Period>& rel_time) const
100 {
101 std::unique_lock lk(mutex_);
102 startedCv_.wait_for(lk, rel_time, [this] { return isStarted(); });
103 return isStarted();
104 }
105
111 void putUrgent(std::shared_ptr<AudioFrame> buffer);
112
117 void playIncomingCallNotification(bool play) { playIncomingCallBeep_.exchange(play); }
118
122 void flushMain();
123
127 void flushUrgent();
128
129 bool isCaptureMuted() const { return isCaptureMuted_; }
130
135
136 bool isPlaybackMuted() const { return isPlaybackMuted_; }
137
142
143 bool isRingtoneMuted() const { return isRingtoneMuted_; }
145
151
155 double getCaptureGain() const { return captureGain_; }
156
162
166 double getPlaybackGain() const { return playbackGain_; }
167
173 unsigned int getSampleRate() const { return audioFormat_.sample_rate; }
174
179
183 void notifyIncomingCall();
184
185 virtual void updatePreference(AudioPreference& pref, int index, AudioDeviceType type) = 0;
186
187protected:
191 void hardwareFormatAvailable(AudioFormat playback, size_t bufSize = 0);
192
197
198 void devicesChanged();
199
200 void playbackChanged(bool started);
201 void recordChanged(bool started);
202 void setHasNativeAEC(bool hasEAC);
203 void setHasNativeNS(bool hasNS);
204
205 std::shared_ptr<AudioFrame> getToPlay(AudioFormat format, size_t writableSamples);
206 std::shared_ptr<AudioFrame> getToRing(AudioFormat format, size_t writableSamples);
207 std::shared_ptr<AudioFrame> getPlayback(AudioFormat format, size_t samples)
208 {
209 const auto& ringBuff = getToRing(format, samples);
210 const auto& playBuff = getToPlay(format, samples);
211 return ringBuff ? ringBuff : playBuff;
212 }
213
214 void putRecorded(std::shared_ptr<AudioFrame>&& frame);
215
216 void flush();
217
222
227
231 bool isRingtoneMuted_ {false};
232
233 bool playbackStarted_ {false};
234 bool recordStarted_ {false};
235 bool hasNativeAEC_ {true};
236 bool hasNativeNS_ {false};
237
242
247
248 // audio processor preferences
250
254 std::shared_ptr<RingBuffer> mainRingBuffer_;
255 std::unique_ptr<AudioFrameResizer> playbackQueue_;
256
260 std::atomic<Status> status_ {Status::Idle};
261 mutable std::condition_variable startedCv_;
262
267
272
274
279
283 mutable std::mutex mutex_ {};
284
288 std::unique_ptr<Resampler> resampler_;
289
290private:
291 std::mutex audioProcessorMutex {};
292 std::unique_ptr<AudioProcessor> audioProcessor;
293
294 void createAudioProcessor();
295 void destroyAudioProcessor();
296
297 // Set to "true" to play the incoming call notification (beep)
298 // when the playback is on (typically when there is already an
299 // active call).
300 std::atomic_bool playIncomingCallBeep_ {false};
304 std::chrono::system_clock::time_point lastNotificationTime_ {
305 std::chrono::system_clock::time_point::min()};
306};
307
308} // namespace jami
bool isCaptureMuted_
True if capture is not to be used.
Definition audiolayer.h:221
void mutePlayback(bool muted)
Mute playback.
Definition audiolayer.h:141
std::shared_ptr< RingBuffer > mainRingBuffer_
Buffers for audio processing.
Definition audiolayer.h:254
std::mutex mutex_
Lock for the entire audio layer.
Definition audiolayer.h:283
std::unique_ptr< Resampler > resampler_
Manage sampling rate conversion.
Definition audiolayer.h:288
virtual int getIndexRingtone() const =0
bool isRingtoneMuted() const
Definition audiolayer.h:143
virtual int getIndexCapture() const =0
virtual void updatePreference(AudioPreference &pref, int index, AudioDeviceType type)=0
double getPlaybackGain() const
Get playback stream gain (speaker)
Definition audiolayer.h:166
std::atomic< Status > status_
Whether or not the audio layer's playback stream is started.
Definition audiolayer.h:260
std::shared_ptr< AudioFrame > getPlayback(AudioFormat format, size_t samples)
Definition audiolayer.h:207
virtual std::vector< std::string > getPlaybackDeviceList() const =0
RingBuffer urgentRingBuffer_
Urgent ring buffer used for ringtones.
Definition audiolayer.h:278
bool waitForStart(const std::chrono::duration< Rep, Period > &rel_time) const
Definition audiolayer.h:99
virtual ~AudioLayer()
void playbackChanged(bool started)
void notifyIncomingCall()
Emit an audio notification (beep) on incoming calls.
virtual int getIndexPlayback() const =0
double getCaptureGain() const
Get capture stream gain (microphone)
Definition audiolayer.h:155
void muteRingtone(bool muted)
Definition audiolayer.h:144
virtual void startStream(AudioDeviceType stream=AudioDeviceType::ALL)=0
Start the capture stream and prepare the playback stream.
void setHasNativeNS(bool hasNS)
bool isPlaybackMuted_
True if playback is not to be used.
Definition audiolayer.h:226
virtual int getAudioDeviceIndex(const std::string &name, AudioDeviceType type) const =0
void hardwareFormatAvailable(AudioFormat playback, size_t bufSize=0)
Callback to be called by derived classes when the audio output is opened.
std::shared_ptr< AudioFrame > getToRing(AudioFormat format, size_t writableSamples)
bool isCaptureMuted() const
Definition audiolayer.h:129
void flushUrgent()
Flush urgent buffer.
void hardwareInputFormatAvailable(AudioFormat capture)
Set the input format on necessary objects.
std::unique_ptr< AudioFrameResizer > playbackQueue_
Definition audiolayer.h:255
void muteCapture(bool muted)
Mute capture (microphone)
Definition audiolayer.h:134
double captureGain_
Gain applied to mic signal.
Definition audiolayer.h:241
void playIncomingCallNotification(bool play)
Start/Stop playing the incoming call notification sound (beep) while playing back audio (typically du...
Definition audiolayer.h:117
void setHasNativeAEC(bool hasEAC)
std::shared_ptr< AudioFrame > getToPlay(AudioFormat format, size_t writableSamples)
size_t nativeFrameSize_
Definition audiolayer.h:273
bool isPlaybackMuted() const
Definition audiolayer.h:136
virtual std::string getAudioDeviceName(int index, AudioDeviceType type) const =0
virtual void stopStream(AudioDeviceType stream=AudioDeviceType::ALL)=0
Stop the playback and capture streams.
double playbackGain_
Gain applied to playback signal.
Definition audiolayer.h:246
bool isRingtoneMuted_
True if ringtone should be muted.
Definition audiolayer.h:231
void recordChanged(bool started)
AudioFormat audioFormat_
Sample Rate that should be sent to the sound card.
Definition audiolayer.h:266
bool isStarted() const
Determine whether or not the audio layer is active (i.e.
Definition audiolayer.h:96
void flushMain()
Flush main buffer.
unsigned int getSampleRate() const
Get the sample rate of the audio layer.
Definition audiolayer.h:173
const AudioPreference & pref_
Definition audiolayer.h:249
AudioFormat audioInputFormat_
Sample Rate for input.
Definition audiolayer.h:271
std::condition_variable startedCv_
Definition audiolayer.h:261
virtual std::vector< std::string > getCaptureDeviceList() const =0
void setCaptureGain(double gain)
Set capture stream gain (microphone) Range should be [-1.0, 1.0].
Definition audiolayer.h:150
void putRecorded(std::shared_ptr< AudioFrame > &&frame)
void setPlaybackGain(double gain)
Set playback stream gain (speaker) Range should be [-1.0, 1.0].
Definition audiolayer.h:161
AudioFormat getFormat() const
Get the audio format of the layer (sample rate & channel number).
Definition audiolayer.h:178
void putUrgent(std::shared_ptr< AudioFrame > buffer)
Send a chunk of data to the hardware buffer to start the playback Copy data in the urgent buffer.
A ring buffer for mutichannel audio samples.
Definition ringbuffer.h:38
void emitSignal(Args... args)
Definition ring_signal.h:64
AudioDeviceType
Definition audiolayer.h:58
Simple macro to hide class' copy constructor and assignment operator.
#define NON_COPYABLE(ClassName)
Definition noncopyable.h:30
struct SpeexEchoState_ SpeexEchoState
Definition speex.h:24
Structure to hold sample rate and channel number associated with audio data.