Repo created

This commit is contained in:
Fr4nz D13trich 2025-11-22 14:04:28 +01:00
parent 81b91f4139
commit f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions

View file

@ -0,0 +1,226 @@
/*
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/audio_device/dummy/audio_device_dummy.h"
namespace webrtc {
int32_t AudioDeviceDummy::ActiveAudioLayer(
AudioDeviceModule::AudioLayer& audioLayer) const {
return -1;
}
AudioDeviceGeneric::InitStatus AudioDeviceDummy::Init() {
return InitStatus::OK;
}
int32_t AudioDeviceDummy::Terminate() {
return 0;
}
bool AudioDeviceDummy::Initialized() const {
return true;
}
int16_t AudioDeviceDummy::PlayoutDevices() {
return -1;
}
int16_t AudioDeviceDummy::RecordingDevices() {
return -1;
}
int32_t AudioDeviceDummy::PlayoutDeviceName(uint16_t index,
char name[kAdmMaxDeviceNameSize],
char guid[kAdmMaxGuidSize]) {
return -1;
}
int32_t AudioDeviceDummy::RecordingDeviceName(uint16_t index,
char name[kAdmMaxDeviceNameSize],
char guid[kAdmMaxGuidSize]) {
return -1;
}
int32_t AudioDeviceDummy::SetPlayoutDevice(uint16_t index) {
return -1;
}
int32_t AudioDeviceDummy::SetPlayoutDevice(
AudioDeviceModule::WindowsDeviceType device) {
return -1;
}
int32_t AudioDeviceDummy::SetRecordingDevice(uint16_t index) {
return -1;
}
int32_t AudioDeviceDummy::SetRecordingDevice(
AudioDeviceModule::WindowsDeviceType device) {
return -1;
}
int32_t AudioDeviceDummy::PlayoutIsAvailable(bool& available) {
return -1;
}
int32_t AudioDeviceDummy::InitPlayout() {
return -1;
}
bool AudioDeviceDummy::PlayoutIsInitialized() const {
return false;
}
int32_t AudioDeviceDummy::RecordingIsAvailable(bool& available) {
return -1;
}
int32_t AudioDeviceDummy::InitRecording() {
return -1;
}
bool AudioDeviceDummy::RecordingIsInitialized() const {
return false;
}
int32_t AudioDeviceDummy::StartPlayout() {
return -1;
}
int32_t AudioDeviceDummy::StopPlayout() {
return 0;
}
bool AudioDeviceDummy::Playing() const {
return false;
}
int32_t AudioDeviceDummy::StartRecording() {
return -1;
}
int32_t AudioDeviceDummy::StopRecording() {
return 0;
}
bool AudioDeviceDummy::Recording() const {
return false;
}
int32_t AudioDeviceDummy::InitSpeaker() {
return -1;
}
bool AudioDeviceDummy::SpeakerIsInitialized() const {
return false;
}
int32_t AudioDeviceDummy::InitMicrophone() {
return -1;
}
bool AudioDeviceDummy::MicrophoneIsInitialized() const {
return false;
}
int32_t AudioDeviceDummy::SpeakerVolumeIsAvailable(bool& available) {
return -1;
}
int32_t AudioDeviceDummy::SetSpeakerVolume(uint32_t volume) {
return -1;
}
int32_t AudioDeviceDummy::SpeakerVolume(uint32_t& volume) const {
return -1;
}
int32_t AudioDeviceDummy::MaxSpeakerVolume(uint32_t& maxVolume) const {
return -1;
}
int32_t AudioDeviceDummy::MinSpeakerVolume(uint32_t& minVolume) const {
return -1;
}
int32_t AudioDeviceDummy::MicrophoneVolumeIsAvailable(bool& available) {
return -1;
}
int32_t AudioDeviceDummy::SetMicrophoneVolume(uint32_t volume) {
return -1;
}
int32_t AudioDeviceDummy::MicrophoneVolume(uint32_t& volume) const {
return -1;
}
int32_t AudioDeviceDummy::MaxMicrophoneVolume(uint32_t& maxVolume) const {
return -1;
}
int32_t AudioDeviceDummy::MinMicrophoneVolume(uint32_t& minVolume) const {
return -1;
}
int32_t AudioDeviceDummy::SpeakerMuteIsAvailable(bool& available) {
return -1;
}
int32_t AudioDeviceDummy::SetSpeakerMute(bool enable) {
return -1;
}
int32_t AudioDeviceDummy::SpeakerMute(bool& enabled) const {
return -1;
}
int32_t AudioDeviceDummy::MicrophoneMuteIsAvailable(bool& available) {
return -1;
}
int32_t AudioDeviceDummy::SetMicrophoneMute(bool enable) {
return -1;
}
int32_t AudioDeviceDummy::MicrophoneMute(bool& enabled) const {
return -1;
}
int32_t AudioDeviceDummy::StereoPlayoutIsAvailable(bool& available) {
return -1;
}
int32_t AudioDeviceDummy::SetStereoPlayout(bool enable) {
return -1;
}
int32_t AudioDeviceDummy::StereoPlayout(bool& enabled) const {
return -1;
}
int32_t AudioDeviceDummy::StereoRecordingIsAvailable(bool& available) {
return -1;
}
int32_t AudioDeviceDummy::SetStereoRecording(bool enable) {
return -1;
}
int32_t AudioDeviceDummy::StereoRecording(bool& enabled) const {
return -1;
}
int32_t AudioDeviceDummy::PlayoutDelay(uint16_t& delayMS) const {
return -1;
}
void AudioDeviceDummy::AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) {}
} // namespace webrtc

View file

@ -0,0 +1,117 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef AUDIO_DEVICE_AUDIO_DEVICE_DUMMY_H_
#define AUDIO_DEVICE_AUDIO_DEVICE_DUMMY_H_
#include <stdint.h>
#include "modules/audio_device/audio_device_buffer.h"
#include "modules/audio_device/audio_device_generic.h"
#include "modules/audio_device/include/audio_device.h"
#include "modules/audio_device/include/audio_device_defines.h"
namespace webrtc {
class AudioDeviceDummy : public AudioDeviceGeneric {
public:
AudioDeviceDummy() {}
virtual ~AudioDeviceDummy() {}
// Retrieve the currently utilized audio layer
int32_t ActiveAudioLayer(
AudioDeviceModule::AudioLayer& audioLayer) const override;
// Main initializaton and termination
InitStatus Init() override;
int32_t Terminate() override;
bool Initialized() const override;
// Device enumeration
int16_t PlayoutDevices() override;
int16_t RecordingDevices() override;
int32_t PlayoutDeviceName(uint16_t index,
char name[kAdmMaxDeviceNameSize],
char guid[kAdmMaxGuidSize]) override;
int32_t RecordingDeviceName(uint16_t index,
char name[kAdmMaxDeviceNameSize],
char guid[kAdmMaxGuidSize]) override;
// Device selection
int32_t SetPlayoutDevice(uint16_t index) override;
int32_t SetPlayoutDevice(
AudioDeviceModule::WindowsDeviceType device) override;
int32_t SetRecordingDevice(uint16_t index) override;
int32_t SetRecordingDevice(
AudioDeviceModule::WindowsDeviceType device) override;
// Audio transport initialization
int32_t PlayoutIsAvailable(bool& available) override;
int32_t InitPlayout() override;
bool PlayoutIsInitialized() const override;
int32_t RecordingIsAvailable(bool& available) override;
int32_t InitRecording() override;
bool RecordingIsInitialized() const override;
// Audio transport control
int32_t StartPlayout() override;
int32_t StopPlayout() override;
bool Playing() const override;
int32_t StartRecording() override;
int32_t StopRecording() override;
bool Recording() const override;
// Audio mixer initialization
int32_t InitSpeaker() override;
bool SpeakerIsInitialized() const override;
int32_t InitMicrophone() override;
bool MicrophoneIsInitialized() const override;
// Speaker volume controls
int32_t SpeakerVolumeIsAvailable(bool& available) override;
int32_t SetSpeakerVolume(uint32_t volume) override;
int32_t SpeakerVolume(uint32_t& volume) const override;
int32_t MaxSpeakerVolume(uint32_t& maxVolume) const override;
int32_t MinSpeakerVolume(uint32_t& minVolume) const override;
// Microphone volume controls
int32_t MicrophoneVolumeIsAvailable(bool& available) override;
int32_t SetMicrophoneVolume(uint32_t volume) override;
int32_t MicrophoneVolume(uint32_t& volume) const override;
int32_t MaxMicrophoneVolume(uint32_t& maxVolume) const override;
int32_t MinMicrophoneVolume(uint32_t& minVolume) const override;
// Speaker mute control
int32_t SpeakerMuteIsAvailable(bool& available) override;
int32_t SetSpeakerMute(bool enable) override;
int32_t SpeakerMute(bool& enabled) const override;
// Microphone mute control
int32_t MicrophoneMuteIsAvailable(bool& available) override;
int32_t SetMicrophoneMute(bool enable) override;
int32_t MicrophoneMute(bool& enabled) const override;
// Stereo support
int32_t StereoPlayoutIsAvailable(bool& available) override;
int32_t SetStereoPlayout(bool enable) override;
int32_t StereoPlayout(bool& enabled) const override;
int32_t StereoRecordingIsAvailable(bool& available) override;
int32_t SetStereoRecording(bool enable) override;
int32_t StereoRecording(bool& enabled) const override;
// Delay information and control
int32_t PlayoutDelay(uint16_t& delayMS) const override;
void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) override;
};
} // namespace webrtc
#endif // AUDIO_DEVICE_AUDIO_DEVICE_DUMMY_H_

View file

@ -0,0 +1,508 @@
/*
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/audio_device/dummy/file_audio_device.h"
#include <string.h>
#include "absl/strings/string_view.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/platform_thread.h"
#include "rtc_base/time_utils.h"
#include "system_wrappers/include/sleep.h"
namespace webrtc {
const int kRecordingFixedSampleRate = 48000;
const size_t kRecordingNumChannels = 2;
const int kPlayoutFixedSampleRate = 48000;
const size_t kPlayoutNumChannels = 2;
const size_t kPlayoutBufferSize =
kPlayoutFixedSampleRate / 100 * kPlayoutNumChannels * 2;
const size_t kRecordingBufferSize =
kRecordingFixedSampleRate / 100 * kRecordingNumChannels * 2;
FileAudioDevice::FileAudioDevice(absl::string_view inputFilename,
absl::string_view outputFilename)
: _ptrAudioBuffer(NULL),
_recordingBuffer(NULL),
_playoutBuffer(NULL),
_recordingFramesLeft(0),
_playoutFramesLeft(0),
_recordingBufferSizeIn10MS(0),
_recordingFramesIn10MS(0),
_playoutFramesIn10MS(0),
_playing(false),
_recording(false),
_lastCallPlayoutMillis(0),
_lastCallRecordMillis(0),
_outputFilename(outputFilename),
_inputFilename(inputFilename) {}
FileAudioDevice::~FileAudioDevice() {}
int32_t FileAudioDevice::ActiveAudioLayer(
AudioDeviceModule::AudioLayer& audioLayer) const {
return -1;
}
AudioDeviceGeneric::InitStatus FileAudioDevice::Init() {
return InitStatus::OK;
}
int32_t FileAudioDevice::Terminate() {
return 0;
}
bool FileAudioDevice::Initialized() const {
return true;
}
int16_t FileAudioDevice::PlayoutDevices() {
return 1;
}
int16_t FileAudioDevice::RecordingDevices() {
return 1;
}
int32_t FileAudioDevice::PlayoutDeviceName(uint16_t index,
char name[kAdmMaxDeviceNameSize],
char guid[kAdmMaxGuidSize]) {
const char* kName = "dummy_device";
const char* kGuid = "dummy_device_unique_id";
if (index < 1) {
memset(name, 0, kAdmMaxDeviceNameSize);
memset(guid, 0, kAdmMaxGuidSize);
memcpy(name, kName, strlen(kName));
memcpy(guid, kGuid, strlen(guid));
return 0;
}
return -1;
}
int32_t FileAudioDevice::RecordingDeviceName(uint16_t index,
char name[kAdmMaxDeviceNameSize],
char guid[kAdmMaxGuidSize]) {
const char* kName = "dummy_device";
const char* kGuid = "dummy_device_unique_id";
if (index < 1) {
memset(name, 0, kAdmMaxDeviceNameSize);
memset(guid, 0, kAdmMaxGuidSize);
memcpy(name, kName, strlen(kName));
memcpy(guid, kGuid, strlen(guid));
return 0;
}
return -1;
}
int32_t FileAudioDevice::SetPlayoutDevice(uint16_t index) {
if (index == 0) {
_playout_index = index;
return 0;
}
return -1;
}
int32_t FileAudioDevice::SetPlayoutDevice(
AudioDeviceModule::WindowsDeviceType device) {
return -1;
}
int32_t FileAudioDevice::SetRecordingDevice(uint16_t index) {
if (index == 0) {
_record_index = index;
return _record_index;
}
return -1;
}
int32_t FileAudioDevice::SetRecordingDevice(
AudioDeviceModule::WindowsDeviceType device) {
return -1;
}
int32_t FileAudioDevice::PlayoutIsAvailable(bool& available) {
if (_playout_index == 0) {
available = true;
return _playout_index;
}
available = false;
return -1;
}
int32_t FileAudioDevice::InitPlayout() {
MutexLock lock(&mutex_);
if (_playing) {
return -1;
}
_playoutFramesIn10MS = static_cast<size_t>(kPlayoutFixedSampleRate / 100);
if (_ptrAudioBuffer) {
// Update webrtc audio buffer with the selected parameters
_ptrAudioBuffer->SetPlayoutSampleRate(kPlayoutFixedSampleRate);
_ptrAudioBuffer->SetPlayoutChannels(kPlayoutNumChannels);
}
return 0;
}
bool FileAudioDevice::PlayoutIsInitialized() const {
return _playoutFramesIn10MS != 0;
}
int32_t FileAudioDevice::RecordingIsAvailable(bool& available) {
if (_record_index == 0) {
available = true;
return _record_index;
}
available = false;
return -1;
}
int32_t FileAudioDevice::InitRecording() {
MutexLock lock(&mutex_);
if (_recording) {
return -1;
}
_recordingFramesIn10MS = static_cast<size_t>(kRecordingFixedSampleRate / 100);
if (_ptrAudioBuffer) {
_ptrAudioBuffer->SetRecordingSampleRate(kRecordingFixedSampleRate);
_ptrAudioBuffer->SetRecordingChannels(kRecordingNumChannels);
}
return 0;
}
bool FileAudioDevice::RecordingIsInitialized() const {
return _recordingFramesIn10MS != 0;
}
int32_t FileAudioDevice::StartPlayout() {
if (_playing) {
return 0;
}
_playing = true;
_playoutFramesLeft = 0;
if (!_playoutBuffer) {
_playoutBuffer = new int8_t[kPlayoutBufferSize];
}
if (!_playoutBuffer) {
_playing = false;
return -1;
}
// PLAYOUT
if (!_outputFilename.empty()) {
_outputFile = FileWrapper::OpenWriteOnly(_outputFilename);
if (!_outputFile.is_open()) {
RTC_LOG(LS_ERROR) << "Failed to open playout file: " << _outputFilename;
_playing = false;
delete[] _playoutBuffer;
_playoutBuffer = NULL;
return -1;
}
}
_ptrThreadPlay = rtc::PlatformThread::SpawnJoinable(
[this] {
while (PlayThreadProcess()) {
}
},
"webrtc_audio_module_play_thread",
rtc::ThreadAttributes().SetPriority(rtc::ThreadPriority::kRealtime));
RTC_LOG(LS_INFO) << "Started playout capture to output file: "
<< _outputFilename;
return 0;
}
int32_t FileAudioDevice::StopPlayout() {
{
MutexLock lock(&mutex_);
_playing = false;
}
// stop playout thread first
if (!_ptrThreadPlay.empty())
_ptrThreadPlay.Finalize();
MutexLock lock(&mutex_);
_playoutFramesLeft = 0;
delete[] _playoutBuffer;
_playoutBuffer = NULL;
_outputFile.Close();
RTC_LOG(LS_INFO) << "Stopped playout capture to output file: "
<< _outputFilename;
return 0;
}
bool FileAudioDevice::Playing() const {
return _playing;
}
int32_t FileAudioDevice::StartRecording() {
_recording = true;
// Make sure we only create the buffer once.
_recordingBufferSizeIn10MS =
_recordingFramesIn10MS * kRecordingNumChannels * 2;
if (!_recordingBuffer) {
_recordingBuffer = new int8_t[_recordingBufferSizeIn10MS];
}
if (!_inputFilename.empty()) {
_inputFile = FileWrapper::OpenReadOnly(_inputFilename);
if (!_inputFile.is_open()) {
RTC_LOG(LS_ERROR) << "Failed to open audio input file: "
<< _inputFilename;
_recording = false;
delete[] _recordingBuffer;
_recordingBuffer = NULL;
return -1;
}
}
_ptrThreadRec = rtc::PlatformThread::SpawnJoinable(
[this] {
while (RecThreadProcess()) {
}
},
"webrtc_audio_module_capture_thread",
rtc::ThreadAttributes().SetPriority(rtc::ThreadPriority::kRealtime));
RTC_LOG(LS_INFO) << "Started recording from input file: " << _inputFilename;
return 0;
}
int32_t FileAudioDevice::StopRecording() {
{
MutexLock lock(&mutex_);
_recording = false;
}
if (!_ptrThreadRec.empty())
_ptrThreadRec.Finalize();
MutexLock lock(&mutex_);
_recordingFramesLeft = 0;
if (_recordingBuffer) {
delete[] _recordingBuffer;
_recordingBuffer = NULL;
}
_inputFile.Close();
RTC_LOG(LS_INFO) << "Stopped recording from input file: " << _inputFilename;
return 0;
}
bool FileAudioDevice::Recording() const {
return _recording;
}
int32_t FileAudioDevice::InitSpeaker() {
return -1;
}
bool FileAudioDevice::SpeakerIsInitialized() const {
return false;
}
int32_t FileAudioDevice::InitMicrophone() {
return 0;
}
bool FileAudioDevice::MicrophoneIsInitialized() const {
return true;
}
int32_t FileAudioDevice::SpeakerVolumeIsAvailable(bool& available) {
return -1;
}
int32_t FileAudioDevice::SetSpeakerVolume(uint32_t volume) {
return -1;
}
int32_t FileAudioDevice::SpeakerVolume(uint32_t& volume) const {
return -1;
}
int32_t FileAudioDevice::MaxSpeakerVolume(uint32_t& maxVolume) const {
return -1;
}
int32_t FileAudioDevice::MinSpeakerVolume(uint32_t& minVolume) const {
return -1;
}
int32_t FileAudioDevice::MicrophoneVolumeIsAvailable(bool& available) {
return -1;
}
int32_t FileAudioDevice::SetMicrophoneVolume(uint32_t volume) {
return -1;
}
int32_t FileAudioDevice::MicrophoneVolume(uint32_t& volume) const {
return -1;
}
int32_t FileAudioDevice::MaxMicrophoneVolume(uint32_t& maxVolume) const {
return -1;
}
int32_t FileAudioDevice::MinMicrophoneVolume(uint32_t& minVolume) const {
return -1;
}
int32_t FileAudioDevice::SpeakerMuteIsAvailable(bool& available) {
return -1;
}
int32_t FileAudioDevice::SetSpeakerMute(bool enable) {
return -1;
}
int32_t FileAudioDevice::SpeakerMute(bool& enabled) const {
return -1;
}
int32_t FileAudioDevice::MicrophoneMuteIsAvailable(bool& available) {
return -1;
}
int32_t FileAudioDevice::SetMicrophoneMute(bool enable) {
return -1;
}
int32_t FileAudioDevice::MicrophoneMute(bool& enabled) const {
return -1;
}
int32_t FileAudioDevice::StereoPlayoutIsAvailable(bool& available) {
available = true;
return 0;
}
int32_t FileAudioDevice::SetStereoPlayout(bool enable) {
return 0;
}
int32_t FileAudioDevice::StereoPlayout(bool& enabled) const {
enabled = true;
return 0;
}
int32_t FileAudioDevice::StereoRecordingIsAvailable(bool& available) {
available = true;
return 0;
}
int32_t FileAudioDevice::SetStereoRecording(bool enable) {
return 0;
}
int32_t FileAudioDevice::StereoRecording(bool& enabled) const {
enabled = true;
return 0;
}
int32_t FileAudioDevice::PlayoutDelay(uint16_t& delayMS) const {
return 0;
}
void FileAudioDevice::AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) {
MutexLock lock(&mutex_);
_ptrAudioBuffer = audioBuffer;
// Inform the AudioBuffer about default settings for this implementation.
// Set all values to zero here since the actual settings will be done by
// InitPlayout and InitRecording later.
_ptrAudioBuffer->SetRecordingSampleRate(0);
_ptrAudioBuffer->SetPlayoutSampleRate(0);
_ptrAudioBuffer->SetRecordingChannels(0);
_ptrAudioBuffer->SetPlayoutChannels(0);
}
bool FileAudioDevice::PlayThreadProcess() {
if (!_playing) {
return false;
}
int64_t currentTime = rtc::TimeMillis();
mutex_.Lock();
if (_lastCallPlayoutMillis == 0 ||
currentTime - _lastCallPlayoutMillis >= 10) {
mutex_.Unlock();
_ptrAudioBuffer->RequestPlayoutData(_playoutFramesIn10MS);
mutex_.Lock();
_playoutFramesLeft = _ptrAudioBuffer->GetPlayoutData(_playoutBuffer);
RTC_DCHECK_EQ(_playoutFramesIn10MS, _playoutFramesLeft);
if (_outputFile.is_open()) {
_outputFile.Write(_playoutBuffer, kPlayoutBufferSize);
}
_lastCallPlayoutMillis = currentTime;
}
_playoutFramesLeft = 0;
mutex_.Unlock();
int64_t deltaTimeMillis = rtc::TimeMillis() - currentTime;
if (deltaTimeMillis < 10) {
SleepMs(10 - deltaTimeMillis);
}
return true;
}
bool FileAudioDevice::RecThreadProcess() {
if (!_recording) {
return false;
}
int64_t currentTime = rtc::TimeMillis();
mutex_.Lock();
if (_lastCallRecordMillis == 0 || currentTime - _lastCallRecordMillis >= 10) {
if (_inputFile.is_open()) {
if (_inputFile.Read(_recordingBuffer, kRecordingBufferSize) > 0) {
_ptrAudioBuffer->SetRecordedBuffer(_recordingBuffer,
_recordingFramesIn10MS);
} else {
_inputFile.Rewind();
}
_lastCallRecordMillis = currentTime;
mutex_.Unlock();
_ptrAudioBuffer->DeliverRecordedData();
mutex_.Lock();
}
}
mutex_.Unlock();
int64_t deltaTimeMillis = rtc::TimeMillis() - currentTime;
if (deltaTimeMillis < 10) {
SleepMs(10 - deltaTimeMillis);
}
return true;
}
} // namespace webrtc

View file

@ -0,0 +1,163 @@
/*
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef AUDIO_DEVICE_FILE_AUDIO_DEVICE_H_
#define AUDIO_DEVICE_FILE_AUDIO_DEVICE_H_
#include <stdio.h>
#include <memory>
#include <string>
#include "absl/strings/string_view.h"
#include "modules/audio_device/audio_device_generic.h"
#include "rtc_base/platform_thread.h"
#include "rtc_base/synchronization/mutex.h"
#include "rtc_base/system/file_wrapper.h"
#include "rtc_base/time_utils.h"
namespace webrtc {
// This is a fake audio device which plays audio from a file as its microphone
// and plays out into a file.
class FileAudioDevice : public AudioDeviceGeneric {
public:
// Constructs a file audio device with `id`. It will read audio from
// `inputFilename` and record output audio to `outputFilename`.
//
// The input file should be a readable 48k stereo raw file, and the output
// file should point to a writable location. The output format will also be
// 48k stereo raw audio.
FileAudioDevice(absl::string_view inputFilename,
absl::string_view outputFilename);
virtual ~FileAudioDevice();
// Retrieve the currently utilized audio layer
int32_t ActiveAudioLayer(
AudioDeviceModule::AudioLayer& audioLayer) const override;
// Main initializaton and termination
InitStatus Init() override;
int32_t Terminate() override;
bool Initialized() const override;
// Device enumeration
int16_t PlayoutDevices() override;
int16_t RecordingDevices() override;
int32_t PlayoutDeviceName(uint16_t index,
char name[kAdmMaxDeviceNameSize],
char guid[kAdmMaxGuidSize]) override;
int32_t RecordingDeviceName(uint16_t index,
char name[kAdmMaxDeviceNameSize],
char guid[kAdmMaxGuidSize]) override;
// Device selection
int32_t SetPlayoutDevice(uint16_t index) override;
int32_t SetPlayoutDevice(
AudioDeviceModule::WindowsDeviceType device) override;
int32_t SetRecordingDevice(uint16_t index) override;
int32_t SetRecordingDevice(
AudioDeviceModule::WindowsDeviceType device) override;
// Audio transport initialization
int32_t PlayoutIsAvailable(bool& available) override;
int32_t InitPlayout() override;
bool PlayoutIsInitialized() const override;
int32_t RecordingIsAvailable(bool& available) override;
int32_t InitRecording() override;
bool RecordingIsInitialized() const override;
// Audio transport control
int32_t StartPlayout() override;
int32_t StopPlayout() override;
bool Playing() const override;
int32_t StartRecording() override;
int32_t StopRecording() override;
bool Recording() const override;
// Audio mixer initialization
int32_t InitSpeaker() override;
bool SpeakerIsInitialized() const override;
int32_t InitMicrophone() override;
bool MicrophoneIsInitialized() const override;
// Speaker volume controls
int32_t SpeakerVolumeIsAvailable(bool& available) override;
int32_t SetSpeakerVolume(uint32_t volume) override;
int32_t SpeakerVolume(uint32_t& volume) const override;
int32_t MaxSpeakerVolume(uint32_t& maxVolume) const override;
int32_t MinSpeakerVolume(uint32_t& minVolume) const override;
// Microphone volume controls
int32_t MicrophoneVolumeIsAvailable(bool& available) override;
int32_t SetMicrophoneVolume(uint32_t volume) override;
int32_t MicrophoneVolume(uint32_t& volume) const override;
int32_t MaxMicrophoneVolume(uint32_t& maxVolume) const override;
int32_t MinMicrophoneVolume(uint32_t& minVolume) const override;
// Speaker mute control
int32_t SpeakerMuteIsAvailable(bool& available) override;
int32_t SetSpeakerMute(bool enable) override;
int32_t SpeakerMute(bool& enabled) const override;
// Microphone mute control
int32_t MicrophoneMuteIsAvailable(bool& available) override;
int32_t SetMicrophoneMute(bool enable) override;
int32_t MicrophoneMute(bool& enabled) const override;
// Stereo support
int32_t StereoPlayoutIsAvailable(bool& available) override;
int32_t SetStereoPlayout(bool enable) override;
int32_t StereoPlayout(bool& enabled) const override;
int32_t StereoRecordingIsAvailable(bool& available) override;
int32_t SetStereoRecording(bool enable) override;
int32_t StereoRecording(bool& enabled) const override;
// Delay information and control
int32_t PlayoutDelay(uint16_t& delayMS) const override;
void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) override;
private:
static void RecThreadFunc(void*);
static void PlayThreadFunc(void*);
bool RecThreadProcess();
bool PlayThreadProcess();
int32_t _playout_index;
int32_t _record_index;
AudioDeviceBuffer* _ptrAudioBuffer;
int8_t* _recordingBuffer; // In bytes.
int8_t* _playoutBuffer; // In bytes.
uint32_t _recordingFramesLeft;
uint32_t _playoutFramesLeft;
Mutex mutex_;
size_t _recordingBufferSizeIn10MS;
size_t _recordingFramesIn10MS;
size_t _playoutFramesIn10MS;
rtc::PlatformThread _ptrThreadRec;
rtc::PlatformThread _ptrThreadPlay;
bool _playing;
bool _recording;
int64_t _lastCallPlayoutMillis;
int64_t _lastCallRecordMillis;
FileWrapper _outputFile;
FileWrapper _inputFile;
std::string _outputFilename;
std::string _inputFilename;
};
} // namespace webrtc
#endif // AUDIO_DEVICE_FILE_AUDIO_DEVICE_H_

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/audio_device/dummy/file_audio_device_factory.h"
#include <stdio.h>
#include <cstdlib>
#include "absl/strings/string_view.h"
#include "modules/audio_device/dummy/file_audio_device.h"
#include "rtc_base/logging.h"
#include "rtc_base/string_utils.h"
namespace webrtc {
bool FileAudioDeviceFactory::_isConfigured = false;
char FileAudioDeviceFactory::_inputAudioFilename[MAX_FILENAME_LEN] = "";
char FileAudioDeviceFactory::_outputAudioFilename[MAX_FILENAME_LEN] = "";
FileAudioDevice* FileAudioDeviceFactory::CreateFileAudioDevice() {
// Bail out here if the files haven't been set explicitly.
// audio_device_impl.cc should then fall back to dummy audio.
if (!_isConfigured) {
RTC_LOG(LS_WARNING)
<< "WebRTC configured with WEBRTC_DUMMY_FILE_DEVICES but "
"no device files supplied. Will fall back to dummy "
"audio.";
return nullptr;
}
return new FileAudioDevice(_inputAudioFilename, _outputAudioFilename);
}
void FileAudioDeviceFactory::SetFilenamesToUse(
absl::string_view inputAudioFilename,
absl::string_view outputAudioFilename) {
#ifdef WEBRTC_DUMMY_FILE_DEVICES
RTC_DCHECK_LT(inputAudioFilename.size(), MAX_FILENAME_LEN);
RTC_DCHECK_LT(outputAudioFilename.size(), MAX_FILENAME_LEN);
// Copy the strings since we don't know the lifetime of the input pointers.
rtc::strcpyn(_inputAudioFilename, MAX_FILENAME_LEN, inputAudioFilename);
rtc::strcpyn(_outputAudioFilename, MAX_FILENAME_LEN, outputAudioFilename);
_isConfigured = true;
#else
// Sanity: must be compiled with the right define to run this.
printf(
"Trying to use dummy file devices, but is not compiled "
"with WEBRTC_DUMMY_FILE_DEVICES. Bailing out.\n");
std::exit(1);
#endif
}
} // namespace webrtc

View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef AUDIO_DEVICE_FILE_AUDIO_DEVICE_FACTORY_H_
#define AUDIO_DEVICE_FILE_AUDIO_DEVICE_FACTORY_H_
#include <stdint.h>
#include "absl/strings/string_view.h"
namespace webrtc {
class FileAudioDevice;
// This class is used by audio_device_impl.cc when WebRTC is compiled with
// WEBRTC_DUMMY_FILE_DEVICES. The application must include this file and set the
// filenames to use before the audio device module is initialized. This is
// intended for test tools which use the audio device module.
class FileAudioDeviceFactory {
public:
static FileAudioDevice* CreateFileAudioDevice();
// The input file must be a readable 48k stereo raw file. The output
// file must be writable. The strings will be copied.
static void SetFilenamesToUse(absl::string_view inputAudioFilename,
absl::string_view outputAudioFilename);
private:
enum : uint32_t { MAX_FILENAME_LEN = 512 };
static bool _isConfigured;
static char _inputAudioFilename[MAX_FILENAME_LEN];
static char _outputAudioFilename[MAX_FILENAME_LEN];
};
} // namespace webrtc
#endif // AUDIO_DEVICE_FILE_AUDIO_DEVICE_FACTORY_H_