diff --git a/src/manager.cpp b/src/manager.cpp index 8f54cb90a85389139ea1566f609a00050fb1cdc6..04f4952856e488a7d9e9bf4e8251deb61976583b 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -903,7 +903,6 @@ Manager::outgoingCall(const std::string& account_id, JAMI_DBG() << "try outgoing call to '" << to << "'" << " with account '" << account_id << "'"; - const auto& current_call_id(getCurrentCallId()); std::string to_cleaned = hookPreference.getNumberAddPrefix() + trim(to); std::shared_ptr<Call> call; @@ -939,12 +938,9 @@ Manager::answerCall(const std::string& call_id) return false; } - // If ring is ringing + // If ringing stopTone(); - // store the current call id - const auto& current_call_id(getCurrentCallId()); - try { call->answer(); } catch (const std::runtime_error &e) { diff --git a/src/media/audio/audio_receive_thread.h b/src/media/audio/audio_receive_thread.h index 418efcb5b7089b6ad9e88854b5854d9a2e5999de..57af79ecbe225d1b49555683b8ef4fb048fc50bb 100644 --- a/src/media/audio/audio_receive_thread.h +++ b/src/media/audio/audio_receive_thread.h @@ -18,6 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#pragma once #include "audiobuffer.h" #include "media_buffer.h" diff --git a/src/media/audio/audio_rtp_session.h b/src/media/audio/audio_rtp_session.h index faac7acd0e5f5314653c3a8fcbb6e3f48a0fa7b7..88c2bd564be5c79816aa535e2f318a7b6033eb22 100644 --- a/src/media/audio/audio_rtp_session.h +++ b/src/media/audio/audio_rtp_session.h @@ -19,13 +19,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef AUDIO_RTP_SESSION_H__ -#define AUDIO_RTP_SESSION_H__ +#pragma once #include "audiobuffer.h" #include "media_device.h" #include "rtp_session.h" -#include "threadloop.h" #include <string> #include <memory> @@ -70,5 +68,3 @@ class AudioRtpSession : public RtpSession { }; } // namespace jami - -#endif // __AUDIO_RTP_SESSION_H__ diff --git a/src/media/audio/audio_sender.h b/src/media/audio/audio_sender.h index 2d2b123bca8adfed691c0fe4d31e09a766ba474e..10452121bcfa6bf0d4bbcb9d1247ae36b5ef89c2 100644 --- a/src/media/audio/audio_sender.h +++ b/src/media/audio/audio_sender.h @@ -18,6 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#pragma once #include "audiobuffer.h" #include "media_buffer.h" diff --git a/src/media/audio/audiobuffer.h b/src/media/audio/audiobuffer.h index ee13a2f17e44c6382811f8032b2f920a8e70b1ee..61b7119a6718c6b7c23ccae7447d3eb689ea17dd 100644 --- a/src/media/audio/audiobuffer.h +++ b/src/media/audio/audiobuffer.h @@ -18,8 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef _AUDIO_BUFFER_H -#define _AUDIO_BUFFER_H +#pragma once #if __cplusplus >= 201103L #undef isblank @@ -376,4 +375,3 @@ class AudioBuffer { } // namespace jami -#endif // _AUDIO_BUFFER_H diff --git a/src/media/audio/audiolayer.h b/src/media/audio/audiolayer.h index 1e42a1fb303f592cf24702a7f6d9b88ab4c77a51..3e6b36e2f27deea1f52131834853b98a8c20aeca 100644 --- a/src/media/audio/audiolayer.h +++ b/src/media/audio/audiolayer.h @@ -20,10 +20,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ - -#ifndef AUDIO_LAYER_H_ -#define AUDIO_LAYER_H_ - +#pragma once #include "ringbuffer.h" #include "dcblocker.h" @@ -65,265 +62,263 @@ enum class DeviceType { class AudioLayer { - private: - NON_COPYABLE(AudioLayer); - - protected: - enum class Status { - Idle, - Starting, - Started - }; - - public: - - AudioLayer(const AudioPreference &); - virtual ~AudioLayer(); - - virtual std::vector<std::string> getCaptureDeviceList() const = 0; - virtual std::vector<std::string> getPlaybackDeviceList() const = 0; - - virtual int getAudioDeviceIndex(const std::string& name, DeviceType type) const = 0; - virtual std::string getAudioDeviceName(int index, DeviceType type) const = 0; - virtual int getIndexCapture() const = 0; - virtual int getIndexPlayback() const = 0; - virtual int getIndexRingtone() const = 0; - - /** - * Start the capture stream and prepare the playback stream. - * The playback starts accordingly to its threshold - * ALSA Library API - */ - virtual void startStream() = 0; - - /** - * Stop the playback and capture streams. - * Drops the pending frames and put the capture and playback handles to PREPARED state - * ALSA Library API - */ - virtual void stopStream() = 0; - - /** - * Determine wether or not the audio layer is active (i.e. stream opened) - */ - inline bool isStarted() const { - return status_ == Status::Started; - } - - template< class Rep, class Period > - bool waitForStart(const std::chrono::duration<Rep, Period>& rel_time) const { - std::unique_lock<std::mutex> lk(mutex_); - startedCv_.wait_for(lk, rel_time, [&]{return isStarted();}); - return isStarted(); - } - - /** - * Send a chunk of data to the hardware buffer to start the playback - * Copy data in the urgent buffer. - * @param buffer The buffer containing the data to be played ( ringtones ) - */ - void putUrgent(AudioBuffer& buffer); - - /** - * Flush main buffer - */ - void flushMain(); - - /** - * Flush urgent buffer - */ - void flushUrgent(); - - bool isCaptureMuted() const { - return isCaptureMuted_; - } - - /** - * Mute capture (microphone) - */ - void muteCapture(bool muted) { - isCaptureMuted_ = muted; - } - - bool isPlaybackMuted() const { - return isPlaybackMuted_; - } - - /** - * Mute playback - */ - void mutePlayback(bool muted) { - isPlaybackMuted_ = muted; - } - - bool isRingtoneMuted() const { - return isRingtoneMuted_; - } - void muteRingtone(bool muted) { - isRingtoneMuted_ = muted; - } - - /** - * Set capture stream gain (microphone) - * Range should be [-1.0, 1.0] - */ - void setCaptureGain(double gain) { - captureGain_ = gain; - } - - /** - * Get capture stream gain (microphone) - */ - double getCaptureGain() const { - return captureGain_; - } - - /** - * Set playback stream gain (speaker) - * Range should be [-1.0, 1.0] - */ - void setPlaybackGain(double gain) { - playbackGain_ = gain; - } - - /** - * Get playback stream gain (speaker) - */ - double getPlaybackGain() const { - return playbackGain_; - } - - /** - * Get the sample rate of the audio layer - * @return unsigned int The sample rate - * default: 44100 HZ - */ - unsigned int getSampleRate() const { - return audioFormat_.sample_rate; - } - - /** - * Get the audio format of the layer (sample rate & channel number). - */ - AudioFormat getFormat() const { - return audioFormat_; - } - - /** - * Emit an audio notification on incoming calls - */ - void notifyIncomingCall(); - - virtual void updatePreference(AudioPreference &pref, int index, DeviceType type) = 0; - - protected: - /** - * Callback to be called by derived classes when the audio output is opened. - */ - void hardwareFormatAvailable(AudioFormat playback); - - /** - * Set the input format on necessary objects. - */ - void hardwareInputFormatAvailable(AudioFormat capture); - - void devicesChanged(); - - std::shared_ptr<AudioFrame> getToPlay(AudioFormat format, size_t writableSamples); - - std::shared_ptr<AudioFrame> getToRing(AudioFormat format, size_t writableSamples); - - std::shared_ptr<AudioFrame> getPlayback(AudioFormat format, size_t samples) { - const auto& ringBuff = getToRing(format, samples); - const auto& playBuff = getToPlay(format, samples); - return ringBuff ? ringBuff : playBuff; - } - - void flush(); - - /** - * True if capture is not to be used - */ - bool isCaptureMuted_; - - /** - * True if playback is not to be used - */ - bool isPlaybackMuted_; - - /** - * True if ringtone should be muted - */ - bool isRingtoneMuted_ {false}; - - /** - * Gain applied to mic signal - */ - double captureGain_; - - /** - * Gain applied to playback signal - */ - double playbackGain_; - - /** - * Buffers for audio processing - */ - AudioBuffer playbackBuffer_; - AudioBuffer playbackResampleBuffer_; - AudioBuffer ringtoneBuffer_; - AudioBuffer ringtoneResampleBuffer_; - std::unique_ptr<AudioFrameResizer> playbackQueue_; - - /** - * Whether or not the audio layer stream is started - */ - std::atomic<Status> status_ {Status::Idle}; - mutable std::condition_variable startedCv_; - - /** - * Sample Rate that should be sent to the sound card - */ - AudioFormat audioFormat_; - - /** - * Sample Rate for input. - */ - AudioFormat audioInputFormat_; - - /** - * Urgent ring buffer used for ringtones - */ - RingBuffer urgentRingBuffer_; - - /** - * Lock for the entire audio layer - */ - mutable std::mutex mutex_ {}; - - /** - * Remove audio offset that can be introduced by certain cheap audio device - */ - DcBlocker dcblocker_ {}; - - /** - * Manage sampling rate conversion - */ - std::unique_ptr<Resampler> resampler_; - - /** - * Manage input sampling rate conversions - */ - std::unique_ptr<Resampler> inputResampler_; - - private: - - /** - * Time of the last incoming call notification - */ - std::chrono::system_clock::time_point lastNotificationTime_; +private: + NON_COPYABLE(AudioLayer); + +protected: + enum class Status { + Idle, + Starting, + Started + }; + +public: + + AudioLayer(const AudioPreference &); + virtual ~AudioLayer(); + + virtual std::vector<std::string> getCaptureDeviceList() const = 0; + virtual std::vector<std::string> getPlaybackDeviceList() const = 0; + + virtual int getAudioDeviceIndex(const std::string& name, DeviceType type) const = 0; + virtual std::string getAudioDeviceName(int index, DeviceType type) const = 0; + virtual int getIndexCapture() const = 0; + virtual int getIndexPlayback() const = 0; + virtual int getIndexRingtone() const = 0; + + /** + * Start the capture stream and prepare the playback stream. + * The playback starts accordingly to its threshold + * ALSA Library API + */ + virtual void startStream() = 0; + + /** + * Stop the playback and capture streams. + * Drops the pending frames and put the capture and playback handles to PREPARED state + * ALSA Library API + */ + virtual void stopStream() = 0; + + /** + * Determine wether or not the audio layer is active (i.e. stream opened) + */ + inline bool isStarted() const { + return status_ == Status::Started; + } + + template< class Rep, class Period > + bool waitForStart(const std::chrono::duration<Rep, Period>& rel_time) const { + std::unique_lock<std::mutex> lk(mutex_); + startedCv_.wait_for(lk, rel_time, [&]{return isStarted();}); + return isStarted(); + } + + /** + * Send a chunk of data to the hardware buffer to start the playback + * Copy data in the urgent buffer. + * @param buffer The buffer containing the data to be played ( ringtones ) + */ + void putUrgent(AudioBuffer& buffer); + + /** + * Flush main buffer + */ + void flushMain(); + + /** + * Flush urgent buffer + */ + void flushUrgent(); + + bool isCaptureMuted() const { + return isCaptureMuted_; + } + + /** + * Mute capture (microphone) + */ + void muteCapture(bool muted) { + isCaptureMuted_ = muted; + } + + bool isPlaybackMuted() const { + return isPlaybackMuted_; + } + + /** + * Mute playback + */ + void mutePlayback(bool muted) { + isPlaybackMuted_ = muted; + } + + bool isRingtoneMuted() const { + return isRingtoneMuted_; + } + void muteRingtone(bool muted) { + isRingtoneMuted_ = muted; + } + + /** + * Set capture stream gain (microphone) + * Range should be [-1.0, 1.0] + */ + void setCaptureGain(double gain) { + captureGain_ = gain; + } + + /** + * Get capture stream gain (microphone) + */ + double getCaptureGain() const { + return captureGain_; + } + + /** + * Set playback stream gain (speaker) + * Range should be [-1.0, 1.0] + */ + void setPlaybackGain(double gain) { + playbackGain_ = gain; + } + + /** + * Get playback stream gain (speaker) + */ + double getPlaybackGain() const { + return playbackGain_; + } + + /** + * Get the sample rate of the audio layer + * @return unsigned int The sample rate + * default: 44100 HZ + */ + unsigned int getSampleRate() const { + return audioFormat_.sample_rate; + } + + /** + * Get the audio format of the layer (sample rate & channel number). + */ + AudioFormat getFormat() const { + return audioFormat_; + } + + /** + * Emit an audio notification on incoming calls + */ + void notifyIncomingCall(); + + virtual void updatePreference(AudioPreference &pref, int index, DeviceType type) = 0; + +protected: + /** + * Callback to be called by derived classes when the audio output is opened. + */ + void hardwareFormatAvailable(AudioFormat playback); + + /** + * Set the input format on necessary objects. + */ + void hardwareInputFormatAvailable(AudioFormat capture); + + void devicesChanged(); + + std::shared_ptr<AudioFrame> getToPlay(AudioFormat format, size_t writableSamples); + + std::shared_ptr<AudioFrame> getToRing(AudioFormat format, size_t writableSamples); + + std::shared_ptr<AudioFrame> getPlayback(AudioFormat format, size_t samples) { + const auto& ringBuff = getToRing(format, samples); + const auto& playBuff = getToPlay(format, samples); + return ringBuff ? ringBuff : playBuff; + } + + void flush(); + + /** + * True if capture is not to be used + */ + bool isCaptureMuted_; + + /** + * True if playback is not to be used + */ + bool isPlaybackMuted_; + + /** + * True if ringtone should be muted + */ + bool isRingtoneMuted_ {false}; + + /** + * Gain applied to mic signal + */ + double captureGain_; + + /** + * Gain applied to playback signal + */ + double playbackGain_; + + /** + * Buffers for audio processing + */ + AudioBuffer playbackBuffer_; + AudioBuffer playbackResampleBuffer_; + AudioBuffer ringtoneBuffer_; + AudioBuffer ringtoneResampleBuffer_; + std::unique_ptr<AudioFrameResizer> playbackQueue_; + + /** + * Whether or not the audio layer stream is started + */ + std::atomic<Status> status_ {Status::Idle}; + mutable std::condition_variable startedCv_; + + /** + * Sample Rate that should be sent to the sound card + */ + AudioFormat audioFormat_; + + /** + * Sample Rate for input. + */ + AudioFormat audioInputFormat_; + + /** + * Urgent ring buffer used for ringtones + */ + RingBuffer urgentRingBuffer_; + + /** + * Lock for the entire audio layer + */ + mutable std::mutex mutex_ {}; + + /** + * Remove audio offset that can be introduced by certain cheap audio device + */ + DcBlocker dcblocker_ {}; + + /** + * Manage sampling rate conversion + */ + std::unique_ptr<Resampler> resampler_; + + /** + * Manage input sampling rate conversions + */ + std::unique_ptr<Resampler> inputResampler_; + +private: + + /** + * Time of the last incoming call notification + */ + std::chrono::system_clock::time_point lastNotificationTime_; }; } // namespace jami - -#endif // _AUDIO_LAYER_H_ diff --git a/src/media/audio/audioloop.h b/src/media/audio/audioloop.h index 447611697a811cbe995c1a367ab73416d65202a8..5ea5721f6b939b1156644bcf29595444dc20e316 100644 --- a/src/media/audio/audioloop.h +++ b/src/media/audio/audioloop.h @@ -20,7 +20,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ - #pragma once #include "ring_types.h" @@ -35,58 +34,58 @@ namespace jami { class AudioLoop { - public: - AudioLoop() {} - - AudioLoop(unsigned int sampleRate); - - AudioLoop& operator=(AudioLoop&& o) noexcept { - std::swap(buffer_, o.buffer_); - std::swap(pos_, o.pos_); - return *this; - } - - virtual ~AudioLoop(); - - /** - * Get the next fragment of the tone - * the function change the intern position, and will loop - * @param output The data buffer - * @param nb of int16 to send - * @param gain The gain [-1.0, 1.0] - */ - void getNext(AudioBuffer& output, double gain); - std::unique_ptr<AudioFrame> getNext(size_t samples = 0); - - void seek(double relative_position); - - /** - * Reset the pointer position - */ - void reset() { - pos_ = 0; - } - - /** - * Accessor to the size of the buffer - * @return unsigned int The size - */ - size_t getSize() const { - return buffer_->frames(); - } - AudioFormat getFormat() const { - return buffer_->getFormat(); - } - protected: - /** The data buffer */ - AudioBuffer * buffer_ {nullptr}; - - /** current position, set to 0, when initialize */ - size_t pos_ {0}; - - private: - NON_COPYABLE(AudioLoop); - virtual void onBufferFinish(); +public: + AudioLoop() {} + + AudioLoop(unsigned int sampleRate); + + AudioLoop& operator=(AudioLoop&& o) noexcept { + std::swap(buffer_, o.buffer_); + std::swap(pos_, o.pos_); + return *this; + } + + virtual ~AudioLoop(); + + /** + * Get the next fragment of the tone + * the function change the intern position, and will loop + * @param output The data buffer + * @param nb of int16 to send + * @param gain The gain [-1.0, 1.0] + */ + void getNext(AudioBuffer& output, double gain); + std::unique_ptr<AudioFrame> getNext(size_t samples = 0); + + void seek(double relative_position); + + /** + * Reset the pointer position + */ + void reset() { + pos_ = 0; + } + + /** + * Accessor to the size of the buffer + * @return unsigned int The size + */ + size_t getSize() const { + return buffer_->frames(); + } + AudioFormat getFormat() const { + return buffer_->getFormat(); + } +protected: + /** The data buffer */ + AudioBuffer * buffer_ {nullptr}; + + /** current position, set to 0, when initialize */ + size_t pos_ {0}; + +private: + NON_COPYABLE(AudioLoop); + virtual void onBufferFinish(); }; } // namespace jami diff --git a/src/smartools.cpp b/src/smartools.cpp index 58ab7826219904e338b5cf90887785d817ca945a..d7bde8c3f645061838f52bc9a22d471b16c7a58f 100644 --- a/src/smartools.cpp +++ b/src/smartools.cpp @@ -47,12 +47,13 @@ void Smartools::start(std::chrono::milliseconds refreshTimeMs) { JAMI_DBG("Start SmartInfo"); - if (auto t = std::move(task_)) - t->cancel(); - task_ = Manager::instance().scheduler().scheduleAtFixedRate([this]{ + auto task = Manager::instance().scheduler().scheduleAtFixedRate([this]{ sendInfo(); return true; }, refreshTimeMs); + task_.swap(task); + if (task) + task->cancel(); } void