media_audio_track.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #pragma once
  8. #include "base/timer.h"
  9. #include "base/bytes.h"
  10. #include "webrtc/webrtc_device_resolver.h"
  11. namespace Core {
  12. class FileLocation;
  13. } // namespace Core
  14. namespace Media {
  15. namespace Audio {
  16. class Instance;
  17. class Track {
  18. public:
  19. Track(not_null<Instance*> instance);
  20. void samplePeakEach(crl::time peakDuration);
  21. void fillFromData(bytes::vector &&data);
  22. void fillFromFile(const Core::FileLocation &location);
  23. void fillFromFile(const QString &filePath);
  24. void playOnce() {
  25. playWithLooping(false);
  26. }
  27. void playInLoop() {
  28. playWithLooping(true);
  29. }
  30. bool isLooping() const {
  31. return _looping;
  32. }
  33. bool isActive() const {
  34. return _active;
  35. }
  36. bool failed() const {
  37. return _failed;
  38. }
  39. int64 getLengthMs() const {
  40. return _lengthMs;
  41. }
  42. float64 getPeakValue(crl::time when) const;
  43. void detachFromDevice();
  44. void reattachToDevice();
  45. void updateState();
  46. ~Track();
  47. private:
  48. void finish();
  49. void ensureSourceCreated();
  50. void playWithLooping(bool looping);
  51. not_null<Instance*> _instance;
  52. bool _failed = false;
  53. bool _active = false;
  54. bool _looping = false;
  55. float64 _volume = 1.;
  56. int64 _samplesCount = 0;
  57. int32 _sampleRate = 0;
  58. bytes::vector _samples;
  59. crl::time _peakDurationMs = 0;
  60. int _peakEachPosition = 0;
  61. std::vector<uint16> _peaks;
  62. uint16 _peakValueMin = 0;
  63. uint16 _peakValueMax = 0;
  64. crl::time _lengthMs = 0;
  65. crl::time _stateUpdatedAt = 0;
  66. int32 _alFormat = 0;
  67. int64 _alPosition = 0;
  68. uint32 _alSource = 0;
  69. uint32 _alBuffer = 0;
  70. };
  71. class Instance {
  72. public:
  73. // Thread: Main.
  74. Instance();
  75. // Thread: Any. Must be locked: AudioMutex.
  76. [[nodiscard]] Webrtc::DeviceResolvedId playbackDeviceId() const;
  77. // Thread: Main.
  78. [[nodiscard]] Webrtc::DeviceResolvedId captureDeviceId() const;
  79. [[nodiscard]] std::unique_ptr<Track> createTrack();
  80. void detachTracks();
  81. void reattachTracks();
  82. bool hasActiveTracks() const;
  83. void scheduleDetachFromDevice();
  84. void scheduleDetachIfNotUsed();
  85. void stopDetachIfNotUsed();
  86. ~Instance();
  87. private:
  88. friend class Track;
  89. void registerTrack(Track *track);
  90. void unregisterTrack(Track *track);
  91. void trackStarted(Track *track);
  92. void trackFinished(Track *track);
  93. private:
  94. std::set<Track*> _tracks;
  95. Webrtc::DeviceResolver _playbackDeviceId;
  96. Webrtc::DeviceResolver _captureDeviceId;
  97. base::Timer _updateTimer;
  98. base::Timer _detachFromDeviceTimer;
  99. bool _detachFromDeviceForce = false;
  100. rpl::lifetime _lifetime;
  101. };
  102. [[nodiscard]] Instance &Current();
  103. } // namespace Audio
  104. } // namespace Media