#include "Audio_Null.h" #include "helper/HL_Log.h" #include #include #define LOG_SUBSYSTEM "audio" using namespace Audio; using namespace std::chrono_literals; NullTimer::NullTimer(std::chrono::milliseconds interval, Delegate *delegate, const char* name) :mShutdown(false), mDelegate(delegate), mInterval(interval), mThreadName(name) { start(); } NullTimer::~NullTimer() { stop(); } void NullTimer::start() { mShutdown = false; mWorkerThread = std::thread(&NullTimer::run, this); } void NullTimer::stop() { mShutdown = true; if (mWorkerThread.joinable()) mWorkerThread.join(); } void NullTimer::run() { mTail = 0us; while (!mShutdown) { // Get current timestamp std::chrono::system_clock::time_point timestamp = std::chrono::system_clock::now(); while (mTail >= mInterval) { if (mDelegate) mDelegate->onTimerSignal(*this); mTail -= mInterval; } // Sleep for mInterval - mTail milliseconds std::this_thread::sleep_for(mInterval - mTail); mTail = mTail + std::chrono::duration_cast(std::chrono::system_clock::now() - timestamp); } } // --------------------- NullInputDevice ------------------------- NullInputDevice::NullInputDevice() :mBuffer(nullptr) { } NullInputDevice::~NullInputDevice() { internalClose(); } bool NullInputDevice::open() { ICELogInfo(<< "Starting NullInputDevice for " << AUDIO_MIC_BUFFER_LENGTH << "ms buffers"); mBuffer = malloc(AUDIO_MIC_BUFFER_SIZE); memset(mBuffer, 0, AUDIO_MIC_BUFFER_SIZE); mTimeCounter = 0; mDataCounter = 0; // Creation of timer starts it also. So first onTimerSignal can come even before open() returns. mTimer = std::make_shared(std::chrono::milliseconds(AUDIO_MIC_BUFFER_LENGTH), this, "null_mic"); return true; } void NullInputDevice::internalClose() { ICELogInfo(<< "Stopping NullInputDevice"); mTimer.reset(); if (mBuffer) { free(mBuffer); mBuffer = nullptr; } ICELogInfo( << "Pseudocaptured " << mTimeCounter << " milliseconds , " << mDataCounter << " bytes."); } void NullInputDevice::close() { internalClose(); } Format NullInputDevice::getFormat() { assert (Format().sizeFromTime(AUDIO_MIC_BUFFER_LENGTH) == AUDIO_MIC_BUFFER_SIZE); return {}; // Return library-define default format } void NullInputDevice::onTimerSignal(NullTimer& timer) { mTimeCounter += AUDIO_MIC_BUFFER_LENGTH; mDataCounter += AUDIO_MIC_BUFFER_SIZE; if (mConnection) mConnection->onMicData(getFormat(), mBuffer, AUDIO_MIC_BUFFER_SIZE); } // --------------------- NullOutputDevice -------------------------- NullOutputDevice::NullOutputDevice() :mBuffer(nullptr) { } NullOutputDevice::~NullOutputDevice() { internalClose(); } bool NullOutputDevice::open() { mTimeCounter = 0; mDataCounter = 0; mBuffer = malloc(AUDIO_SPK_BUFFER_SIZE); // Creation of timer starts it also. So first onSpkData() can come before open() returns even. mTimer = std::make_shared(std::chrono::milliseconds(AUDIO_SPK_BUFFER_LENGTH), this, "null_spk"); return true; } void NullOutputDevice::internalClose() { mTimer.reset(); free(mBuffer); mBuffer = nullptr; ICELogInfo(<< "Pseudoplayed " << mTimeCounter << " milliseconds, " << mDataCounter << " bytes."); } void NullOutputDevice::close() { internalClose(); } Format NullOutputDevice::getFormat() { assert (Format().sizeFromTime(AUDIO_SPK_BUFFER_LENGTH) == AUDIO_SPK_BUFFER_SIZE); return Format(); } void NullOutputDevice::onTimerSignal(NullTimer &timer) { mTimeCounter += AUDIO_SPK_BUFFER_LENGTH; mDataCounter += AUDIO_SPK_BUFFER_SIZE; if (mConnection) mConnection->onSpkData(getFormat(), mBuffer, AUDIO_SPK_BUFFER_SIZE); } // ---------------------- NullEnumerator -------------------------- NullEnumerator::NullEnumerator() {} NullEnumerator::~NullEnumerator() {} void NullEnumerator::open(int direction) {} void NullEnumerator::close() {} int NullEnumerator::count() { return 1; } std::tstring NullEnumerator::nameAt(int index) { #if defined(TARGET_WIN) return L"null"; #else return "null"; #endif } int NullEnumerator::idAt(int index) { return 0; } int NullEnumerator::indexOfDefaultDevice() { return 0; }