Repo created
This commit is contained in:
parent
81b91f4139
commit
f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
Loading…
Add table
Add a link
Reference in a new issue