| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- // This file is part of Desktop App Toolkit,
- // a set of libraries for developing nice desktop applications.
- //
- // For license and copyright information please follow this link:
- // https://github.com/desktop-app/legal/blob/master/LEGAL
- //
- #include "webrtc/webrtc_audio_input_tester.h"
- #include "webrtc/webrtc_device_common.h"
- #include "webrtc/webrtc_create_adm.h"
- #include "crl/crl_object_on_thread.h"
- #include "crl/crl_async.h"
- #include <api/task_queue/default_task_queue_factory.h>
- #include <modules/audio_device/include/audio_device_defines.h>
- #include <modules/audio_device/include/audio_device.h>
- namespace Webrtc {
- class AudioInputTester::Impl : public webrtc::AudioTransport {
- public:
- explicit Impl(const std::shared_ptr<std::atomic<int>> &maxSample);
- ~Impl();
- void setDeviceId(const DeviceResolvedId &deviceId);
- private:
- void init();
- void restart();
- int32_t RecordedDataIsAvailable(
- const void* audioSamples,
- const size_t nSamples,
- const size_t nBytesPerSample,
- const size_t nChannels,
- const uint32_t samplesPerSec,
- const uint32_t totalDelayMS,
- const int32_t clockDrift,
- const uint32_t currentMicLevel,
- const bool keyPressed,
- uint32_t& newMicLevel) override;
- // Implementation has to setup safe values for all specified out parameters.
- int32_t NeedMorePlayData(
- const size_t nSamples,
- const size_t nBytesPerSample,
- const size_t nChannels,
- const uint32_t samplesPerSec,
- void* audioSamples,
- size_t& nSamplesOut, // NOLINT
- int64_t* elapsed_time_ms,
- int64_t* ntp_time_ms) override;
- // Method to pull mixed render audio data from all active VoE channels.
- // The data will not be passed as reference for audio processing internally.
- void PullRenderData(
- int bits_per_sample,
- int sample_rate,
- size_t number_of_channels,
- size_t number_of_frames,
- void* audio_data,
- int64_t* elapsed_time_ms,
- int64_t* ntp_time_ms) override;
- std::shared_ptr<std::atomic<int>> _maxSample;
- std::unique_ptr<webrtc::TaskQueueFactory> _taskQueueFactory;
- rtc::scoped_refptr<webrtc::AudioDeviceModule> _adm;
- Fn<void(DeviceResolvedId)> _setDeviceIdCallback;
- DeviceResolvedId _deviceId;
- };
- AudioInputTester::Impl::Impl(
- const std::shared_ptr<std::atomic<int>> &maxSample)
- : _maxSample(std::move(maxSample))
- , _taskQueueFactory(webrtc::CreateDefaultTaskQueueFactory())
- , _deviceId{ .type = DeviceType::Capture } {
- const auto saveSetDeviceIdCallback = [=](
- Fn<void(DeviceResolvedId)> setDeviceIdCallback) {
- _setDeviceIdCallback = std::move(setDeviceIdCallback);
- if (!_deviceId.isDefault()) {
- _setDeviceIdCallback(_deviceId);
- restart();
- }
- };
- _adm = CreateAudioDeviceModule(
- _taskQueueFactory.get(),
- saveSetDeviceIdCallback);
- init();
- }
- AudioInputTester::Impl::~Impl() {
- if (_adm) {
- _adm->StopRecording();
- _adm->RegisterAudioCallback(nullptr);
- _adm->Terminate();
- }
- }
- void AudioInputTester::Impl::init() {
- if (!_adm) {
- return;
- }
- _adm->Init();
- _adm->RegisterAudioCallback(this);
- }
- void AudioInputTester::Impl::setDeviceId(const DeviceResolvedId &deviceId) {
- _deviceId = deviceId;
- if (_setDeviceIdCallback) {
- _setDeviceIdCallback(_deviceId);
- restart();
- }
- }
- void AudioInputTester::Impl::restart() {
- if (!_adm) {
- return;
- }
- _adm->StopRecording();
- _adm->SetRecordingDevice(0);
- if (_adm->InitRecording() == 0) {
- _adm->StartRecording();
- }
- }
- int32_t AudioInputTester::Impl::RecordedDataIsAvailable(
- const void* audioSamples,
- const size_t nSamples,
- const size_t nBytesPerSample,
- const size_t nChannels,
- const uint32_t samplesPerSec,
- const uint32_t totalDelayMS,
- const int32_t clockDrift,
- const uint32_t currentMicLevel,
- const bool keyPressed,
- uint32_t& newMicLevel) {
- const auto channels = nBytesPerSample / sizeof(int16_t);
- if (channels > 0 && !(nBytesPerSample % sizeof(int16_t))) {
- auto max = 0;
- auto values = static_cast<const int16_t*>(audioSamples);
- for (auto i = size_t(); i != nSamples * channels; ++i) {
- if (max < values[i]) {
- max = values[i];
- }
- }
- const auto now = _maxSample->load();
- if (max > now) {
- _maxSample->store(max);
- }
- }
- newMicLevel = currentMicLevel;
- return 0;
- }
- int32_t AudioInputTester::Impl::NeedMorePlayData(const size_t nSamples,
- const size_t nBytesPerSample,
- const size_t nChannels,
- const uint32_t samplesPerSec,
- void* audioSamples,
- size_t& nSamplesOut,
- int64_t* elapsed_time_ms,
- int64_t* ntp_time_ms) {
- nSamplesOut = 0;
- return 0;
- }
- void AudioInputTester::Impl::PullRenderData(int bits_per_sample,
- int sample_rate,
- size_t number_of_channels,
- size_t number_of_frames,
- void* audio_data,
- int64_t* elapsed_time_ms,
- int64_t* ntp_time_ms) {
- }
- AudioInputTester::AudioInputTester(rpl::producer<DeviceResolvedId> deviceId)
- : _maxSample(std::make_shared<std::atomic<int>>(0))
- , _impl(std::as_const(_maxSample)) {
- std::move(
- deviceId
- ) | rpl::start_with_next([=](const DeviceResolvedId &id) {
- _impl.with([=](Impl &impl) {
- impl.setDeviceId(id);
- });
- }, _lifetime);
- }
- AudioInputTester::~AudioInputTester() = default;
- float AudioInputTester::getAndResetLevel() {
- return _maxSample->exchange(0) / float(INT16_MAX);
- }
- } // namespace Webrtc
|