Line data Source code
1 : /* 2 : * Copyright (C) 2004-2024 Savoir-faire Linux Inc. 3 : * 4 : * Author: Hugo Lefeuvre <hugo.lefeuvre@savoirfairelinux.com> 5 : * Author: Philippe Gorley <philippe.gorley@savoirfairelinux.com> 6 : * 7 : * This program is free software; you can redistribute it and/or modify 8 : * it under the terms of the GNU General Public License as published by 9 : * the Free Software Foundation; either version 3 of the License, or 10 : * (at your option) any later version. 11 : * 12 : * This program is distributed in the hope that it will be useful, 13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : * GNU General Public License for more details. 16 : * 17 : * You should have received a copy of the GNU General Public License 18 : * along with this program; if not, write to the Free Software 19 : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 : */ 21 : 22 : #pragma once 23 : 24 : #include <atomic> 25 : #include <future> 26 : #include <mutex> 27 : #include <chrono> 28 : 29 : #include "audio_format.h" 30 : #include "media/media_device.h" 31 : #include "media/media_buffer.h" 32 : #include "observer.h" 33 : #include "threadloop.h" 34 : #include "media/media_codec.h" 35 : 36 : namespace jami { 37 : class AudioDeviceGuard; 38 : class AudioFrameResizer; 39 : class MediaDemuxer; 40 : class MediaDecoder; 41 : class MediaRecorder; 42 : struct MediaStream; 43 : class Resampler; 44 : class RingBuffer; 45 : 46 : class AudioInput : public Observable<std::shared_ptr<MediaFrame>> 47 : { 48 : public: 49 : AudioInput(const std::string& id); 50 : AudioInput(const std::string& id, const std::string& resource); 51 : ~AudioInput(); 52 : 53 : std::shared_future<DeviceParams> switchInput(const std::string& resource); 54 10 : void start() { loop_.start(); }; 55 : 56 0 : bool isCapturing() const { return loop_.isRunning(); } 57 : void setFormat(const AudioFormat& fmt); 58 : void setMuted(bool isMuted); 59 : MediaStream getInfo() const; 60 : MediaStream getInfo(const std::string& name) const; 61 : void updateStartTime(int64_t start); 62 : void setPaused(bool paused); 63 : void configureFilePlayback(const std::string& path, 64 : std::shared_ptr<MediaDemuxer>& demuxer, 65 : int index); 66 : void flushBuffers(); 67 : void setSeekTime(int64_t time); 68 : 69 187 : void setSuccessfulSetupCb(const std::function<void(MediaType, bool)>& cb) 70 : { 71 187 : onSuccessfulSetup_ = cb; 72 187 : } 73 : 74 : void setRecorderCallback(const std::function<void(const MediaStream& ms)>& cb); 75 : 76 187 : std::string getId() const { return id_; }; 77 : 78 : private: 79 : void readFromDevice(); 80 : void readFromFile(); 81 : void readFromQueue(); 82 : bool initDevice(const std::string& device); 83 : bool initFile(const std::string& path); 84 : bool createDecoder(); 85 : void frameResized(std::shared_ptr<AudioFrame>&& ptr); 86 : 87 : std::string id_; 88 : std::shared_ptr<RingBuffer> ringBuf_; 89 : bool muteState_ {false}; 90 : uint64_t sent_samples = 0; 91 : mutable std::mutex fmtMutex_ {}; 92 : AudioFormat format_; 93 : int frameSize_; 94 : std::atomic_bool paused_ {true}; 95 : 96 : std::unique_ptr<Resampler> resampler_; 97 : std::unique_ptr<AudioFrameResizer> resizer_; 98 : std::unique_ptr<MediaDecoder> decoder_; 99 : 100 : std::string resource_; 101 : std::mutex resourceMutex_ {}; 102 : DeviceParams devOpts_; 103 : std::promise<DeviceParams> foundDevOpts_; 104 : std::shared_future<DeviceParams> futureDevOpts_; 105 : std::atomic_bool devOptsFound_ {false}; 106 : void foundDevOpts(const DeviceParams& params); 107 : 108 : std::atomic_bool playingDevice_ {false}; 109 : std::atomic_bool decodingFile_ {false}; 110 : std::atomic_bool playingFile_ {false}; 111 : std::unique_ptr<AudioDeviceGuard> deviceGuard_; 112 : 113 : ThreadLoop loop_; 114 : void process(); 115 : 116 : std::chrono::time_point<std::chrono::steady_clock> wakeUp_; 117 : 118 : std::function<void(MediaType, bool)> onSuccessfulSetup_; 119 : std::function<void(const MediaStream& ms)> recorderCallback_; 120 : std::atomic_bool settingMS_ {true}; 121 : }; 122 : 123 : } // namespace jami