- clang format + naming improved

This commit is contained in:
2026-09-03 10:03:42 +03:00
parent 249e614def
commit e166bae1ea
204 changed files with 20621 additions and 21019 deletions
+6 -10
View File
@@ -9,14 +9,13 @@
#include "HL_String.h"
#if defined(TARGET_ANDROID)
# include "../engine/audio/Audio_Android.h"
#include "../engine/audio/Audio_Android.h"
#endif
#define LOG_SUBSYSTEM "audio"
AudioManager::AudioManager()
:mTerminal(nullptr), mAudioMonitoring(nullptr)
AudioManager::AudioManager() : mTerminal(nullptr), mAudioMonitoring(nullptr)
{
mPlayer.setDelegate(this);
}
@@ -92,7 +91,7 @@ void AudioManager::start(int usageId)
if (!mAudioOutput)
{
Audio::Enumerator *enumerator = Audio::Enumerator::make(usageId == atNull);
Audio::Enumerator* enumerator = Audio::Enumerator::make(usageId == atNull);
enumerator->open(Audio::mySpeaker);
int outputIndex = enumerator->indexOfDefaultDevice();
@@ -102,8 +101,7 @@ void AudioManager::start(int usageId)
if (outputIndex >= enumerator->count())
outputIndex = 0;
mAudioOutput = Audio::POutputDevice(
Audio::OutputDevice::make(enumerator->idAt(outputIndex)));
mAudioOutput = Audio::POutputDevice(Audio::OutputDevice::make(enumerator->idAt(outputIndex)));
}
else
mAudioOutput = Audio::POutputDevice(new Audio::NullOutputDevice());
@@ -139,7 +137,7 @@ void AudioManager::stop(int usageId)
{
LOCK_MANAGER;
ICELogInfo( << "Stop main audio with usage id " << usageId);
ICELogInfo(<< "Stop main audio with usage id " << usageId);
if (mTerminal)
{
if (mTerminal->audio())
@@ -196,9 +194,7 @@ void AudioManager::stopPlayFile(int usageId)
mPlayer.release(usageId);
}
void AudioManager::onFilePlayed(Audio::Player::PlaylistItem& item)
{
}
void AudioManager::onFilePlayed(Audio::Player::PlaylistItem& item) {}
void AudioManager::process()
{
+1 -2
View File
@@ -11,7 +11,6 @@
#include "../engine/media/MT_Box.h"
enum
{
AudioPrefix_Ring = 1,
@@ -31,7 +30,7 @@ enum
#define AudioSessionCoeff 64
class AudioManager: public Audio::Player::EndOfAudioDelegate
class AudioManager : public Audio::Player::EndOfAudioDelegate
{
public:
AudioManager();
+59 -70
View File
@@ -21,8 +21,7 @@ const std::string Status_NoAudioManager = "no audio manager";
#define LOG_SUBSYSTEM "agent"
AgentImpl::AgentImpl()
:mShutdown(false), mEventListChangeCondVar()
AgentImpl::AgentImpl() : mShutdown(false), mEventListChangeCondVar()
{
#if defined(TARGET_ANDROID) || defined(TARGET_WIN)
ice::GLogger.useDebugWindow(true);
@@ -84,76 +83,59 @@ std::string AgentImpl::command(const std::string& command)
}
if (cmd == "config")
processConfig(d, answer);
else
if (cmd == "start")
else if (cmd == "start")
processStart(d, answer);
else
if (cmd == "stop")
else if (cmd == "stop")
processStop(d, answer);
else
if (cmd == "account_create")
else if (cmd == "account_create")
processCreateAccount(d, answer);
else
if (cmd == "account_start")
else if (cmd == "account_start")
processStartAccount(d, answer);
else
if (cmd == "account_setuserinfo")
else if (cmd == "account_setuserinfo")
processSetUserInfoToAccount(d, answer);
else
if (cmd == "session_create") {
else if (cmd == "session_create")
{
// For Bugsnag test
// int* v = nullptr;
// *v = 0;
processCreateSession(d, answer);
}
else
if (cmd == "session_start")
else if (cmd == "session_start")
processStartSession(d, answer);
else
if (cmd == "session_stop")
else if (cmd == "session_stop")
processStopSession(d, answer);
else
if (cmd == "session_accept")
else if (cmd == "session_accept")
processAcceptSession(d, answer);
else
if (cmd == "session_destroy")
else if (cmd == "session_destroy")
processDestroySession(d, answer);
else
if (cmd == "session_use_stream")
else if (cmd == "session_use_stream")
processUseStreamForSession(d, answer);
else
if (cmd == "wait_for_event")
else if (cmd == "wait_for_event")
processWaitForEvent(d, answer);
else
if (cmd == "session_get_media_stats")
else if (cmd == "session_get_media_stats")
processGetMediaStats(d, answer);
else
if (cmd == "agent_network_changed")
else if (cmd == "agent_network_changed")
processNetworkChanged(d, answer);
else
if (cmd == "agent_add_root_cert")
else if (cmd == "agent_add_root_cert")
processAddRootCert(d, answer);
else
if (cmd == "detach_log")
else if (cmd == "detach_log")
{
GLogger.closeFile();
answer["status"] = Status_Ok;
}
else
if (cmd == "attach_log")
else if (cmd == "attach_log")
{
GLogger.openFile();
answer["status"] = Status_Ok;
}
else
if (cmd == "log_message")
else if (cmd == "log_message")
processLogMessage(d, answer);
else
{
answer["status"] = Status_NoCommand;
}
}
catch(std::exception& e)
catch (std::exception& e)
{
answer["status"] = e.what();
}
@@ -172,12 +154,15 @@ std::string AgentImpl::read()
return "";
}
void AgentImpl::processConfig(JsonCpp::Value &d, JsonCpp::Value &answer)
void AgentImpl::processConfig(JsonCpp::Value& d, JsonCpp::Value& answer)
{
std::unique_lock<std::recursive_mutex> l(mAgentMutex);
std::string transport = d["transport"].asString();
config()[CONFIG_TRANSPORT] = (transport == "any") ? TransportType_Any : (transport == "udp" ? TransportType_Udp : (transport == "tcp" ? TransportType_Tcp : TransportType_Tls));
config()[CONFIG_TRANSPORT] =
(transport == "any")
? TransportType_Any
: (transport == "udp" ? TransportType_Udp : (transport == "tcp" ? TransportType_Tcp : TransportType_Tls));
config()[CONFIG_IPV4] = d["ipv4"].asBool();
config()[CONFIG_IPV6] = d["ipv6"].asBool();
@@ -199,7 +184,7 @@ void AgentImpl::processConfig(JsonCpp::Value &d, JsonCpp::Value &answer)
answer["status"] = Status_Ok;
}
void AgentImpl::processStart(JsonCpp::Value& request, JsonCpp::Value &answer)
void AgentImpl::processStart(JsonCpp::Value& request, JsonCpp::Value& answer)
{
std::unique_lock<std::recursive_mutex> l(mAgentMutex);
if (mThread)
@@ -222,7 +207,7 @@ void AgentImpl::processStart(JsonCpp::Value& request, JsonCpp::Value &answer)
// Enable/disable codecs
PVariantMap priorityConfig = std::make_shared<VariantMap>();
MT::CodecList& cl = mTerminal->codeclist();
for (int i=0; i<cl.count(); i++)
for (int i = 0; i < cl.count(); i++)
priorityConfig->at(i) = i;
config()[CONFIG_CODEC_PRIORITY] = priorityConfig;
@@ -250,7 +235,7 @@ void AgentImpl::processStop(JsonCpp::Value& /*request*/, JsonCpp::Value& answer)
answer["status"] = Status_Ok;
}
void AgentImpl::processCreateAccount(JsonCpp::Value &d, JsonCpp::Value& answer)
void AgentImpl::processCreateAccount(JsonCpp::Value& d, JsonCpp::Value& answer)
{
std::unique_lock<std::recursive_mutex> l(mAgentMutex);
PVariantMap c = std::make_shared<VariantMap>();
@@ -286,7 +271,7 @@ void AgentImpl::processStartAccount(JsonCpp::Value& request, JsonCpp::Value& ans
answer["status"] = Status_AccountNotFound;
}
void AgentImpl::processSetUserInfoToAccount(JsonCpp::Value &request, JsonCpp::Value &answer)
void AgentImpl::processSetUserInfoToAccount(JsonCpp::Value& request, JsonCpp::Value& answer)
{
std::unique_lock<std::recursive_mutex> l(mAgentMutex);
// Locate account in map
@@ -296,7 +281,7 @@ void AgentImpl::processSetUserInfoToAccount(JsonCpp::Value &request, JsonCpp::Va
Account::UserInfo info;
JsonCpp::Value& arg = request["userinfo"];
std::vector<std::string> keys = arg.getMemberNames();
for (const std::string& k: keys)
for (const std::string& k : keys)
info[k] = arg[k].asString();
accountIter->second->setUserInfo(info);
@@ -306,7 +291,7 @@ void AgentImpl::processSetUserInfoToAccount(JsonCpp::Value &request, JsonCpp::Va
answer["status"] = Status_AccountNotFound;
}
void AgentImpl::processCreateSession(JsonCpp::Value &request, JsonCpp::Value &answer)
void AgentImpl::processCreateSession(JsonCpp::Value& request, JsonCpp::Value& answer)
{
std::unique_lock<std::recursive_mutex> l(mAgentMutex);
auto accountIter = mAccountMap.find(request["account_id"].asInt());
@@ -347,7 +332,8 @@ void AgentImpl::processStartSession(JsonCpp::Value& request, JsonCpp::Value& ans
// Ensure audio provider is here
PSession session = sessionIter->second;
PDataProvider audioProvider = std::make_shared<AudioProvider>(*this, *mTerminal);
audioProvider->setState(audioProvider->state() | static_cast<int>(StreamState::Grabbing) | static_cast<int>(StreamState::Playing));
audioProvider->setState(audioProvider->state() | static_cast<int>(StreamState::Grabbing) |
static_cast<int>(StreamState::Playing));
/*#if defined(USE_AQUA_LIBRARY)
std::string path_faults = request["path_faults"].asString();
@@ -372,7 +358,8 @@ void AgentImpl::processStartSession(JsonCpp::Value& request, JsonCpp::Value& ans
{ "specp", "32"}
};
// std::string config = "-avlp on -smtnrm on -decor off -mprio off -npnt auto -voip off -enorm off -g711 on -spfrcor off -grad off -tmc on -miter 1 -trim a 10 -output json";
// std::string config = "-avlp on -smtnrm on -decor off -mprio off -npnt auto -voip off -enorm off -g711 on
-spfrcor off -grad off -tmc on -miter 1 -trim a 10 -output json";
// if (temp_path.size())
// config += " -fau " + temp_path;
@@ -395,7 +382,7 @@ void AgentImpl::processStartSession(JsonCpp::Value& request, JsonCpp::Value& ans
Session::UserHeaders info;
JsonCpp::Value& arg = request["userinfo"];
std::vector<std::string> keys = arg.getMemberNames();
for (const std::string& k: keys)
for (const std::string& k : keys)
info[k] = arg[k].asString();
session->setUserHeaders(info);
@@ -451,7 +438,7 @@ void AgentImpl::processAcceptSession(JsonCpp::Value& request, JsonCpp::Value& an
Session::UserHeaders info;
JsonCpp::Value& arg = request["userinfo"];
std::vector<std::string> keys = arg.getMemberNames();
for (const std::string& k: keys)
for (const std::string& k : keys)
info[k] = arg[k].asString();
session->setUserHeaders(info);
@@ -473,13 +460,13 @@ void AgentImpl::processDestroySession(JsonCpp::Value& request, JsonCpp::Value& a
auto sessionIter = mSessionMap.find(sessionId);
if (sessionIter != mSessionMap.end())
mSessionMap.erase(sessionIter);
//#if defined(USE_AQUA_LIBRARY)
// #if defined(USE_AQUA_LIBRARY)
// closeAqua(sessionId);
//#endif
// #endif
answer["status"] = Status_Ok;
}
void AgentImpl::processWaitForEvent(JsonCpp::Value &request, JsonCpp::Value &answer)
void AgentImpl::processWaitForEvent(JsonCpp::Value& request, JsonCpp::Value& answer)
{
// Deliberately does NOT take mAgentMutex: events are produced by the worker
// thread inside process(), which needs mAgentMutex. Holding it here would
@@ -512,8 +499,7 @@ void AgentImpl::processGetMediaStats(JsonCpp::Value& request, JsonCpp::Value& an
{
PSession session = sessionIter->second;
VariantMap result;
session->getSessionInfo(Session::InfoOptions::Detailed,
result);
session->getSessionInfo(Session::InfoOptions::Detailed, result);
if (result.exists(SessionInfo_AudioCodec))
answer["codec"] = result[SessionInfo_AudioCodec].asStdString();
@@ -566,11 +552,13 @@ void AgentImpl::processAddRootCert(JsonCpp::Value& request, JsonCpp::Value& answ
std::string pem = request["cert"].asString();
std::string::size_type pb = 0, pe = 0;
while (pb != std::string::npos && pe != std::string::npos) {
while (pb != std::string::npos && pe != std::string::npos)
{
pb = pem.find(BeginCertificate, pb);
pe = pem.find(EndCertificate, pe);
if (pb != std::string::npos && pe != std::string::npos && pe > pb) {
if (pb != std::string::npos && pe != std::string::npos && pe > pb)
{
std::string cert = pem.substr(pb, pe - pb + EndCertificate.size());
addRootCert(ByteBuffer(cert.c_str(), cert.size()));
@@ -581,7 +569,7 @@ void AgentImpl::processAddRootCert(JsonCpp::Value& request, JsonCpp::Value& answ
answer["status"] = Status_Ok;
}
void AgentImpl::processLogMessage(JsonCpp::Value &request, JsonCpp::Value &answer)
void AgentImpl::processLogMessage(JsonCpp::Value& request, JsonCpp::Value& answer)
{
int level = request["level"].asInt();
std::string message = request["message"].asString();
@@ -600,7 +588,8 @@ void AgentImpl::stopAgentAndThread()
stop();
}
catch (...)
{}
{
}
// Stop worker thread
if (mThread)
@@ -644,8 +633,8 @@ void AgentImpl::processUseStreamForSession(JsonCpp::Value& request, JsonCpp::Val
std::string actionText = request["media_action"].asString(),
directionText = request["media_direction"].asString();
MT::Stream::MediaDirection direction = directionText == "incoming" ? MT::Stream::MediaDirection::Incoming
: MT::Stream::MediaDirection::Outgoing;
MT::Stream::MediaDirection direction =
directionText == "incoming" ? MT::Stream::MediaDirection::Incoming : MT::Stream::MediaDirection::Outgoing;
std::string path = request["path"].asString();
// Try to open file
@@ -672,8 +661,7 @@ void AgentImpl::processUseStreamForSession(JsonCpp::Value& request, JsonCpp::Val
}
}
}
else
if (actionText == "write")
else if (actionText == "write")
{
if (path.empty())
{
@@ -693,8 +681,7 @@ void AgentImpl::processUseStreamForSession(JsonCpp::Value& request, JsonCpp::Val
}
}
}
else
if (actionText == "mirror")
else if (actionText == "mirror")
{
prov->setupMirror(request["enable"].asBool());
answer["status"] = Status_Ok;
@@ -707,7 +694,8 @@ void AgentImpl::processUseStreamForSession(JsonCpp::Value& request, JsonCpp::Val
}
}
void AgentImpl::onMedia(const void* data, int length, MT::Stream::MediaDirection direction, void* context, void* userTag)
void AgentImpl::onMedia(const void* data, int length, MT::Stream::MediaDirection direction, void* context,
void* userTag)
{
/*switch (direction)
{
@@ -718,7 +706,9 @@ void AgentImpl::onMedia(const void* data, int length, MT::Stream::MediaDirection
// Called on new incoming session; providers shoukld
#define EVENT_WITH_NAME(X) JsonCpp::Value v; v["event_name"] = X;
#define EVENT_WITH_NAME(X) \
JsonCpp::Value v; \
v["event_name"] = X;
PDataProvider AgentImpl::onProviderNeeded(const std::string& name)
{
@@ -856,8 +846,7 @@ void AgentImpl::onCheckFinished(PSession s, const char* description)
}
// Called when log message must be recorded
void AgentImpl::onLog(const char* /*msg*/)
{}
void AgentImpl::onLog(const char* /*msg*/) {}
// Called when problem with SIP connection(s) detected
void AgentImpl::onSipConnectionFailed()
+3 -2
View File
@@ -16,7 +16,7 @@
#include <atomic>
class AgentImpl: public UserAgent, public MT::Stream::MediaObserver
class AgentImpl : public UserAgent, public MT::Stream::MediaObserver
{
protected:
std::recursive_mutex mAgentMutex;
@@ -123,7 +123,8 @@ public:
void onSipConnectionFailed() override;
// Called on incoming & outgoing audio for voice sessions
void onMedia(const void* data, int length, MT::Stream::MediaDirection direction, void* context, void* userTag) override;
void onMedia(const void* data, int length, MT::Stream::MediaDirection direction, void* context,
void* userTag) override;
};
#endif
+4 -15
View File
@@ -1,27 +1,16 @@
#include "Agent_Interface.h"
#include "Agent_Impl.h"
Agent::Agent()
:mContext(new AgentImpl());
Agent::Agent() : mContext(new AgentImpl());
{
}
Agent::~Agent()
{
Agent::~Agent() {}
}
void Agent::write(const std::string& command)
{
}
void Agent::write(const std::string& command) {}
bool Agent::waitForData(int milliseconds)
{
return false;
}
std::string Agent::read()
{
}
std::string Agent::read() {}
+87 -93
View File
@@ -14,11 +14,9 @@ using namespace Audio;
// -------------------- AndroidEnumerator -----------------------------
AndroidEnumerator::AndroidEnumerator()
{}
AndroidEnumerator::AndroidEnumerator() {}
AndroidEnumerator::~AndroidEnumerator()
{}
AndroidEnumerator::~AndroidEnumerator() {}
int AndroidEnumerator::indexOfDefaultDevice()
{
@@ -40,26 +38,21 @@ std::string AndroidEnumerator::nameAt(int index)
return "Audio";
}
void AndroidEnumerator::open(int direction)
{}
void AndroidEnumerator::open(int direction) {}
void AndroidEnumerator::close()
{}
void AndroidEnumerator::close() {}
// -----------------------
OpenSLEngine::OpenSLEngine()
{}
OpenSLEngine::OpenSLEngine() {}
OpenSLEngine::~OpenSLEngine()
{}
OpenSLEngine::~OpenSLEngine() {}
void OpenSLEngine::open()
{
std::unique_lock<std::mutex> l(mMutex);
if (++mUsageCounter == 1)
internalOpen();
}
void OpenSLEngine::close()
@@ -72,7 +65,9 @@ void OpenSLEngine::close()
internalClose();
}
#define CHECK_OPENSLES_ERROR if (resultCode != SL_RESULT_SUCCESS) throw Exception(ERR_OPENSLES, (int)resultCode)
#define CHECK_OPENSLES_ERROR \
if (resultCode != SL_RESULT_SUCCESS) \
throw Exception(ERR_OPENSLES, (int)resultCode)
void OpenSLEngine::internalOpen()
{
@@ -118,25 +113,15 @@ OpenSLEngine& OpenSLEngine::instance()
}
// --------------- Input implementation ----------------
AndroidInputDevice::AndroidInputDevice(int devId)
{}
AndroidInputDevice::AndroidInputDevice(int devId) {}
AndroidInputDevice::~AndroidInputDevice()
{}
AndroidInputDevice::~AndroidInputDevice() {}
static int RateToProbe[12][2] = {
{ SL_SAMPLINGRATE_16, 16000 },
{ SL_SAMPLINGRATE_8, 8000 },
{ SL_SAMPLINGRATE_32, 32000 },
{ SL_SAMPLINGRATE_44_1, 44100 },
{ SL_SAMPLINGRATE_11_025, 10025 },
{ SL_SAMPLINGRATE_22_05, 22050 },
{ SL_SAMPLINGRATE_24, 24000 },
{ SL_SAMPLINGRATE_48, 48000 },
{ SL_SAMPLINGRATE_64, 64000 },
{ SL_SAMPLINGRATE_88_2, 88200 },
{ SL_SAMPLINGRATE_96, 96000 },
{ SL_SAMPLINGRATE_192, 192000} };
{SL_SAMPLINGRATE_16, 16000}, {SL_SAMPLINGRATE_8, 8000}, {SL_SAMPLINGRATE_32, 32000},
{SL_SAMPLINGRATE_44_1, 44100}, {SL_SAMPLINGRATE_11_025, 10025}, {SL_SAMPLINGRATE_22_05, 22050},
{SL_SAMPLINGRATE_24, 24000}, {SL_SAMPLINGRATE_48, 48000}, {SL_SAMPLINGRATE_64, 64000},
{SL_SAMPLINGRATE_88_2, 88200}, {SL_SAMPLINGRATE_96, 96000}, {SL_SAMPLINGRATE_192, 192000}};
bool AndroidInputDevice::open()
{
@@ -158,7 +143,7 @@ bool AndroidInputDevice::open()
if (!opened)
internalClose();
}
catch(...)
catch (...)
{
opened = false;
internalClose();
@@ -192,8 +177,7 @@ bool AndroidInputDevice::fakeMode()
return false;
}
void AndroidInputDevice::setFakeMode(bool fakemode)
{}
void AndroidInputDevice::setFakeMode(bool fakemode) {}
int AndroidInputDevice::readBuffer(void* buffer)
{
@@ -206,7 +190,13 @@ int AndroidInputDevice::readBuffer(void* buffer)
return mSdkRateCache.read(buffer, AUDIO_MIC_BUFFER_SIZE);
}
#define CHECK_SL_INTERFACE(INTF, ERR) {if (!INTF) throw Exception(ERR_OPENSLES, ERR); if (!(*INTF)) throw Exception(ERR_OPENSLES, ERR);}
#define CHECK_SL_INTERFACE(INTF, ERR) \
{ \
if (!INTF) \
throw Exception(ERR_OPENSLES, ERR); \
if (!(*INTF)) \
throw Exception(ERR_OPENSLES, ERR); \
}
void AndroidInputDevice::internalOpen(int rateCode, int rate)
{
@@ -214,33 +204,37 @@ void AndroidInputDevice::internalOpen(int rateCode, int rate)
SLuint32 nrOfChannels = 1;
// Prepare audio source
SLDataLocator_IODevice devDescription = { SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, SL_DEFAULTDEVICEID_AUDIOINPUT, NULL};
SLDataSource audioSource = { &devDescription, NULL };
SLDataLocator_IODevice devDescription = {SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT,
SL_DEFAULTDEVICEID_AUDIOINPUT, NULL};
SLDataSource audioSource = {&devDescription, NULL};
// Source flags
SLuint32 speakersFlags = nrOfChannels > 1 ? (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT) : SL_SPEAKER_FRONT_CENTER;
SLuint32 speakersFlags =
nrOfChannels > 1 ? (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT) : SL_SPEAKER_FRONT_CENTER;
// Buffer queue
SLDataLocator_AndroidSimpleBufferQueue queueDescription = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2 };
SLDataLocator_AndroidSimpleBufferQueue queueDescription = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
// Audio format
SLDataFormat_PCM formatDescription = { SL_DATAFORMAT_PCM, nrOfChannels, (SLuint32)rateCode, SL_PCMSAMPLEFORMAT_FIXED_16,
SL_PCMSAMPLEFORMAT_FIXED_16, (SLuint32)speakersFlags, SL_BYTEORDER_LITTLEENDIAN };
SLDataFormat_PCM formatDescription = {SL_DATAFORMAT_PCM, nrOfChannels,
(SLuint32)rateCode, SL_PCMSAMPLEFORMAT_FIXED_16,
SL_PCMSAMPLEFORMAT_FIXED_16, (SLuint32)speakersFlags,
SL_BYTEORDER_LITTLEENDIAN};
SLDataSink audioSink = { &queueDescription, &formatDescription };
SLDataSink audioSink = {&queueDescription, &formatDescription};
// Create recorder
// Do not forget about RECORD_AUDIO permission
const SLInterfaceID interfacesList[2] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION };
const SLboolean interfacesRequirements[2] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
const SLInterfaceID interfacesList[2] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION};
const SLboolean interfacesRequirements[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
// Get access to OpenSL engine
SLEngineItf engine_interface = OpenSLEngine::instance().getNativeEngine();
CHECK_SL_INTERFACE(engine_interface, -1);
resultCode = (*engine_interface)->CreateAudioRecorder(
OpenSLEngine::instance().getNativeEngine(),
&mRecorderObject, &audioSource, &audioSink, 2, interfacesList, interfacesRequirements);
resultCode = (*engine_interface)
->CreateAudioRecorder(OpenSLEngine::instance().getNativeEngine(), &mRecorderObject, &audioSource,
&audioSink, 2, interfacesList, interfacesRequirements);
CHECK_OPENSLES_ERROR;
CHECK_SL_INTERFACE(mRecorderObject, -2);
@@ -258,7 +252,8 @@ void AndroidInputDevice::internalOpen(int rateCode, int rate)
CHECK_SL_INTERFACE(mRecorderInterface, -3);
// Now buffer queue interface...
resultCode = (*mRecorderObject)->GetInterface(mRecorderObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &mRecorderBufferInterface);
resultCode =
(*mRecorderObject)->GetInterface(mRecorderObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &mRecorderBufferInterface);
CHECK_OPENSLES_ERROR;
CHECK_SL_INTERFACE(mRecorderBufferInterface, -4);
@@ -276,8 +271,9 @@ void AndroidInputDevice::internalOpen(int rateCode, int rate)
CHECK_OPENSLES_ERROR;
// Setup buffers
for (int i=0; i<AUDIO_MIC_BUFFER_COUNT; i++)
(*mRecorderBufferInterface)->Enqueue(mRecorderBufferInterface, mRecorderBuffer.data() + i * mBufferSize, mBufferSize);
for (int i = 0; i < AUDIO_MIC_BUFFER_COUNT; i++)
(*mRecorderBufferInterface)
->Enqueue(mRecorderBufferInterface, mRecorderBuffer.data() + i * mBufferSize, mBufferSize);
// Start finally
resultCode = (*mRecorderInterface)->SetRecordState(mRecorderInterface, SL_RECORDSTATE_RECORDING);
@@ -302,8 +298,7 @@ void AndroidInputDevice::internalClose()
{
(*mRecorderInterface)->GetRecordState(mRecorderInterface, &state);
SyncHelper::delay(1);
}
while (state == SL_RECORDSTATE_RECORDING);
} while (state == SL_RECORDSTATE_RECORDING);
}
(*mRecorderObject)->Destroy(mRecorderObject);
}
@@ -331,9 +326,8 @@ void AndroidInputDevice::handleCallback(SLAndroidSimpleBufferQueueItf bq)
{
char* resampled = (char*)alloca(Format().sizeFromTime(10));
int processed = 0;
int outlen = mResampler->processBuffer(mDeviceRateCache.data(), tenMsSize, processed, resampled, Format().sizeFromTime(10));
if (outlen > 0)
mSdkRateCache.add(resampled, (int)Format().sizeFromTime(10));
int outlen = mResampler->processBuffer(mDeviceRateCache.data(), tenMsSize, processed, resampled,
Format().sizeFromTime(10)); if (outlen > 0) mSdkRateCache.add(resampled, (int)Format().sizeFromTime(10));
mDeviceRateCache.erase(tenMsSize);
}
@@ -346,20 +340,22 @@ void AndroidInputDevice::handleCallback(SLAndroidSimpleBufferQueueItf bq)
}
*/
// Re-enqueue used buffer
(*mRecorderBufferInterface)->Enqueue(mRecorderBufferInterface, mRecorderBuffer.data() + mRecorderBufferIndex * mBufferSize, mBufferSize);
(*mRecorderBufferInterface)
->Enqueue(mRecorderBufferInterface, mRecorderBuffer.data() + mRecorderBufferIndex * mBufferSize, mBufferSize);
mRecorderBufferIndex++;
mRecorderBufferIndex %= AUDIO_MIC_BUFFER_COUNT;
}
void AndroidInputDevice::DeviceCallback(SLAndroidSimpleBufferQueueItf bq, void *context)
void AndroidInputDevice::DeviceCallback(SLAndroidSimpleBufferQueueItf bq, void* context)
{
try
{
if (context)
reinterpret_cast<AndroidInputDevice*>(context)->handleCallback(bq);
}
catch(...)
{}
catch (...)
{
}
}
// ------------ AndroidOutputDevice -----------------
@@ -387,7 +383,7 @@ bool AndroidOutputDevice::open()
mDeviceRate = RateToProbe[rateIndex][1];
ICELogCritical(<< "Output opened with rate " << mDeviceRate << " and index " << rateIndex);
}
catch(...)
catch (...)
{
opened = false;
}
@@ -414,9 +410,7 @@ bool AndroidOutputDevice::fakeMode()
return false;
}
void AndroidOutputDevice::setFakeMode(bool fakemode)
{
}
void AndroidOutputDevice::setFakeMode(bool fakemode) {}
void AndroidOutputDevice::internalOpen(int rateId, int rate, bool voice)
{
@@ -426,12 +420,12 @@ void AndroidOutputDevice::internalOpen(int rateId, int rate, bool voice)
SLuint32 channels = 1;
// Configure audio source
SLDataLocator_AndroidSimpleBufferQueue queue_desc = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2 };
SLDataLocator_AndroidSimpleBufferQueue queue_desc = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
const SLInterfaceID interfacesList[] = { SL_IID_VOLUME };
const SLboolean interfaceRequirements[] = { SL_BOOLEAN_FALSE };
resultCode = (*OpenSLEngine::instance().getNativeEngine())->CreateOutputMix(
OpenSLEngine::instance().getNativeEngine(), &mMixer, 1, interfacesList,
const SLInterfaceID interfacesList[] = {SL_IID_VOLUME};
const SLboolean interfaceRequirements[] = {SL_BOOLEAN_FALSE};
resultCode = (*OpenSLEngine::instance().getNativeEngine())
->CreateOutputMix(OpenSLEngine::instance().getNativeEngine(), &mMixer, 1, interfacesList,
interfaceRequirements);
CHECK_OPENSLES_ERROR;
@@ -440,30 +434,28 @@ void AndroidOutputDevice::internalOpen(int rateId, int rate, bool voice)
CHECK_OPENSLES_ERROR;
// Prepare mixer configuration
SLuint32 speakers =
channels > 1 ? (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT) : SL_SPEAKER_FRONT_CENTER;
SLuint32 speakers = channels > 1 ? (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT) : SL_SPEAKER_FRONT_CENTER;
// Describe audio format
SLDataFormat_PCM pcm_format = {SL_DATAFORMAT_PCM, channels, (SLuint32) rateId,
SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
speakers, SL_BYTEORDER_LITTLEENDIAN};
SLDataFormat_PCM pcm_format = {
SL_DATAFORMAT_PCM, channels, (SLuint32)rateId, SL_PCMSAMPLEFORMAT_FIXED_16,
SL_PCMSAMPLEFORMAT_FIXED_16, speakers, SL_BYTEORDER_LITTLEENDIAN};
// Describe audio source - buffers + audio format
SLDataSource audio_source = { &queue_desc, &pcm_format };
SLDataSource audio_source = {&queue_desc, &pcm_format};
// Describe audio sink
SLDataLocator_OutputMix mixer_desc = { SL_DATALOCATOR_OUTPUTMIX, mMixer };
SLDataSink audio_sink = { &mixer_desc, NULL };
SLDataLocator_OutputMix mixer_desc = {SL_DATALOCATOR_OUTPUTMIX, mMixer};
SLDataSink audio_sink = {&mixer_desc, NULL};
// Create player instance
const SLInterfaceID playerInterfaces[] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
SL_IID_VOLUME,
SL_IID_ANDROIDCONFIGURATION };
const SLboolean playerInterfacesReqs[] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
const SLInterfaceID playerInterfaces[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_VOLUME,
SL_IID_ANDROIDCONFIGURATION};
const SLboolean playerInterfacesReqs[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
resultCode = (*OpenSLEngine::instance().getNativeEngine())->CreateAudioPlayer(
OpenSLEngine::instance().getNativeEngine(), &mPlayer,
&audio_source, &audio_sink, 3, playerInterfaces, playerInterfacesReqs);
resultCode = (*OpenSLEngine::instance().getNativeEngine())
->CreateAudioPlayer(OpenSLEngine::instance().getNativeEngine(), &mPlayer, &audio_source,
&audio_sink, 3, playerInterfaces, playerInterfacesReqs);
CHECK_OPENSLES_ERROR;
// Get android config interface
@@ -472,8 +464,8 @@ void AndroidOutputDevice::internalOpen(int rateId, int rate, bool voice)
if (resultCode == SL_RESULT_SUCCESS)
{
SLint32 streamType = voice ? SL_ANDROID_STREAM_VOICE : SL_ANDROID_STREAM_MEDIA;
resultCode = (*mAndroidConfig)->SetConfiguration(mAndroidConfig, SL_ANDROID_KEY_STREAM_TYPE,
&streamType, sizeof(SLint32));
resultCode = (*mAndroidConfig)
->SetConfiguration(mAndroidConfig, SL_ANDROID_KEY_STREAM_TYPE, &streamType, sizeof(SLint32));
if (resultCode != SL_RESULT_SUCCESS)
ICELogCritical(<< "Failed to set audio destination with error " << (unsigned)resultCode);
}
@@ -489,8 +481,7 @@ void AndroidOutputDevice::internalOpen(int rateId, int rate, bool voice)
CHECK_OPENSLES_ERROR;
// Get the buffer queue interface
resultCode = (*mPlayer)->GetInterface(mPlayer, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
&mBufferQueue);
resultCode = (*mPlayer)->GetInterface(mPlayer, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &mBufferQueue);
CHECK_OPENSLES_ERROR;
// Setup callback
@@ -503,8 +494,7 @@ void AndroidOutputDevice::internalOpen(int rateId, int rate, bool voice)
mBufferIndex = 0;
for (int i = 0; i < AUDIO_SPK_BUFFER_COUNT; i++)
(*mBufferQueue)->Enqueue(mBufferQueue, mPlayBuffer.data() + i * mBufferSize,
(SLuint32)mBufferSize);
(*mBufferQueue)->Enqueue(mBufferQueue, mPlayBuffer.data() + i * mBufferSize, (SLuint32)mBufferSize);
// Set the player's state to playing
resultCode = (*mPlayerControl)->SetPlayState(mPlayerControl, SL_PLAYSTATE_PLAYING);
@@ -521,12 +511,15 @@ void AndroidOutputDevice::internalClose()
{
mInShutdown = true;
ICELogInfo(<< "Stop player");
if (mPlayerControl) {
if (*mPlayerControl) {
if (mPlayerControl)
{
if (*mPlayerControl)
{
SLuint32 state = SL_PLAYSTATE_PLAYING;
(*mPlayerControl)->SetPlayState(mPlayerControl, SL_PLAYSTATE_STOPPED);
while (state != SL_PLAYSTATE_STOPPED) {
while (state != SL_PLAYSTATE_STOPPED)
{
(*mPlayerControl)->GetPlayState(mPlayerControl, &state);
SyncHelper::delay(1);
}
@@ -592,8 +585,9 @@ void AndroidOutputDevice::DeviceCallback(SLAndroidSimpleBufferQueueItf bq, void*
{
reinterpret_cast<AndroidOutputDevice*>(context)->handleCallback(bq);
}
catch(...)
{}
catch (...)
{
}
}
#endif // TARGET_ANDROID
+21 -22
View File
@@ -25,9 +25,9 @@
namespace Audio
{
class AndroidEnumerator: public Enumerator
{
public:
class AndroidEnumerator : public Enumerator
{
public:
AndroidEnumerator();
~AndroidEnumerator();
@@ -39,12 +39,12 @@ namespace Audio
int idAt(int index);
int indexOfDefaultDevice();
protected:
};
protected:
};
class AndroidInputDevice: public InputDevice
{
public:
class AndroidInputDevice : public InputDevice
{
public:
AndroidInputDevice(int devId);
~AndroidInputDevice();
@@ -57,7 +57,7 @@ namespace Audio
int readBuffer(void* buffer);
bool active() const;
protected:
protected:
bool mActive = false;
SLObjectItf mRecorderObject = nullptr;
SLRecordItf mRecorderInterface = nullptr;
@@ -77,11 +77,11 @@ namespace Audio
void internalClose();
void handleCallback(SLAndroidSimpleBufferQueueItf bq);
static void DeviceCallback(SLAndroidSimpleBufferQueueItf bq, void* context);
};
};
class AndroidOutputDevice: public OutputDevice
{
public:
class AndroidOutputDevice : public OutputDevice
{
public:
AndroidOutputDevice(int devId);
~AndroidOutputDevice();
@@ -92,7 +92,7 @@ namespace Audio
bool fakeMode();
void setFakeMode(bool fakemode);
protected:
protected:
std::mutex mMutex;
int mDeviceRate = 0;
SLObjectItf mMixer = nullptr;
@@ -111,12 +111,11 @@ namespace Audio
void handleCallback(SLAndroidSimpleBufferQueueItf bq);
static void DeviceCallback(SLAndroidSimpleBufferQueueItf bq, void* context);
};
};
class OpenSLEngine: public OsEngine
{
public:
class OpenSLEngine : public OsEngine
{
public:
OpenSLEngine();
~OpenSLEngine();
@@ -130,7 +129,7 @@ namespace Audio
static OpenSLEngine& instance();
protected:
protected:
std::mutex mMutex;
int mUsageCounter = 0;
SLObjectItf mEngineObject = nullptr;
@@ -138,8 +137,8 @@ namespace Audio
void internalOpen();
void internalClose();
};
}
};
} // namespace Audio
#endif // TARGET_ANDROID
+22 -27
View File
@@ -18,11 +18,9 @@ using namespace Audio;
// -------------------- AndroidEnumerator -----------------------------
AndroidEnumerator::AndroidEnumerator()
{}
AndroidEnumerator::AndroidEnumerator() {}
AndroidEnumerator::~AndroidEnumerator()
{}
AndroidEnumerator::~AndroidEnumerator() {}
int AndroidEnumerator::indexOfDefaultDevice()
{
@@ -44,15 +42,12 @@ std::string AndroidEnumerator::nameAt(int index)
return "Audio";
}
void AndroidEnumerator::open(int direction)
{}
void AndroidEnumerator::open(int direction) {}
void AndroidEnumerator::close()
{}
void AndroidEnumerator::close() {}
// --------------- Input implementation ----------------
AndroidInputDevice::AndroidInputDevice(int devId)
{}
AndroidInputDevice::AndroidInputDevice(int devId) {}
AndroidInputDevice::~AndroidInputDevice()
{
@@ -94,13 +89,14 @@ void AndroidInputDevice::close()
if (mRecordingStream != nullptr)
{
mRecordingStream->close();
delete mRecordingStream; mRecordingStream = nullptr;
delete mRecordingStream;
mRecordingStream = nullptr;
}
mActive = false;
}
oboe::DataCallbackResult
AndroidInputDevice::onAudioReady(oboe::AudioStream *audioStream, void *audioData, int32_t numFrames)
oboe::DataCallbackResult AndroidInputDevice::onAudioReady(oboe::AudioStream* audioStream, void* audioData,
int32_t numFrames)
{
std::unique_lock<std::mutex> l(mMutex);
@@ -126,8 +122,7 @@ bool AndroidInputDevice::fakeMode()
return false;
}
void AndroidInputDevice::setFakeMode(bool fakemode)
{}
void AndroidInputDevice::setFakeMode(bool fakemode) {}
int AndroidInputDevice::readBuffer(void* buffer)
{
@@ -172,7 +167,7 @@ bool AndroidOutputDevice::open()
builder.setContentType(oboe::ContentType::Speech);
// builder.setDataCallback(this);
builder.setCallback(this);
//builder.setErrorCallback(this)
// builder.setErrorCallback(this)
oboe::Result rescode = builder.openStream(&mPlayingStream);
if (rescode != oboe::Result::OK)
@@ -211,7 +206,8 @@ void AndroidOutputDevice::close()
if (mPlayingStream != nullptr)
{
mPlayingStream->close();
delete mPlayingStream; mPlayingStream = nullptr;
delete mPlayingStream;
mPlayingStream = nullptr;
}
mEndTime = now_ms();
mActive = false;
@@ -230,11 +226,10 @@ bool AndroidOutputDevice::fakeMode()
return false;
}
void AndroidOutputDevice::setFakeMode(bool /*fakemode*/)
{
}
void AndroidOutputDevice::setFakeMode(bool /*fakemode*/) {}
oboe::DataCallbackResult AndroidOutputDevice::onAudioReady(oboe::AudioStream *audioStream, void *audioData, int32_t numFrames)
oboe::DataCallbackResult AndroidOutputDevice::onAudioReady(oboe::AudioStream* audioStream, void* audioData,
int32_t numFrames)
{
if (mInShutdown)
return oboe::DataCallbackResult::Stop;
@@ -276,10 +271,8 @@ oboe::DataCallbackResult AndroidOutputDevice::onAudioReady(oboe::AudioStream *au
mHeartbeatLast = t;
else if (t - mHeartbeatLast >= 5000.0f)
{
ICELogInfo(<< "[spk-heartbeat] xruns=" << mXRunLast
<< " bufFrames=" << audioStream->getBufferSizeInFrames()
<< " burst=" << mBurstFrames
<< " rate=" << mDeviceRate);
ICELogInfo(<< "[spk-heartbeat] xruns=" << mXRunLast << " bufFrames=" << audioStream->getBufferSizeInFrames()
<< " burst=" << mBurstFrames << " rate=" << mDeviceRate);
mHeartbeatLast = t;
}
@@ -290,8 +283,10 @@ oboe::DataCallbackResult AndroidOutputDevice::onAudioReady(oboe::AudioStream *au
// stream down and calls this on its own thread after the stream is closed. Rebuild
// on the new default route so audio doesn't silently die mid-call.
// See https://github.com/google/oboe/blob/master/docs/notes/disconnect.md
void AndroidOutputDevice::onErrorAfterClose(oboe::AudioStream *stream, oboe::Result result) {
if (result == oboe::Result::ErrorDisconnected && !mInShutdown) {
void AndroidOutputDevice::onErrorAfterClose(oboe::AudioStream* stream, oboe::Result result)
{
if (result == oboe::Result::ErrorDisconnected && !mInShutdown)
{
ICELogInfo(<< "Output stream disconnected; restarting on the new route");
// close() and open() each take mMutex internally; this callback holds none.
close();
+19 -20
View File
@@ -25,9 +25,9 @@
namespace Audio
{
class AndroidEnumerator: public Enumerator
{
public:
class AndroidEnumerator : public Enumerator
{
public:
AndroidEnumerator();
~AndroidEnumerator();
@@ -39,12 +39,12 @@ namespace Audio
int idAt(int index);
int indexOfDefaultDevice();
protected:
};
protected:
};
class AndroidInputDevice: public InputDevice, public oboe::AudioStreamCallback
{
public:
class AndroidInputDevice : public InputDevice, public oboe::AudioStreamCallback
{
public:
AndroidInputDevice(int devId);
~AndroidInputDevice();
@@ -57,11 +57,10 @@ namespace Audio
int readBuffer(void* buffer);
bool active() const;
oboe::DataCallbackResult
onAudioReady(oboe::AudioStream *audioStream, void *audioData, int32_t numFrames);
oboe::DataCallbackResult onAudioReady(oboe::AudioStream* audioStream, void* audioData, int32_t numFrames);
protected:
protected:
bool mActive = false;
oboe::AudioStream* mRecordingStream = nullptr;
PResampler mResampler;
@@ -72,11 +71,11 @@ namespace Audio
std::condition_variable mDataCondVar;
int mRecorderBufferIndex;
std::mutex mMutex;
};
};
class AndroidOutputDevice: public OutputDevice, public oboe::AudioStreamCallback
{
public:
class AndroidOutputDevice : public OutputDevice, public oboe::AudioStreamCallback
{
public:
AndroidOutputDevice(int devId);
~AndroidOutputDevice();
@@ -87,10 +86,10 @@ class AndroidOutputDevice: public OutputDevice, public oboe::AudioStreamCallback
bool fakeMode();
void setFakeMode(bool fakemode);
oboe::DataCallbackResult onAudioReady(oboe::AudioStream *audioStream, void *audioData, int32_t numFrames);
void onErrorAfterClose(oboe::AudioStream *stream, oboe::Result result);
oboe::DataCallbackResult onAudioReady(oboe::AudioStream* audioStream, void* audioData, int32_t numFrames);
void onErrorAfterClose(oboe::AudioStream* stream, oboe::Result result);
protected:
protected:
std::mutex mMutex;
int mDeviceRate = 0;
oboe::AudioStream* mPlayingStream = nullptr;
@@ -106,8 +105,8 @@ class AndroidOutputDevice: public OutputDevice, public oboe::AudioStreamCallback
// Statistics
float mRequestedFrames = 0.0, mStartTime = 0.0, mEndTime = 0.0;
};
}
};
} // namespace Audio
#endif // TARGET_ANDROID
+84 -149
View File
@@ -7,7 +7,7 @@
#include "Audio_CoreAudio.h"
#include "../Helper/HL_Log.h"
//#include <qdebug.h>
// #include <qdebug.h>
#include <AudioUnit/AudioUnit.h>
#include <CoreAudio/CoreAudio.h>
@@ -23,12 +23,11 @@ enum
static inline short Float32ToInt16(Float32 v)
{
//assert (v <= 1.0);
// assert (v <= 1.0);
int r = int(v * 32768);
if (r >= 32768)
return (short)32767;
else
if (r < -32768)
else if (r < -32768)
return (short)-32768;
else
return (short)r;
@@ -43,7 +42,7 @@ static inline Float32 Int16ToFloat32(short v)
static inline Float32 StereoToMono(bool interleaved, Float32* buffer, int samples, int index, int channels)
{
Float32 sum = 0;
for (int i = 0; i<channels; i++)
for (int i = 0; i < channels; i++)
{
if (!interleaved)
sum += buffer[index * channels + i];
@@ -55,7 +54,7 @@ static inline Float32 StereoToMono(bool interleaved, Float32* buffer, int sample
static inline void MonoToStereo(bool interleaved, Float32 sample, Float32* buffer, int samples, int index, int channels)
{
for (int i=0; i<channels; i++)
for (int i = 0; i < channels; i++)
{
if (!interleaved)
buffer[index * channels + i] = sample;
@@ -64,7 +63,7 @@ static inline void MonoToStereo(bool interleaved, Float32 sample, Float32* buffe
}
}
static void propertyListenerCallback(void *inUserData, AudioQueueRef queueObject, AudioQueuePropertyID propertyID)
static void propertyListenerCallback(void* inUserData, AudioQueueRef queueObject, AudioQueuePropertyID propertyID)
{
// AudioPlayer *player = (AudioPlayer *) inUserData;
// gets a reference to the playback object
@@ -73,10 +72,7 @@ static void propertyListenerCallback(void *inUserData, AudioQueueRef queueObject
}
CoreAudioUnit::CoreAudioUnit()
:mUnit(0)
{
}
CoreAudioUnit::CoreAudioUnit() : mUnit(0) {}
void CoreAudioUnit::open(bool voice)
{
@@ -84,9 +80,7 @@ void CoreAudioUnit::open(bool voice)
#ifdef TARGET_IOS
UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord;
/* We want to be able to open playback and recording streams */
ostatus = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,
sizeof(audioCategory),
&audioCategory);
ostatus = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory);
if (ostatus != kAudioSessionNoError)
{
ICELogError(<< "Cannot set audio session to PlaybackAndRecord category, error" << ostatus);
@@ -101,7 +95,8 @@ void CoreAudioUnit::open(bool voice)
#ifdef TARGET_IOS
desc.componentSubType = voice ? kAudioUnitSubType_VoiceProcessingIO : kAudioUnitSubType_RemoteIO;
#else
desc.componentSubType = kAudioUnitSubType_HALOutput;//voice ? kAudioUnitSubType_VoiceProcessingIO : kAudioUnitSubType_DefaultOutput;
desc.componentSubType =
kAudioUnitSubType_HALOutput; // voice ? kAudioUnitSubType_VoiceProcessingIO : kAudioUnitSubType_DefaultOutput;
#endif
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
@@ -153,12 +148,8 @@ AudioStreamBasicDescription CoreAudioUnit::getFormat(int scope, int bus)
void CoreAudioUnit::setFormat(AudioStreamBasicDescription& format, int scope, int bus)
{
OSStatus ostatus = AudioUnitSetProperty(mUnit,
kAudioUnitProperty_StreamFormat,
scope,
bus,
&format,
sizeof(format));
OSStatus ostatus =
AudioUnitSetProperty(mUnit, kAudioUnitProperty_StreamFormat, scope, bus, &format, sizeof(format));
if (ostatus != noErr)
{
ICELogError(<< "Cannot set stream format, error " << int(ostatus));
@@ -181,28 +172,20 @@ bool CoreAudioUnit::getEnabled(int scope, int bus)
void CoreAudioUnit::setEnabled(bool enabled, int scope, int bus)
{
UInt32 enable = enabled ? 1 : 0;
OSStatus ostatus = AudioUnitSetProperty(mUnit,
kAudioOutputUnitProperty_EnableIO,
scope,
bus,
&enable,
sizeof(enable));
OSStatus ostatus =
AudioUnitSetProperty(mUnit, kAudioOutputUnitProperty_EnableIO, scope, bus, &enable, sizeof(enable));
if (ostatus != noErr)
{
ICELogError(<< "Cannot enable input on audio device , error " << int(ostatus));
//throw AudioException(ERR_COREAUDIO, ostatus);
// throw AudioException(ERR_COREAUDIO, ostatus);
}
}
void CoreAudioUnit::makeCurrent(AudioDeviceID deviceId, int scope, int bus)
{
OSStatus ostatus = AudioUnitSetProperty(mUnit,
kAudioOutputUnitProperty_CurrentDevice,
scope,
bus,
&deviceId,
sizeof(deviceId));
OSStatus ostatus =
AudioUnitSetProperty(mUnit, kAudioOutputUnitProperty_CurrentDevice, scope, bus, &deviceId, sizeof(deviceId));
if (ostatus != noErr)
{
ICELogError(<< "Cannot make device " << int(deviceId) << " current, error " << ostatus);
@@ -213,12 +196,7 @@ void CoreAudioUnit::makeCurrent(AudioDeviceID deviceId, int scope, int bus)
void CoreAudioUnit::setCallback(AURenderCallbackStruct cb, int callbackType, int scope, int bus)
{
OSStatus ostatus = AudioUnitSetProperty(mUnit,
callbackType,
scope,
bus,
&cb,
sizeof(cb));
OSStatus ostatus = AudioUnitSetProperty(mUnit, callbackType, scope, bus, &cb, sizeof(cb));
if (ostatus != noErr)
{
ICELogError(<< "Cannot set callback pointer, error " << int(ostatus));
@@ -230,7 +208,8 @@ void CoreAudioUnit::setBufferFrameSizeInMilliseconds(int ms)
{
#ifdef TARGET_IOS
Float32 preferredBufferSize = Float32(ms) / 1000; // in seconds
OSStatus ostatus = AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, sizeof(preferredBufferSize), &preferredBufferSize);
OSStatus ostatus = AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration,
sizeof(preferredBufferSize), &preferredBufferSize);
if (ostatus != noErr)
{
ICELogError(<< "Cannot set audio buffer length to " << ms << " milliseconds");
@@ -245,12 +224,8 @@ int CoreAudioUnit::getBufferFrameSize()
{
UInt32 bufsize = 0;
UInt32 size = sizeof(UInt32);
OSStatus ostatus = AudioUnitGetProperty(mUnit,
kAudioDevicePropertyBufferFrameSize,
kAudioUnitScope_Global,
Bus_Speaker,
&bufsize,
&size);
OSStatus ostatus = AudioUnitGetProperty(mUnit, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Global,
Bus_Speaker, &bufsize, &size);
if (ostatus != noErr)
{
ICELogError(<< "Cannot obtain input buffer size , error " << int(ostatus));
@@ -274,12 +249,9 @@ AudioUnit CoreAudioUnit::getHandle()
return mUnit;
}
OSStatus MacDevice::outputCallback( void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData )
OSStatus MacDevice::outputCallback(void* inRefCon, AudioUnitRenderActionFlags* ioActionFlags,
const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,
AudioBufferList* ioData)
{
MacDevice* d = reinterpret_cast<MacDevice*>(inRefCon);
if (!d)
@@ -293,20 +265,18 @@ OSStatus MacDevice::outputCallback( void *inRefCon,
AudioBuffer& ab = ioData->mBuffers[0];
if (ab.mNumberChannels == 1)
{
ICELogMedia(<< "CoreAudio output callback for mono " << (int)ab.mDataByteSize <<
" bytes");
ICELogMedia(<< "CoreAudio output callback for mono " << (int)ab.mDataByteSize << " bytes");
memset(ab.mData, 0, ab.mDataByteSize);
d->provideAudioToSpeaker(ab.mNumberChannels, ab.mData, ab.mDataByteSize);
for (int i=1; i<ioData->mNumberBuffers; i++)
for (int i = 1; i < ioData->mNumberBuffers; i++)
memcpy(ioData->mBuffers[i].mData, ab.mData, ab.mDataByteSize);
}
else
{
ICELogMedia(<< "CoreAudio output callback for stereo " << (int)ab.mDataByteSize <<
" bytes")
ICELogMedia(<< "CoreAudio output callback for stereo " << (int)ab.mDataByteSize << " bytes")
// Iterate requested buffers
for (unsigned i=0; i<ioData->mNumberBuffers; i++)
for (unsigned i = 0; i < ioData->mNumberBuffers; i++)
{
unsigned channels = ioData->mBuffers[i].mNumberChannels;
short* dataPtr = (short*)ioData->mBuffers[i].mData;
@@ -325,32 +295,25 @@ OSStatus MacDevice::outputCallback( void *inRefCon,
static char GlobalInputBuffer[AUDIO_MIC_BUFFER_COUNT * AUDIO_MIC_BUFFER_SIZE];
OSStatus MacDevice::inputCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData)
OSStatus MacDevice::inputCallback(void* inRefCon, AudioUnitRenderActionFlags* ioActionFlags,
const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,
AudioBufferList* ioData)
{
//ICELogDebug(<< "CoreAudio input callback");
// ICELogDebug(<< "CoreAudio input callback");
MacDevice* d = reinterpret_cast<MacDevice*>(inRefCon);
if (!d)
return 0;
OSStatus ostatus;
AudioBuffer& b = d->mInputBufferList->mBuffers[0];
//b.mDataByteSize = 65536;
// b.mDataByteSize = 65536;
b.mNumberChannels = d->mStreamFormat.mChannelsPerFrame;
b.mData = NULL;
b.mDataByteSize = inNumberFrames * d->mStreamFormat.mChannelsPerFrame;
// Render the unit to get input data
ostatus = AudioUnitRender(d->mAudioUnit.getHandle(),
ioActionFlags,
inTimeStamp,
inBusNumber,
inNumberFrames,
ostatus = AudioUnitRender(d->mAudioUnit.getHandle(), ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames,
d->mInputBufferList);
if (ostatus != noErr)
@@ -365,10 +328,7 @@ OSStatus MacDevice::inputCallback(void *inRefCon,
}
#ifdef TARGET_IOS
void MacDevice::propListener(void *inClientData,
AudioSessionPropertyID inID,
UInt32 inDataSize,
const void * inData)
void MacDevice::propListener(void* inClientData, AudioSessionPropertyID inID, UInt32 inDataSize, const void* inData)
{
MacDevice* d = reinterpret_cast<MacDevice*>(inClientData);
CFDictionaryRef routeDictionary;
@@ -388,10 +348,9 @@ void MacDevice::propListener(void *inClientData,
}
// Audio route changed. Nothing to do in this implementation.
}
void MacDevice::interruptionListener(void *inClientData, UInt32 inInterruption)
void MacDevice::interruptionListener(void* inClientData, UInt32 inInterruption)
{
MacDevice* d = reinterpret_cast<MacDevice*>(inClientData);
@@ -409,19 +368,16 @@ void MacDevice::interruptionListener(void *inClientData, UInt32 inInterruption)
*/
/* Make sure we set the correct audio category before restarting */
audioCategory = kAudioSessionCategory_PlayAndRecord;
ostatus = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,
sizeof(audioCategory),
&audioCategory);
ostatus = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory);
if (ostatus != kAudioSessionNoError)
{
ICELogError(<<"Cannot set the audio session category, error " << ostatus);
ICELogError(<< "Cannot set the audio session category, error " << ostatus);
}
// Start stream
d->startStream();
}
else
if (inInterruption == kAudioSessionBeginInterruption)
else if (inInterruption == kAudioSessionBeginInterruption)
{
d->stopStream();
}
@@ -429,28 +385,25 @@ void MacDevice::interruptionListener(void *inClientData, UInt32 inInterruption)
#endif
MacDevice::MacDevice(int devId)
:mDeviceId(devId), mCapture(false), mRender(false), mActive(false),
mConnection(nullptr), mUsageCount(0)
: mDeviceId(devId), mCapture(false), mRender(false), mActive(false), mConnection(nullptr), mUsageCount(0)
{
mInputBuffer.setCapacity(AUDIO_MIC_BUFFER_COUNT * AUDIO_MIC_BUFFER_SIZE);
mOutputBuffer.setCapacity(AUDIO_SPK_BUFFER_SIZE);
}
MacDevice::~MacDevice()
{
}
MacDevice::~MacDevice() {}
DataConnection* MacDevice::connection()
{
return mConnection;
}
void MacDevice::setConnection(DataConnection *c)
void MacDevice::setConnection(DataConnection* c)
{
mConnection = c;
}
void MacDevice::provideAudioToSpeaker(int channels, void *buffer, int length)
void MacDevice::provideAudioToSpeaker(int channels, void* buffer, int length)
{
if (!mConnection)
return;
@@ -459,7 +412,7 @@ void MacDevice::provideAudioToSpeaker(int channels, void *buffer, int length)
return;
}
void MacDevice::obtainAudioFromMic(int channels, const void *buffer, int length)
void MacDevice::obtainAudioFromMic(int channels, const void* buffer, int length)
{
if (!mConnection)
return;
@@ -539,13 +492,13 @@ bool MacDevice::createUnit(bool voice)
mAudioUnit.open(voice);
//if (mCapture != mAudioUnit.getEnabled(kAudioUnitScope_Input, Bus_Microphone))
// if (mCapture != mAudioUnit.getEnabled(kAudioUnitScope_Input, Bus_Microphone))
mAudioUnit.setEnabled(mCapture, kAudioUnitScope_Input, Bus_Microphone);
//mAudioUnit.setEnabled(mCapture, kAudioUnitScope_Output, Bus_Microphone);
// mAudioUnit.setEnabled(mCapture, kAudioUnitScope_Output, Bus_Microphone);
//if (mRender != mAudioUnit.getEnabled(kAudioUnitScope_Output, Bus_Speaker))
// if (mRender != mAudioUnit.getEnabled(kAudioUnitScope_Output, Bus_Speaker))
mAudioUnit.setEnabled(mRender, kAudioUnitScope_Output, Bus_Speaker);
//mAudioUnit.setEnabled(mRender, kAudioUnitScope_Input, Bus_Speaker);
// mAudioUnit.setEnabled(mRender, kAudioUnitScope_Input, Bus_Speaker);
#ifdef TARGET_OSX
@@ -582,8 +535,9 @@ bool MacDevice::createUnit(bool voice)
// Start resample
mRenderResampler.start(mStreamFormat.mChannelsPerFrame, AUDIO_SAMPLERATE, mStreamFormat.mSampleRate);
// Set current render format - it is format required by unit from application; scope is Input and bus is 0 (speaker)
//mAudioUnit.setFormat(mRenderInputFormat, kAudioUnitScope_Input, Bus_Speaker);
// Set current render format - it is format required by unit from application; scope is Input and bus is 0
// (speaker)
// mAudioUnit.setFormat(mRenderInputFormat, kAudioUnitScope_Input, Bus_Speaker);
// Configure callback
AURenderCallbackStruct cb;
@@ -597,9 +551,10 @@ bool MacDevice::createUnit(bool voice)
AURenderCallbackStruct cb;
cb.inputProc = inputCallback;
cb.inputProcRefCon = this;
mAudioUnit.setCallback(cb, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, Bus_Microphone); //!!!
mAudioUnit.setCallback(cb, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global,
Bus_Microphone); //!!!
#ifdef TARGET_OSX
AudioBuffer *ab;
AudioBuffer* ab;
UInt32 size, bufsize;
mAudioUnit.setBufferFrameSizeInMilliseconds(COREAUDIO_BUFFER_TIME);
@@ -615,11 +570,11 @@ bool MacDevice::createUnit(bool voice)
mInputBufferList->mNumberBuffers = 1;
ab = &mInputBufferList->mBuffers[0];
ab->mNumberChannels = mStreamFormat.mChannelsPerFrame;
ab->mDataByteSize = 0;//bufsize * ab->mNumberChannels * mCaptureOutputFormat.mBitsPerChannel / 8 * 8;
ab->mData = NULL;//malloc(ab->mDataByteSize);
ab->mDataByteSize = 0; // bufsize * ab->mNumberChannels * mCaptureOutputFormat.mBitsPerChannel / 8 * 8;
ab->mData = NULL; // malloc(ab->mDataByteSize);
if (!ab->mData)
{
//ICELogError(<< "No memory for capture buffer");
// ICELogError(<< "No memory for capture buffer");
}
#endif
#ifdef TARGET_IOS
@@ -662,8 +617,9 @@ void MacDevice::startStream()
}
// Share audio chain
//UInt32 allowMixing = YES;
//AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof (allowMixing), &allowMixing);
// UInt32 allowMixing = YES;
// AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof (allowMixing),
// &allowMixing);
// Activate audio chain
AudioSessionSetActive(true);
@@ -721,15 +677,9 @@ protected:
MacDeviceList* MacDeviceList::mInstance = NULL;
MacDeviceList::MacDeviceList()
{
MacDeviceList::MacDeviceList() {}
}
MacDeviceList::~MacDeviceList()
{
}
MacDeviceList::~MacDeviceList() {}
MacDeviceList& MacDeviceList::instance()
{
@@ -741,7 +691,7 @@ MacDeviceList& MacDeviceList::instance()
PMacDevice MacDeviceList::findDevice(int devId)
{
Lock l(mGuard);
for (unsigned i=0; i<mDeviceList.size(); i++)
for (unsigned i = 0; i < mDeviceList.size(); i++)
{
PMacDevice& d = mDeviceList[i];
if (d->getId() == devId)
@@ -754,8 +704,7 @@ PMacDevice MacDeviceList::findDevice(int devId)
}
// Share list of opened devices
MacInputDevice::MacInputDevice(int devId)
:InputDevice()
MacInputDevice::MacInputDevice(int devId) : InputDevice()
{
// Look for MacDevice
mDevice = MacDeviceList::instance().findDevice(devId);
@@ -784,8 +733,7 @@ Format MacInputDevice::getFormat()
return mDevice->getFormat();
}
MacOutputDevice::MacOutputDevice(int devId)
:OutputDevice()
MacOutputDevice::MacOutputDevice(int devId) : OutputDevice()
{
// Look for MacDevice
mDevice = MacDeviceList::instance().findDevice(devId);
@@ -814,16 +762,9 @@ Format MacOutputDevice::getFormat()
return mDevice->getFormat();
}
MacEnumerator::MacEnumerator()
:mDefaultInput(0), mDefaultOutput(0)
{
MacEnumerator::MacEnumerator() : mDefaultInput(0), mDefaultOutput(0) {}
}
MacEnumerator::~MacEnumerator()
{
}
MacEnumerator::~MacEnumerator() {}
void MacEnumerator::open(int direction)
{
@@ -841,8 +782,7 @@ void MacEnumerator::open(int direction)
addr.mSelector = kAudioHardwarePropertyDevices;
addr.mScope = kAudioObjectPropertyScopeGlobal;
addr.mElement = kAudioObjectPropertyElementMaster;
osstatus = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &addr,
0, NULL, &devSize);
osstatus = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &addr, 0, NULL, &devSize);
if (osstatus != noErr)
{
devSize = 0;
@@ -854,11 +794,11 @@ void MacEnumerator::open(int direction)
deviceIds.resize(devCount);
// Get actual list
osstatus = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr,
0, NULL, &devSize, (void *)&deviceIds.front());
osstatus =
AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr, 0, NULL, &devSize, (void*)&deviceIds.front());
if (osstatus != noErr)
return;
for (unsigned i=0; i<deviceIds.size(); i++)
for (unsigned i = 0; i < deviceIds.size(); i++)
{
DeviceInfo di;
di.mId = deviceIds[i];
@@ -887,13 +827,12 @@ void MacEnumerator::open(int direction)
addr.mElement = kAudioObjectPropertyElementMaster;
size = sizeof(devId);
osstatus = AudioObjectGetPropertyData(kAudioObjectSystemObject,
&addr, 0, NULL, &size, (void *)&devId);
osstatus = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr, 0, NULL, &size, (void*)&devId);
if (osstatus == noErr)
{
std::vector<DeviceInfo>::iterator r = std::find_if(mDeviceList.begin(), mDeviceList.end(),
[devId] (const DeviceInfo& di) { return di.mId == devId;});
std::vector<DeviceInfo>::iterator r = std::find_if(
mDeviceList.begin(), mDeviceList.end(), [devId](const DeviceInfo& di) { return di.mId == devId; });
if (r != mDeviceList.end())
mDefaultInput = r - mDeviceList.begin();
}
@@ -903,13 +842,11 @@ void MacEnumerator::open(int direction)
if (direction == mySpeaker)
{
addr.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
osstatus = AudioObjectGetPropertyData(kAudioObjectSystemObject,
&addr, 0, NULL,
&size, (void *)&devId);
osstatus = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr, 0, NULL, &size, (void*)&devId);
if (osstatus == noErr)
{
std::vector<DeviceInfo>::iterator r = std::find_if(mDeviceList.begin(), mDeviceList.end(),
[devId](const DeviceInfo& di) { return di.mId == devId;});
std::vector<DeviceInfo>::iterator r = std::find_if(
mDeviceList.begin(), mDeviceList.end(), [devId](const DeviceInfo& di) { return di.mId == devId; });
if (r != mDeviceList.end())
mDefaultOutput = r - mDeviceList.begin();
}
@@ -918,7 +855,7 @@ void MacEnumerator::open(int direction)
#endif
}
void MacEnumerator::getInfo(DeviceInfo &di)
void MacEnumerator::getInfo(DeviceInfo& di)
{
UInt32 size;
OSStatus osstatus;
@@ -930,7 +867,7 @@ void MacEnumerator::getInfo(DeviceInfo &di)
addr.mElement = kAudioObjectPropertyElementMaster;
char name[256];
size = sizeof(name);
AudioObjectGetPropertyData(di.mId, &addr, 0, NULL, &size, (void *)name);
AudioObjectGetPropertyData(di.mId, &addr, 0, NULL, &size, (void*)name);
di.mName = name;
// Get the number of input channels
@@ -984,7 +921,8 @@ void MacEnumerator::getInfo(DeviceInfo &di)
di.mOutputCount += buf->mBuffers[idx].mNumberChannels;
}
}
free(buf); buf = NULL;
free(buf);
buf = NULL;
}
/* Get default sample rate */
@@ -992,7 +930,7 @@ void MacEnumerator::getInfo(DeviceInfo &di)
addr.mScope = kAudioObjectPropertyScopeGlobal;
size = sizeof(Float64);
Float64 sampleRate;
osstatus = AudioObjectGetPropertyData (di.mId, &addr, 0, NULL, &size, &sampleRate);
osstatus = AudioObjectGetPropertyData(di.mId, &addr, 0, NULL, &size, &sampleRate);
if (osstatus == noErr)
di.mDefaultRate = int(sampleRate);
@@ -1009,10 +947,7 @@ void MacEnumerator::getInfo(DeviceInfo &di)
}
}
void MacEnumerator::close()
{
}
void MacEnumerator::close() {}
int MacEnumerator::count()
{
+25 -32
View File
@@ -25,18 +25,16 @@
namespace Audio
{
class AudioException: public Exception
class AudioException : public Exception
{
public:
AudioException(int code, OSStatus subcode)
:Exception(code, int(subcode))
{}
AudioException(int code, OSStatus subcode) : Exception(code, int(subcode)) {}
};
//#ifndef AudioDeviceID
//# define AudioDeviceID unsigned
//#endif
class MacEnumerator: public Enumerator
// #ifndef AudioDeviceID
// # define AudioDeviceID unsigned
// #endif
class MacEnumerator : public Enumerator
{
public:
MacEnumerator();
@@ -59,7 +57,11 @@ protected:
bool mCanChangeInputVolume;
int mInputCount, mOutputCount;
int mDefaultRate;
DeviceInfo(): mId(0), mCanChangeOutputVolume(false), mCanChangeInputVolume(false), mInputCount(0), mOutputCount(0), mDefaultRate(16000) {}
DeviceInfo()
: mId(0), mCanChangeOutputVolume(false), mCanChangeInputVolume(false), mInputCount(0), mOutputCount(0),
mDefaultRate(16000)
{
}
};
std::vector<DeviceInfo> mDeviceList;
unsigned mDefaultInput, mDefaultOutput;
@@ -117,7 +119,8 @@ protected:
CoreAudioUnit mAudioUnit;
AudioComponent mComponent;
AudioStreamBasicDescription mCaptureInputFormat, mCaptureOutputFormat, mRenderInputFormat, mRenderOutputFormat, mStreamFormat;
AudioStreamBasicDescription mCaptureInputFormat, mCaptureOutputFormat, mRenderInputFormat, mRenderOutputFormat,
mStreamFormat;
AudioBufferList* mInputBufferList;
DataConnection* mConnection;
SpeexResampler mCaptureResampler, mRenderResampler;
@@ -130,32 +133,22 @@ protected:
void setupStreamFormat();
bool createResampleUnit(AudioStreamBasicDescription format);
static OSStatus outputCallback( void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData );
static OSStatus outputCallback(void* inRefCon, AudioUnitRenderActionFlags* ioActionFlags,
const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,
AudioBufferList* ioData);
static OSStatus inputCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData);
static OSStatus inputCallback(void* inRefCon, AudioUnitRenderActionFlags* ioActionFlags,
const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,
AudioBufferList* ioData);
#ifdef TARGET_IOS
static void propListener(void *inClientData,
AudioSessionPropertyID inID,
UInt32 inDataSize,
const void * inData);
static void interruptionListener(void *inClientData, UInt32 inInterruption);
static void propListener(void* inClientData, AudioSessionPropertyID inID, UInt32 inDataSize, const void* inData);
static void interruptionListener(void* inClientData, UInt32 inInterruption);
#endif
};
typedef std::shared_ptr<MacDevice> PMacDevice;
class MacInputDevice: public InputDevice
class MacInputDevice : public InputDevice
{
public:
MacInputDevice(int devId);
@@ -168,12 +161,12 @@ public:
bool fakeMode();
void setFakeMode(bool fakemode);
int readBuffer(void* buffer);
protected:
PMacDevice mDevice;
};
class MacOutputDevice: public OutputDevice
class MacOutputDevice : public OutputDevice
{
public:
MacOutputDevice(int devId);
@@ -190,7 +183,7 @@ protected:
PMacDevice mDevice;
};
}
} // namespace Audio
#endif // TARGET_OSX
+6 -7
View File
@@ -8,8 +8,7 @@
using namespace Audio;
DataWindow::DataWindow()
{}
DataWindow::DataWindow() {}
DataWindow::~DataWindow()
{
@@ -145,7 +144,7 @@ size_t DataWindow::read(void* buffer, size_t length)
if (buffer)
memcpy(buffer, mData, length);
if (length < mFilled)
memmove(mData, mData+length, mFilled - length);
memmove(mData, mData + length, mFilled - length);
mFilled -= length;
}
return length;
@@ -195,18 +194,18 @@ size_t DataWindow::moveTo(DataWindow& dst, size_t size)
std::chrono::milliseconds DataWindow::getTimeLength(const Audio::Format& fmt) const
{
Lock l(mMutex);
return std::chrono::milliseconds(mFilled / sizeof(short) / fmt.channels() / (fmt.rate()/ 1000));
return std::chrono::milliseconds(mFilled / sizeof(short) / fmt.channels() / (fmt.rate() / 1000));
}
void DataWindow::makeStereoFromMono(DataWindow& dst, DataWindow& src)
{
Lock lockDst(dst.mMutex), lockSrc(src.mMutex);
dst.setCapacity(src.filled()*2);
dst.setCapacity(src.filled() * 2);
short* input = (short*)src.mutableData();
short* output = (short*)dst.mutableData();
for (int i=0; i<src.filled()/2; i++)
output[i*2] = output[i*2+1] = input[i];
for (int i = 0; i < src.filled() / 2; i++)
output[i * 2] = output[i * 2 + 1] = input[i];
dst.mFilled = src.filled() * 2;
}
+2 -2
View File
@@ -35,7 +35,7 @@ public:
short shortAt(size_t index) const;
void setShortAt(short value, size_t index);
void zero(size_t length);
size_t moveTo(DataWindow& dst, size_t size /* in bytes*/ );
size_t moveTo(DataWindow& dst, size_t size /* in bytes*/);
std::chrono::milliseconds getTimeLength(const Format& fmt) const;
@@ -47,5 +47,5 @@ protected:
size_t mFilled = 0;
size_t mCapacity = 0;
};
}
} // namespace Audio
#endif
+7 -11
View File
@@ -13,7 +13,8 @@ using namespace Audio;
// --- DevicePair ---
DevicePair::DevicePair()
:mConfig(nullptr), mDelegate(nullptr), mAec(false), mAgc(false), mAecFilter(AUDIO_MIC_BUFFER_LENGTH*10, AUDIO_MIC_BUFFER_LENGTH, AUDIO_SAMPLERATE), mAgcFilter(AUDIO_CHANNELS),
: mConfig(nullptr), mDelegate(nullptr), mAec(false), mAgc(false),
mAecFilter(AUDIO_MIC_BUFFER_LENGTH * 10, AUDIO_MIC_BUFFER_LENGTH, AUDIO_SAMPLERATE), mAgcFilter(AUDIO_CHANNELS),
mMonitoring(nullptr)
{
mInputBuffer.setCapacity(AUDIO_MIC_BUFFER_SIZE * (AUDIO_MIC_BUFFER_COUNT + 1));
@@ -176,7 +177,6 @@ void DevicePair::onMicData(const Format& f, const void* buffer, int length)
for (int blockIndex = 0; blockIndex < blocks; blockIndex++)
{
size_t wasProcessed = 0;
size_t wasProduced = mMicResampler.resample(f.mRate, // Source rate
@@ -193,12 +193,11 @@ void DevicePair::onMicData(const Format& f, const void* buffer, int length)
mInputBuffer.erase((int)Format().sizeFromTime(AUDIO_MIC_BUFFER_LENGTH));
}
}
void DevicePair::onSpkData(const Format& f, void* buffer, int length)
{
//ICELogMedia(<< "Audio::DevicePair::onSpkData() begin");
// ICELogMedia(<< "Audio::DevicePair::onSpkData() begin");
#ifdef DUMP_NATIVEOUTPUT
if (!mNativeOutputDump)
{
@@ -215,7 +214,6 @@ void DevicePair::onSpkData(const Format& f, void* buffer, int length)
int required = length - mOutputNativeData.filled();
if (required > 0)
{
// Find how much blocks must be received from RTP/decoder side
int nativeBufferSize = (int)nativeFormat.sizeFromTime(AUDIO_SPK_BUFFER_LENGTH);
int blocks = required / nativeBufferSize;
@@ -240,10 +238,8 @@ void DevicePair::onSpkData(const Format& f, void* buffer, int length)
// Resample these 10 milliseconds it to native format
size_t wasProcessed = 0;
size_t wasProduced = mSpkResampler.resample(Format().mRate,
mOutput10msBuffer.data(),
mOutput10msBuffer.capacity(),
wasProcessed, f.mRate,
size_t wasProduced = mSpkResampler.resample(Format().mRate, mOutput10msBuffer.data(),
mOutput10msBuffer.capacity(), wasProcessed, f.mRate,
mOutputNativeData.mutableData() + mOutputNativeData.filled(),
mOutputNativeData.capacity() - mOutputNativeData.filled());
mOutputNativeData.setFilled(mOutputNativeData.filled() + wasProduced);
@@ -265,13 +261,13 @@ void DevicePair::onSpkData(const Format& f, void* buffer, int length)
if (mMonitoring)
mMonitoring->onSpkData(f, buffer, length);
#define AEC_FRAME_SIZE (AUDIO_CHANNELS * (AUDIO_SAMPLERATE / 1000) * AEC_FRAME_TIME * sizeof(short))
#define AEC_FRAME_SIZE (AUDIO_CHANNELS * (AUDIO_SAMPLERATE / 1000) * AEC_FRAME_TIME * sizeof(short))
// AEC filter wants frames.
if (mAec)
{
int nrOfFrames = mAecSpkBuffer.filled() / AEC_FRAME_SIZE;
for (int frameIndex=0; frameIndex < nrOfFrames; frameIndex++)
for (int frameIndex = 0; frameIndex < nrOfFrames; frameIndex++)
mAecFilter.toSpeaker(mAecSpkBuffer.mutableData() + AEC_FRAME_SIZE * frameIndex);
mAecSpkBuffer.erase(nrOfFrames * AEC_FRAME_SIZE);
}
+10 -10
View File
@@ -11,16 +11,16 @@
#include "Audio_Resampler.h"
#include "Audio_DataWindow.h"
//#define DUMP_NATIVEOUTPUT
//#define DUMP_NATIVEINPUT
// #define DUMP_NATIVEOUTPUT
// #define DUMP_NATIVEINPUT
namespace Audio
{
class DevicePair: protected DataConnection
{
public:
class Delegate: public DataConnection
class DevicePair : protected DataConnection
{
public:
class Delegate : public DataConnection
{
public:
virtual void deviceChanged(DevicePair* dpair) = 0;
@@ -54,7 +54,7 @@ namespace Audio
Player& player();
protected:
protected:
VariantMap* mConfig;
PInputDevice mInput;
POutputDevice mOutput;
@@ -77,9 +77,9 @@ namespace Audio
void onMicData(const Format& f, const void* buffer, int length);
void onSpkData(const Format& f, void* buffer, int length);
void processMicData(const Format& f, void* buffer, int length);
};
};
typedef std::shared_ptr<DevicePair> PDevicePair;
}
typedef std::shared_ptr<DevicePair> PDevicePair;
} // namespace Audio
#endif
+115 -132
View File
@@ -39,14 +39,14 @@ public:
{
HINSTANCE mInstance;
HRESULT (WINAPI *DirectSoundCreate8)(LPGUID, LPDIRECTSOUND8 *, LPUNKNOWN);
HRESULT (WINAPI *DirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID);
HRESULT (WINAPI *DirectSoundEnumerateA)(LPDSENUMCALLBACKA, LPVOID);
HRESULT(WINAPI* DirectSoundCreate8)(LPGUID, LPDIRECTSOUND8*, LPUNKNOWN);
HRESULT(WINAPI* DirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID);
HRESULT(WINAPI* DirectSoundEnumerateA)(LPDSENUMCALLBACKA, LPVOID);
HRESULT (WINAPI *DirectSoundCaptureCreate8)(LPGUID, LPDIRECTSOUNDCAPTURE8* , LPUNKNOWN);
HRESULT (WINAPI *DirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW, LPVOID);
HRESULT (WINAPI *DirectSoundCaptureEnumerateA)(LPDSENUMCALLBACKA, LPVOID);
HRESULT (WINAPI *GetDeviceID)(LPCGUID src, LPGUID dst);
HRESULT(WINAPI* DirectSoundCaptureCreate8)(LPGUID, LPDIRECTSOUNDCAPTURE8*, LPUNKNOWN);
HRESULT(WINAPI* DirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW, LPVOID);
HRESULT(WINAPI* DirectSoundCaptureEnumerateA)(LPDSENUMCALLBACKA, LPVOID);
HRESULT(WINAPI* GetDeviceID)(LPCGUID src, LPGUID dst);
} mRoutines;
protected:
@@ -57,14 +57,11 @@ protected:
DSoundInit gDSoundInit;
DSoundInit::DSoundInit()
:mRefCount(0)
{
}
DSoundInit::DSoundInit() : mRefCount(0) {}
DSoundInit::~DSoundInit()
{
//Unload();
// Unload();
}
void DSoundInit::load()
@@ -77,16 +74,21 @@ void DSoundInit::load()
hr = ::CoInitialize(NULL);
//load the DirectSound DLL
// load the DirectSound DLL
mRoutines.mInstance = ::LoadLibraryW(L"dsound.dll");
if (!mRoutines.mInstance)
throw std::logic_error("Cannot load dsound.dll");
mRoutines.DirectSoundCaptureCreate8 = (HRESULT (WINAPI *)(LPGUID, LPDIRECTSOUNDCAPTURE8 *, LPUNKNOWN))::GetProcAddress(mRoutines.mInstance, "DirectSoundCaptureCreate8");
mRoutines.DirectSoundCaptureEnumerateW = (HRESULT (WINAPI *)(LPDSENUMCALLBACKW, LPVOID))::GetProcAddress(mRoutines.mInstance, "DirectSoundCaptureEnumerateW");
mRoutines.DirectSoundCreate8 = (HRESULT (WINAPI *)(LPGUID, LPDIRECTSOUND8 *, LPUNKNOWN))::GetProcAddress(mRoutines.mInstance, "DirectSoundCreate8");
mRoutines.DirectSoundEnumerateW = (HRESULT (WINAPI *)(LPDSENUMCALLBACKW, LPVOID))::GetProcAddress(mRoutines.mInstance, "DirectSoundEnumerateW");
mRoutines.GetDeviceID = (HRESULT (WINAPI*) (LPCGUID, LPGUID)) GetProcAddress(mRoutines.mInstance, "GetDeviceID");
mRoutines.DirectSoundCaptureCreate8 =
(HRESULT(WINAPI*)(LPGUID, LPDIRECTSOUNDCAPTURE8*, LPUNKNOWN))::GetProcAddress(mRoutines.mInstance,
"DirectSoundCaptureCreate8");
mRoutines.DirectSoundCaptureEnumerateW = (HRESULT(WINAPI*)(LPDSENUMCALLBACKW, LPVOID))::GetProcAddress(
mRoutines.mInstance, "DirectSoundCaptureEnumerateW");
mRoutines.DirectSoundCreate8 = (HRESULT(WINAPI*)(LPGUID, LPDIRECTSOUND8*, LPUNKNOWN))::GetProcAddress(
mRoutines.mInstance, "DirectSoundCreate8");
mRoutines.DirectSoundEnumerateW =
(HRESULT(WINAPI*)(LPDSENUMCALLBACKW, LPVOID))::GetProcAddress(mRoutines.mInstance, "DirectSoundEnumerateW");
mRoutines.GetDeviceID = (HRESULT(WINAPI*)(LPCGUID, LPGUID))GetProcAddress(mRoutines.mInstance, "GetDeviceID");
}
}
@@ -106,10 +108,7 @@ void DSoundInit::unload()
}
// --------------- VistaEnumerator ---------------------
VistaEnumerator::VistaEnumerator()
:mCollection(NULL), mDefaultDevice(NULL), mEnumerator(NULL), mDirection(eCapture)
{
}
VistaEnumerator::VistaEnumerator() : mCollection(NULL), mDefaultDevice(NULL), mEnumerator(NULL), mDirection(eCapture) {}
VistaEnumerator::~VistaEnumerator()
{
@@ -123,10 +122,8 @@ void VistaEnumerator::open(int direction)
mDirection = (direction == myMicrophone) ? eCapture : eRender;
HRESULT hr = CoCreateInstance(
CLSID_MMDeviceEnumerator, NULL,
CLSCTX_ALL, IID_IMMDeviceEnumerator,
(void**)&mEnumerator);
HRESULT hr =
CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&mEnumerator);
if (!mEnumerator)
return;
@@ -152,7 +149,7 @@ void VistaEnumerator::close()
if (mDefaultDevice)
{
//mDefaultDevice->Release();
// mDefaultDevice->Release();
mDefaultDevice = NULL;
}
@@ -162,7 +159,7 @@ void VistaEnumerator::close()
mEnumerator = NULL;
}
}
catch(...)
catch (...)
{
}
}
@@ -185,7 +182,7 @@ IMMDevice* VistaEnumerator::mapIndexToInterface(int index)
if (mmres != MMSYSERR_NOERROR)
return NULL;
id = (WCHAR*)_alloca(idSize*sizeof(WCHAR));
id = (WCHAR*)_alloca(idSize * sizeof(WCHAR));
mmres = waveInMessage((HWAVEIN)index, DRV_QUERYFUNCTIONINSTANCEID, (DWORD_PTR)id, idSize);
}
else
@@ -195,7 +192,7 @@ IMMDevice* VistaEnumerator::mapIndexToInterface(int index)
if (mmres != MMSYSERR_NOERROR)
return NULL;
id = (WCHAR*)_alloca(idSize*sizeof(WCHAR));
id = (WCHAR*)_alloca(idSize * sizeof(WCHAR));
mmres = waveOutMessage((HWAVEOUT)index, DRV_QUERYFUNCTIONINSTANCEID, (DWORD_PTR)id, idSize);
}
@@ -213,7 +210,7 @@ void VistaEnumerator::enumerate()
mNameList.clear();
int res = (int)count();
for (int i=0; i<res; i++)
for (int i = 0; i < res; i++)
{
IMMDevice* dev = mapIndexToInterface(i);
if (dev)
@@ -258,26 +255,23 @@ int VistaEnumerator::indexOfDefaultDevice()
if (mDirection == mySpeaker)
{
if (waveOutMessage((HWAVEOUT)WAVE_MAPPER, DRVM_MAPPER_CONSOLEVOICECOM_GET, (DWORD_PTR)&devID, (DWORD_PTR)&status) != MMSYSERR_NOERROR)
if (waveOutMessage((HWAVEOUT)WAVE_MAPPER, DRVM_MAPPER_CONSOLEVOICECOM_GET, (DWORD_PTR)&devID,
(DWORD_PTR)&status) != MMSYSERR_NOERROR)
waveOutMessage((HWAVEOUT)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&devID, (DWORD_PTR)&status);
}
else
{
if (waveInMessage((HWAVEIN)WAVE_MAPPER, DRVM_MAPPER_CONSOLEVOICECOM_GET, (DWORD_PTR)&devID, (DWORD_PTR)&status) != MMSYSERR_NOERROR)
if (waveInMessage((HWAVEIN)WAVE_MAPPER, DRVM_MAPPER_CONSOLEVOICECOM_GET, (DWORD_PTR)&devID,
(DWORD_PTR)&status) != MMSYSERR_NOERROR)
waveInMessage((HWAVEIN)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&devID, (DWORD_PTR)&status);
}
return devID;
}
// -------------- XpEnumerator ---------------
XpEnumerator::XpEnumerator()
:mDirection(-1)
{
}
XpEnumerator::XpEnumerator() : mDirection(-1) {}
XpEnumerator::~XpEnumerator()
{
}
XpEnumerator::~XpEnumerator() {}
void XpEnumerator::open(int direction)
{
@@ -285,7 +279,7 @@ void XpEnumerator::open(int direction)
if (direction == myMicrophone)
{
int count = waveInGetNumDevs();
for (int i=0; i<count; i++)
for (int i = 0; i < count; i++)
{
WAVEINCAPSW caps;
if (waveInGetDevCapsW(i, &caps, sizeof caps) == MMSYSERR_NOERROR)
@@ -297,7 +291,7 @@ void XpEnumerator::open(int direction)
else
{
int count = waveOutGetNumDevs();
for (int i=0; i<count; i++)
for (int i = 0; i < count; i++)
{
WAVEOUTCAPSW caps;
if (waveOutGetDevCapsW(i, &caps, sizeof caps) == MMSYSERR_NOERROR)
@@ -308,9 +302,7 @@ void XpEnumerator::open(int direction)
}
}
void XpEnumerator::close()
{
}
void XpEnumerator::close() {}
int XpEnumerator::count()
{
@@ -333,12 +325,14 @@ int XpEnumerator::indexOfDefaultDevice()
if (mDirection == mySpeaker)
{
if (waveOutMessage((HWAVEOUT)WAVE_MAPPER, DRVM_MAPPER_CONSOLEVOICECOM_GET, (DWORD_PTR)&devID, (DWORD_PTR)&status) != MMSYSERR_NOERROR)
if (waveOutMessage((HWAVEOUT)WAVE_MAPPER, DRVM_MAPPER_CONSOLEVOICECOM_GET, (DWORD_PTR)&devID,
(DWORD_PTR)&status) != MMSYSERR_NOERROR)
waveOutMessage((HWAVEOUT)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&devID, (DWORD_PTR)&status);
}
else
{
if (waveInMessage((HWAVEIN)WAVE_MAPPER, DRVM_MAPPER_CONSOLEVOICECOM_GET, (DWORD_PTR)&devID, (DWORD_PTR)&status) != MMSYSERR_NOERROR)
if (waveInMessage((HWAVEIN)WAVE_MAPPER, DRVM_MAPPER_CONSOLEVOICECOM_GET, (DWORD_PTR)&devID,
(DWORD_PTR)&status) != MMSYSERR_NOERROR)
waveInMessage((HWAVEIN)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&devID, (DWORD_PTR)&status);
}
return devID;
@@ -346,11 +340,12 @@ int XpEnumerator::indexOfDefaultDevice()
// -------- DSoundInputDevice ---------------
DSoundInputDevice::DSoundInputDevice(GUID deviceId)
:mSimulate(false), mBufferIndex(0), mGUID(deviceId), mThreadHandle(0), mDenoiser(AUDIO_SAMPLERATE), mEnableDenoiser(true),
mNullAudio(AUDIO_MIC_BUFFER_LENGTH, AUDIO_MIC_BUFFER_COUNT)
#ifdef AUDIO_DUMPINPUT
,mDump(AUDIO_SAMPLERATE)
#endif
: mSimulate(false), mBufferIndex(0), mGUID(deviceId), mThreadHandle(0), mDenoiser(AUDIO_SAMPLERATE),
mEnableDenoiser(true), mNullAudio(AUDIO_MIC_BUFFER_LENGTH, AUDIO_MIC_BUFFER_COUNT)
#ifdef AUDIO_DUMPINPUT
,
mDump(AUDIO_SAMPLERATE)
#endif
{
gDSoundInit.load();
@@ -359,7 +354,7 @@ DSoundInputDevice::DSoundInputDevice(GUID deviceId)
mDevice = NULL;
mBuffer = NULL;
mShutdownSignal = ::CreateEvent(NULL, FALSE, FALSE, NULL);
for (unsigned i=0; i<AUDIO_MIC_BUFFER_COUNT; i++)
for (unsigned i = 0; i < AUDIO_MIC_BUFFER_COUNT; i++)
{
mEventArray[i].dwOffset = (i + 1) * AUDIO_MIC_BUFFER_SIZE - 1;
mEventSignals[i] = mEventArray[i].hEventNotify = ::CreateEvent(NULL, TRUE, FALSE, NULL);
@@ -371,7 +366,7 @@ DSoundInputDevice::~DSoundInputDevice()
{
close();
::CloseHandle(mShutdownSignal);
for (int i=0; i<AUDIO_MIC_BUFFER_COUNT; i++)
for (int i = 0; i < AUDIO_MIC_BUFFER_COUNT; i++)
::CloseHandle(mEventArray[i].hEventNotify);
gDSoundInit.unload();
@@ -389,13 +384,12 @@ bool DSoundInputDevice::isSimulate() const
void DSoundInputDevice::openDevice()
{
ICELogInfo(<< "Open DirectSound audio input.")
::CoInitialize(NULL);
ICELogInfo(<< "Open DirectSound audio input.")::CoInitialize(NULL);
Lock l(mGuard);
// Ensure if GUID is not null
if (IsEqualGUID(mGUID, GUID_NULL))
{
setSimulate( true );
setSimulate(true);
return;
}
@@ -404,24 +398,28 @@ void DSoundInputDevice::openDevice()
mDump.open(L"audioinput.wav");
#endif
mNextBuffer = 0; mDevice = NULL; IUnknown* unk = NULL; mBuffer = NULL;
mNextBuffer = 0;
mDevice = NULL;
IUnknown* unk = NULL;
mBuffer = NULL;
DSoundHelper::checkComResult(gDSoundInit.mRoutines.DirectSoundCaptureCreate8(&mGUID, &mDevice, NULL));
WAVEFORMATEX wfx;
memset(&wfx, 0, sizeof(wfx));
//wfx.cbSize = sizeof(wfx);
// wfx.cbSize = sizeof(wfx);
wfx.nChannels = AUDIO_CHANNELS;
wfx.nSamplesPerSec = AUDIO_SAMPLERATE;
wfx.wBitsPerSample = 16;
wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8;;
wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8;
;
wfx.nAvgBytesPerSec = AUDIO_SAMPLERATE * 2 * AUDIO_CHANNELS;
wfx.wFormatTag = WAVE_FORMAT_PCM;
DSCBUFFERDESC dsbd;
ZeroMemory(&dsbd, sizeof(dsbd));
dsbd.dwSize = sizeof(DSCBUFFERDESC);
dsbd.dwFlags = 0;//DSBCAPS_CTRLPOSITIONNOTIFY;
dsbd.dwFlags = 0; // DSBCAPS_CTRLPOSITIONNOTIFY;
dsbd.dwBufferBytes = AUDIO_MIC_BUFFER_COUNT * AUDIO_MIC_BUFFER_SIZE;
dsbd.lpwfxFormat = &wfx;
dsbd.dwFXCount = 0;
@@ -434,7 +432,7 @@ void DSoundInputDevice::openDevice()
DSoundHelper::checkComResult(mNotifications->SetNotificationPositions(AUDIO_MIC_BUFFER_COUNT, mEventArray));
DSoundHelper::checkComResult(mBuffer->Start(DSCBSTART_LOOPING));
dscb->Release();
setSimulate( false );
setSimulate(false);
}
bool DSoundInputDevice::open()
@@ -452,7 +450,7 @@ bool DSoundInputDevice::open()
void DSoundInputDevice::closeDevice()
{
ICELogInfo(<<"Close DirectSound audio input");
ICELogInfo(<< "Close DirectSound audio input");
Lock l(mGuard);
#ifdef AUDIO_DUMPINPUT
@@ -505,7 +503,7 @@ bool DSoundInputDevice::tryReadBuffer(void* buffer)
// Ensure device exists
if (!mDevice)
{
setSimulate( true );
setSimulate(true);
return false;
}
@@ -524,9 +522,10 @@ bool DSoundInputDevice::tryReadBuffer(void* buffer)
try
{
if (::WaitForSingleObject(mEventArray[mNextBuffer].hEventNotify, AUDIO_MIC_BUFFER_COUNT * AUDIO_MIC_BUFFER_LENGTH * 4) != WAIT_OBJECT_0)
if (::WaitForSingleObject(mEventArray[mNextBuffer].hEventNotify,
AUDIO_MIC_BUFFER_COUNT * AUDIO_MIC_BUFFER_LENGTH * 4) != WAIT_OBJECT_0)
{
setSimulate( true );
setSimulate(true);
return false;
}
@@ -534,7 +533,7 @@ bool DSoundInputDevice::tryReadBuffer(void* buffer)
if (::WaitForMultipleObjects(AUDIO_MIC_BUFFER_COUNT, mEventSignals, TRUE, 0) != WAIT_TIMEOUT)
{
// Possible overflow. Consider current buffer resulting. Reset ALL events.
for (int i = 0; i<AUDIO_MIC_BUFFER_COUNT; i++)
for (int i = 0; i < AUDIO_MIC_BUFFER_COUNT; i++)
ResetEvent(mEventArray[i].hEventNotify);
}
else
@@ -543,11 +542,12 @@ bool DSoundInputDevice::tryReadBuffer(void* buffer)
// Find the buffer start offset
mReadOffset = mNextBuffer * AUDIO_MIC_BUFFER_SIZE;
//increase the buffer's index
// increase the buffer's index
if (++mNextBuffer == AUDIO_MIC_BUFFER_COUNT)
mNextBuffer = 0;
LPVOID ptr1 = NULL, ptr2 = NULL; DWORD len1 = 0, len2 = 0;
LPVOID ptr1 = NULL, ptr2 = NULL;
DWORD len1 = 0, len2 = 0;
DSoundHelper::checkComResult(mBuffer->Lock(mReadOffset, AUDIO_MIC_BUFFER_SIZE, &ptr1, &len1, &ptr2, &len2, 0));
// Copy&Enqueue captured data to mQueue
@@ -574,9 +574,9 @@ bool DSoundInputDevice::tryReadBuffer(void* buffer)
return true;
}
catch(...)
catch (...)
{
setSimulate( true );
setSimulate(true);
}
return false;
}
@@ -585,8 +585,7 @@ void DSoundInputDevice::setSimulate(bool s)
{
if (!mSimulate && s)
mNullAudio.start();
else
if (mSimulate && !s)
else if (mSimulate && !s)
mNullAudio.stop();
mSimulate = s;
@@ -599,7 +598,7 @@ Format DSoundInputDevice::getFormat()
int DSoundInputDevice::readBuffer(void* buffer)
{
//Lock lock(mGuard);
// Lock lock(mGuard);
if (mRefCount <= 0 || isSimulate())
return 0;
@@ -642,10 +641,8 @@ void DSoundInputDevice::threadProc(void* arg)
DSoundOutputDevice::DSoundOutputDevice(GUID deviceId)
:mDevice(NULL), mPrimaryBuffer(NULL), mBuffer(NULL),
mWriteOffset(0), mPlayedSamples(0), mTotalPlayed(0), mTail(0),
mThreadHandle(0), mSimulate(false), mGUID(deviceId),
mNullAudio(AUDIO_SPK_BUFFER_LENGTH, AUDIO_SPK_BUFFER_COUNT)
: mDevice(NULL), mPrimaryBuffer(NULL), mBuffer(NULL), mWriteOffset(0), mPlayedSamples(0), mTotalPlayed(0), mTail(0),
mThreadHandle(0), mSimulate(false), mGUID(deviceId), mNullAudio(AUDIO_SPK_BUFFER_LENGTH, AUDIO_SPK_BUFFER_COUNT)
{
gDSoundInit.load();
mShutdownSignal = ::CreateEvent(NULL, FALSE, FALSE, NULL);
@@ -700,7 +697,7 @@ void DSoundOutputDevice::openDevice()
ICELogInfo(<< "Open DirectSound audio output");
if (IsEqualGUID(mGUID, GUID_NULL))
{
setSimulate( true );
setSimulate(true);
return;
}
@@ -729,10 +726,10 @@ void DSoundOutputDevice::openDevice()
dsbd.dwSize = sizeof(DSBUFFERDESC);
dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
dsbd.dwBufferBytes = 0;
dsbd.lpwfxFormat = NULL;//&wfx;
dsbd.lpwfxFormat = NULL; //&wfx;
dsbd.guid3DAlgorithm = DS3DALG_DEFAULT;
DSoundHelper::checkComResult(mDevice->CreateSoundBuffer(&dsbd, &mPrimaryBuffer, NULL ));
DSoundHelper::checkComResult(mDevice->CreateSoundBuffer(&dsbd, &mPrimaryBuffer, NULL));
DSBCAPS caps;
caps.dwSize = sizeof(caps);
caps.dwFlags = 0;
@@ -751,14 +748,16 @@ void DSoundOutputDevice::openDevice()
DSoundHelper::checkComResult(mDevice->CreateSoundBuffer(&dsbd, &mBuffer, NULL));
// Fill the buffer with silence
LPVOID ptr1 = NULL, ptr2 = NULL; DWORD len1 = 0, len2 = 0;
DSoundHelper::checkComResult(mBuffer->Lock(0, AUDIO_SPK_BUFFER_SIZE * AUDIO_SPK_BUFFER_COUNT, &ptr1, &len1, &ptr2, &len2, 0));
LPVOID ptr1 = NULL, ptr2 = NULL;
DWORD len1 = 0, len2 = 0;
DSoundHelper::checkComResult(
mBuffer->Lock(0, AUDIO_SPK_BUFFER_SIZE * AUDIO_SPK_BUFFER_COUNT, &ptr1, &len1, &ptr2, &len2, 0));
if (len1 && ptr1)
memset(ptr1, 0, len1);
if (len2 && ptr2)
memset(ptr2, 0, len2);
DSoundHelper::checkComResult(mBuffer->Unlock(ptr1, len1, ptr2, len2));
DSoundHelper::checkComResult(mBuffer->Play(0,0,DSBPLAY_LOOPING));
DSoundHelper::checkComResult(mBuffer->Play(0, 0, DSBPLAY_LOOPING));
mBuffer->GetCurrentPosition(NULL, &mWriteCursor);
}
@@ -804,8 +803,9 @@ bool DSoundOutputDevice::getMediaFrame()
if (mConnection)
mConnection->onSpkData(getFormat(), mMediaFrame, sizeof mMediaFrame);
}
catch(...)
{}
catch (...)
{
}
return true;
}
@@ -833,7 +833,8 @@ bool DSoundOutputDevice::process()
offset %= mBufferSize;
// See what we can write
LPVOID ptr1 = NULL, ptr2 = NULL; DWORD len1 = 0, len2 = 0;
LPVOID ptr1 = NULL, ptr2 = NULL;
DWORD len1 = 0, len2 = 0;
DSoundHelper::checkComResult(mBuffer->Lock(offset, AUDIO_SPK_BUFFER_SIZE, &ptr1, &len1, &ptr2, &len2, 0));
assert(ptr2 == NULL);
@@ -884,12 +885,12 @@ void DSoundOutputDevice::threadProc(void* arg)
impl->restoreBuffer();
impl->process();
}
catch(const Exception& e)
catch (const Exception& e)
{
ICELogError(<< "DirectSound output failed with code = " << e.code() << ", subcode = " << e.subcode());
impl->setSimulate(true);
}
catch(...)
catch (...)
{
ICELogError(<< "DirectSound output failed due to unexpected exception.");
impl->setSimulate(true);
@@ -925,9 +926,9 @@ bool DSoundOutputDevice::closing()
return false;
}
typedef WINUSERAPI HRESULT (WINAPI *LPFNDLLGETCLASSOBJECT) (const CLSID &, const IID &, void **);
typedef WINUSERAPI HRESULT(WINAPI* LPFNDLLGETCLASSOBJECT)(const CLSID&, const IID&, void**);
HRESULT DirectSoundPrivateCreate (OUT LPKSPROPERTYSET * ppKsPropertySet)
HRESULT DirectSoundPrivateCreate(OUT LPKSPROPERTYSET* ppKsPropertySet)
{
HMODULE hLibDsound = NULL;
LPFNDLLGETCLASSOBJECT pfnDllGetClassObject = NULL;
@@ -938,49 +939,48 @@ HRESULT DirectSoundPrivateCreate (OUT LPKSPROPERTYSET * ppKsPropertySet)
// Load dsound.dll
hLibDsound = LoadLibrary(TEXT("dsound.dll"));
if(!hLibDsound)
if (!hLibDsound)
{
hr = DSERR_GENERIC;
}
// Find DllGetClassObject
if(SUCCEEDED(hr))
if (SUCCEEDED(hr))
{
pfnDllGetClassObject =
(LPFNDLLGETCLASSOBJECT)GetProcAddress ( hLibDsound, "DllGetClassObject" );
pfnDllGetClassObject = (LPFNDLLGETCLASSOBJECT)GetProcAddress(hLibDsound, "DllGetClassObject");
if(!pfnDllGetClassObject)
if (!pfnDllGetClassObject)
{
hr = DSERR_GENERIC;
}
}
// Create a class factory object
if(SUCCEEDED(hr))
if (SUCCEEDED(hr))
{
hr = pfnDllGetClassObject (CLSID_DirectSoundPrivate, IID_IClassFactory, (LPVOID *)&pClassFactory );
hr = pfnDllGetClassObject(CLSID_DirectSoundPrivate, IID_IClassFactory, (LPVOID*)&pClassFactory);
}
// Create the DirectSoundPrivate object and query for an IKsPropertySet
// interface
if(SUCCEEDED(hr))
if (SUCCEEDED(hr))
{
hr = pClassFactory->CreateInstance ( NULL, IID_IKsPropertySet, (LPVOID *)&pKsPropertySet );
hr = pClassFactory->CreateInstance(NULL, IID_IKsPropertySet, (LPVOID*)&pKsPropertySet);
}
// Release the class factory
if(pClassFactory)
if (pClassFactory)
{
pClassFactory->Release();
}
// Handle final success or failure
if(SUCCEEDED(hr))
if (SUCCEEDED(hr))
{
*ppKsPropertySet = pKsPropertySet;
}
else if(pKsPropertySet)
else if (pKsPropertySet)
{
pKsPropertySet->Release();
}
@@ -990,7 +990,7 @@ HRESULT DirectSoundPrivateCreate (OUT LPKSPROPERTYSET * ppKsPropertySet)
return hr;
}
BOOL GetInfoFromDSoundGUID( GUID i_sGUID, int &dwWaveID)
BOOL GetInfoFromDSoundGUID(GUID i_sGUID, int& dwWaveID)
{
LPKSPROPERTYSET pKsPropertySet = NULL;
HRESULT hr;
@@ -999,45 +999,34 @@ BOOL GetInfoFromDSoundGUID( GUID i_sGUID, int &dwWaveID)
PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_DATA psDirectSoundDeviceDescription = NULL;
DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_DATA sDirectSoundDeviceDescription;
memset(&sDirectSoundDeviceDescription,0,sizeof(sDirectSoundDeviceDescription));
hr = DirectSoundPrivateCreate( &pKsPropertySet );
if(SUCCEEDED(hr))
memset(&sDirectSoundDeviceDescription, 0, sizeof(sDirectSoundDeviceDescription));
hr = DirectSoundPrivateCreate(&pKsPropertySet);
if (SUCCEEDED(hr))
{
ULONG ulBytesReturned = 0;
sDirectSoundDeviceDescription.DeviceId = i_sGUID;
// On the first call the final size is unknown so pass the size of the struct in order to receive
// "Type" and "DataFlow" values, ulBytesReturned will be populated with bytes required for struct+strings.
hr = pKsPropertySet->Get(DSPROPSETID_DirectSoundDevice,
DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION,
NULL,
0,
&sDirectSoundDeviceDescription,
sizeof(sDirectSoundDeviceDescription),
&ulBytesReturned
);
hr = pKsPropertySet->Get(DSPROPSETID_DirectSoundDevice, DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION, NULL, 0,
&sDirectSoundDeviceDescription, sizeof(sDirectSoundDeviceDescription),
&ulBytesReturned);
if (ulBytesReturned)
{
// On the first call it notifies us of the required amount of memory in order to receive the strings.
// Allocate the required memory, the strings will be pointed to the memory space directly after the struct.
psDirectSoundDeviceDescription = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_DATA)new BYTE[ulBytesReturned];
psDirectSoundDeviceDescription = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_DATA) new BYTE[ulBytesReturned];
*psDirectSoundDeviceDescription = sDirectSoundDeviceDescription;
hr = pKsPropertySet->Get(DSPROPSETID_DirectSoundDevice,
DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION,
NULL,
0,
psDirectSoundDeviceDescription,
ulBytesReturned,
&ulBytesReturned
);
hr = pKsPropertySet->Get(DSPROPSETID_DirectSoundDevice, DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION, NULL, 0,
psDirectSoundDeviceDescription, ulBytesReturned, &ulBytesReturned);
dwWaveID = psDirectSoundDeviceDescription->WaveDeviceId;
/*Description = psDirectSoundDeviceDescription->Description;
Module = psDirectSoundDeviceDescription->Module;
Interface = psDirectSoundDeviceDescription->Interface;*/
delete [] psDirectSoundDeviceDescription;
delete[] psDirectSoundDeviceDescription;
retval = TRUE;
}
@@ -1053,16 +1042,10 @@ struct EnumResult
GUID mGuid;
};
BOOL CALLBACK DSEnumCallback(
LPGUID lpGuid,
LPCTSTR lpcstrDescription,
LPCTSTR lpcstrModule,
LPVOID lpContext
)
BOOL CALLBACK DSEnumCallback(LPGUID lpGuid, LPCTSTR lpcstrDescription, LPCTSTR lpcstrModule, LPVOID lpContext)
{
if (lpGuid)
{
int devId = -1;
GetInfoFromDSoundGUID(*lpGuid, devId);
EnumResult* er = (EnumResult*)lpContext;
+7 -7
View File
@@ -22,7 +22,7 @@
#include <EndpointVolume.h>
#include <MMDeviceAPI.h>
#if defined(_MSC_VER)
# include <Functiondiscoverykeys_devpkey.h>
#include <Functiondiscoverykeys_devpkey.h>
#endif
#include <vector>
#include <string>
@@ -31,7 +31,7 @@
namespace Audio
{
class VistaEnumerator: public Enumerator
class VistaEnumerator : public Enumerator
{
public:
VistaEnumerator();
@@ -56,7 +56,7 @@ protected:
IMMDevice* mapIndexToInterface(int index);
};
class XpEnumerator: public Enumerator
class XpEnumerator : public Enumerator
{
public:
XpEnumerator();
@@ -83,10 +83,10 @@ public:
};
#if !defined(_MSC_VER)
typedef struct IDirectSoundNotify8 *LPDIRECTSOUNDNOTIFY8;
typedef struct IDirectSoundNotify8* LPDIRECTSOUNDNOTIFY8;
#endif
class DSoundInputDevice: public InputDevice
class DSoundInputDevice : public InputDevice
{
public:
DSoundInputDevice(GUID deviceId);
@@ -136,7 +136,7 @@ protected:
static void threadProc(void* arg);
};
class DSoundOutputDevice: public OutputDevice
class DSoundOutputDevice : public OutputDevice
{
public:
DSoundOutputDevice(GUID deviceId);
@@ -182,6 +182,6 @@ protected:
static void threadProc(void* arg);
};
}
} // namespace Audio
#endif
+9 -10
View File
@@ -4,7 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifdef TARGET_WIN
# include <WinSock2.h>
#include <WinSock2.h>
#endif
#include <assert.h>
@@ -39,9 +39,7 @@ void TimeSource::start()
#endif
}
void TimeSource::stop()
{
}
void TimeSource::stop() {}
unsigned TimeSource::time()
{
@@ -50,15 +48,15 @@ unsigned TimeSource::time()
if (!QueryPerformanceCounter(&c))
throw Exception(ERR_QPC, GetLastError());
//find the f
// find the f
double f = (double)mFreq.QuadPart / 1000.0;
//find the difference
// find the difference
unsigned __int64 diff = c.QuadPart - mCounter.QuadPart;
mCounter.QuadPart = c.QuadPart;
diff = (unsigned __int64)((double)diff / f + 0.5); //get ms
diff = (unsigned __int64)((double)diff / f + 0.5); // get ms
diff += mTailTime;
if (diff > mDepthTime)
@@ -68,8 +66,8 @@ unsigned TimeSource::time()
}
else
{
mTailTime = (unsigned )(diff % (unsigned __int64)mQuantTime);
unsigned int t = (unsigned )(diff / (unsigned __int64)mQuantTime);
mTailTime = (unsigned)(diff % (unsigned __int64)mQuantTime);
unsigned int t = (unsigned)(diff / (unsigned __int64)mQuantTime);
return t * mQuantTime;
}
#endif
@@ -103,7 +101,8 @@ unsigned TimeSource::time()
// --- StubTimer ---
StubTimer::StubTimer(int bufferTime, int bufferCount)
:mBufferTime(bufferTime), mBufferCount(bufferCount), mTimeSource(bufferTime, bufferCount), mActive(false), mCurrentTime(0)
: mBufferTime(bufferTime), mBufferCount(bufferCount), mTimeSource(bufferTime, bufferCount), mActive(false),
mCurrentTime(0)
{
#ifdef TARGET_WIN
mStubSignal = ::CreateEvent(NULL, FALSE, FALSE, NULL);
+16 -16
View File
@@ -10,15 +10,15 @@
#include <EndpointVolume.h>
#include <MMDeviceAPI.h>
#if defined(_MSC_VER)
# include <Functiondiscoverykeys_devpkey.h>
#include <Functiondiscoverykeys_devpkey.h>
#endif
#endif
#if defined(TARGET_OSX) || defined(TARGET_IOS)
# include <AudioUnit/AudioUnit.h>
# include <AudioToolbox/AudioConverter.h>
# include <AudioToolbox/AudioServices.h>
# include <mach/mach_time.h>
#include <AudioUnit/AudioUnit.h>
#include <AudioToolbox/AudioConverter.h>
#include <AudioToolbox/AudioServices.h>
#include <mach/mach_time.h>
#endif
#include <vector>
@@ -27,9 +27,9 @@
namespace Audio
{
class TimeSource
{
protected:
class TimeSource
{
protected:
#ifdef TARGET_WIN
LARGE_INTEGER mCounter; /// Current value from QPC.
LARGE_INTEGER mFreq; /// Current frequency from QPC.
@@ -45,25 +45,25 @@ namespace Audio
unsigned mDepthTime; /// Number of available time quants.
unsigned mTailTime; /// Not-accounted milliseconds.
public:
public:
TimeSource(int quantTime, int nrOfQuants);
~TimeSource() = default;
void start();
void stop();
unsigned time();
};
};
class StubTimer
{
public:
class StubTimer
{
public:
StubTimer(int bufferTime, int bufferCount);
~StubTimer();
void start();
void stop();
void waitForBuffer();
protected:
protected:
unsigned mBufferTime;
unsigned mBufferCount;
unsigned mCurrentTime;
@@ -72,7 +72,7 @@ namespace Audio
HANDLE mStubSignal;
#endif
bool mActive;
};
}
};
} // namespace Audio
#endif
+20 -38
View File
@@ -7,16 +7,16 @@
#include "../helper/HL_OsVersion.h"
#if !defined(USE_NULL_AUDIO)
# ifdef TARGET_WIN
# include "Audio_Wmme.h"
# include "Audio_DirectSound.h"
# endif
# ifdef TARGET_OSX
# include "Audio_CoreAudio.h"
# endif
# ifdef TARGET_ANDROID
# include "Audio_Android.h"
# endif
#ifdef TARGET_WIN
#include "Audio_Wmme.h"
#include "Audio_DirectSound.h"
#endif
#ifdef TARGET_OSX
#include "Audio_CoreAudio.h"
#endif
#ifdef TARGET_ANDROID
#include "Audio_Android.h"
#endif
#endif
#include "Audio_Helper.h"
@@ -24,14 +24,9 @@
using namespace Audio;
Device::Device()
:mConnection(nullptr)
{
}
Device::Device() : mConnection(nullptr) {}
Device::~Device()
{
}
Device::~Device() {}
void Device::setConnection(DataConnection* connection)
@@ -44,13 +39,9 @@ DataConnection* Device::connection()
return mConnection;
}
InputDevice::InputDevice()
{
}
InputDevice::InputDevice() {}
InputDevice::~InputDevice()
{
}
InputDevice::~InputDevice() {}
InputDevice* InputDevice::make(int devId)
{
@@ -71,13 +62,9 @@ InputDevice* InputDevice::make(int devId)
return nullptr;
}
OutputDevice::OutputDevice()
{
}
OutputDevice::OutputDevice() {}
OutputDevice::~OutputDevice()
{
}
OutputDevice::~OutputDevice() {}
OutputDevice* OutputDevice::make(int devId)
{
@@ -85,7 +72,7 @@ OutputDevice* OutputDevice::make(int devId)
return new NullOutputDevice();
#else
#if defined(TARGET_WIN)
//return new WmmeOutputDevice(index);
// return new WmmeOutputDevice(index);
return new DSoundOutputDevice(DSoundHelper::deviceId2Guid(devId, false));
#endif
#ifdef TARGET_OSX
@@ -100,13 +87,9 @@ OutputDevice* OutputDevice::make(int devId)
// --- Enumerator ---
Enumerator::Enumerator()
{
}
Enumerator::Enumerator() {}
Enumerator::~Enumerator()
{
}
Enumerator::~Enumerator() {}
int Enumerator::nameToIndex(const std::tstring& name)
{
@@ -119,7 +102,6 @@ int Enumerator::nameToIndex(const std::tstring& name)
Enumerator* Enumerator::make(bool useNull)
{
if (useNull)
return new NullEnumerator();
#ifndef USE_NULL_AUDIO
@@ -147,7 +129,7 @@ OsEngine* OsEngine::instance()
#ifdef TARGET_ANDROID
return nullptr; // As we use Oboe library for now
//return &OpenSLEngine::instance();
// return &OpenSLEngine::instance();
#endif
return nullptr;
+14 -42
View File
@@ -27,34 +27,18 @@ struct Format
int mRate;
int mChannels;
Format()
:mRate(AUDIO_SAMPLERATE), mChannels(AUDIO_CHANNELS)
{}
Format() : mRate(AUDIO_SAMPLERATE), mChannels(AUDIO_CHANNELS) {}
Format(int rate, int channels)
:mRate(rate), mChannels(channels)
{}
Format(int rate, int channels) : mRate(rate), mChannels(channels) {}
size_t samplesFromSize(size_t length) const
{
return length / 2 / mChannels;
}
size_t samplesFromSize(size_t length) const { return length / 2 / mChannels; }
// Returns milliseconds
float timeFromSize(size_t length) const
{
return float(samplesFromSize(length) / (mRate / 1000.0));
}
float timeFromSize(size_t length) const { return float(samplesFromSize(length) / (mRate / 1000.0)); }
float sizeFromTime(size_t milliseconds) const
{
return float((milliseconds * mRate) / 500.0 * mChannels);
}
float sizeFromTime(size_t milliseconds) const { return float((milliseconds * mRate) / 500.0 * mChannels); }
size_t sizeFromTime(std::chrono::milliseconds ms) const
{
return sizeFromTime(ms.count());
}
size_t sizeFromTime(std::chrono::milliseconds ms) const { return sizeFromTime(ms.count()); }
std::string toString()
{
@@ -63,26 +47,13 @@ struct Format
return std::string(buffer);
}
bool operator == (const Format& rhs) const
{
return mRate == rhs.mRate && mChannels == rhs.mChannels;
}
bool operator==(const Format& rhs) const { return mRate == rhs.mRate && mChannels == rhs.mChannels; }
bool operator != (const Format& rhs) const
{
return mRate != rhs.mRate || mChannels != rhs.mChannels;
}
bool operator!=(const Format& rhs) const { return mRate != rhs.mRate || mChannels != rhs.mChannels; }
int rate() const
{
return mRate;
}
int channels() const
{
return mChannels;
}
int rate() const { return mRate; }
int channels() const { return mChannels; }
};
class DataConnection
@@ -105,12 +76,13 @@ public:
virtual bool open() = 0;
virtual void close() = 0;
virtual Format getFormat() = 0;
protected:
DataConnection* mConnection;
};
class InputDevice: public Device
class InputDevice : public Device
{
public:
InputDevice();
@@ -120,7 +92,7 @@ public:
};
typedef std::shared_ptr<InputDevice> PInputDevice;
class OutputDevice: public Device
class OutputDevice : public Device
{
public:
OutputDevice();
@@ -156,6 +128,6 @@ public:
static OsEngine* instance();
};
};
}; // namespace Audio
#endif
+23 -30
View File
@@ -28,9 +28,7 @@ Mixer::Stream::Stream()
mData.setCapacity(AUDIO_SPK_BUFFER_SIZE * AUDIO_SPK_BUFFER_COUNT);
}
Mixer::Stream::~Stream()
{
}
Mixer::Stream::~Stream() {}
void Mixer::Stream::setSsrc(unsigned ssrc)
{
@@ -73,7 +71,9 @@ void Mixer::Stream::addPcm(int rate, const void* input, int length)
if (mTempBuffer.size() < outputSize)
mTempBuffer.resize(outputSize);
Resampler* resampler = (rate == 8000) ? &mResampler8 : ((rate == 16000) ? &mResampler16 : ((rate == 32000) ? &mResampler32 : &mResampler48));
Resampler* resampler = (rate == 8000)
? &mResampler8
: ((rate == 16000) ? &mResampler16 : ((rate == 32000) ? &mResampler32 : &mResampler48));
size_t inputProcessed = 0;
resampler->processBuffer(input, length, inputProcessed, mTempBuffer.mutableData(), outputSize);
// inputProcessed result value is ignored here - rate will be 8/16/32/48k, inputProcessed is equal to length
@@ -88,14 +88,12 @@ Mixer::Mixer()
mOutput.setCapacity(32768);
}
Mixer::~Mixer()
{
}
Mixer::~Mixer() {}
void Mixer::unregisterChannel(void* channel)
{
Lock l(mMutex);
for (int i=0; i<AUDIO_MIX_CHANNEL_COUNT; i++)
for (int i = 0; i < AUDIO_MIX_CHANNEL_COUNT; i++)
{
Stream& c = mChannelList[i];
if (c.active() && c.context() == channel)
@@ -110,7 +108,7 @@ void Mixer::unregisterChannel(void* channel)
void Mixer::clear(void* context, unsigned ssrc)
{
Lock l(mMutex);
for (int i=0; i<AUDIO_MIX_CHANNEL_COUNT; i++)
for (int i = 0; i < AUDIO_MIX_CHANNEL_COUNT; i++)
{
Stream& c = mChannelList[i];
if (c.active() && c.context() == context && c.ssrc() == ssrc)
@@ -127,7 +125,7 @@ Mixer::Stream* Mixer::allocateChannel(void* context, unsigned ssrc)
// Allocate new channel
Lock l(mMutex);
Stream* channel;
for (int i=0; i<AUDIO_MIX_CHANNEL_COUNT;i++)
for (int i = 0; i < AUDIO_MIX_CHANNEL_COUNT; i++)
{
channel = &mChannelList[i];
if (!channel->active())
@@ -143,9 +141,7 @@ Mixer::Stream* Mixer::allocateChannel(void* context, unsigned ssrc)
return NULL;
}
void Mixer::addPcm(void* context, unsigned ssrc,
const void* inputData, int inputLength,
int inputRate, bool fadeOut)
void Mixer::addPcm(void* context, unsigned ssrc, const void* inputData, int inputLength, int inputRate, bool fadeOut)
{
assert(inputRate == 8000 || inputRate == 16000 || inputRate == 32000);
@@ -155,7 +151,7 @@ void Mixer::addPcm(void* context, unsigned ssrc,
// Locate a channel
Stream* channel = NULL;
for (i=0; i<AUDIO_MIX_CHANNEL_COUNT && !channel; i++)
for (i = 0; i < AUDIO_MIX_CHANNEL_COUNT && !channel; i++)
{
Stream& c = mChannelList[i];
if (c.active() && c.context() == context && c.ssrc() == ssrc)
@@ -181,7 +177,7 @@ void Mixer::addPcm(void* context, unsigned ssrc, Audio::DataWindow& w, int rate,
// Locate a channel
Stream* channel = NULL;
for (i=0; i<AUDIO_MIX_CHANNEL_COUNT && !channel; i++)
for (i = 0; i < AUDIO_MIX_CHANNEL_COUNT && !channel; i++)
{
Stream& c = mChannelList[i];
if (c.active() && c.context() == context && c.ssrc() == ssrc)
@@ -195,7 +191,7 @@ void Mixer::addPcm(void* context, unsigned ssrc, Audio::DataWindow& w, int rate,
}
channel->addPcm(rate, w.data(), w.filled());
//ICELogSpecial(<<"Mixer stream " << int(this) << " has " << w.filled() << " bytes");
// ICELogSpecial(<<"Mixer stream " << int(this) << " has " << w.filled() << " bytes");
}
void Mixer::mix()
@@ -217,7 +213,7 @@ void Mixer::mix()
// Build active channel map
Stream* channelList[AUDIO_MIX_CHANNEL_COUNT];
int activeCounter = 0;
for (int i=0; i<AUDIO_MIX_CHANNEL_COUNT; i++)
for (int i = 0; i < AUDIO_MIX_CHANNEL_COUNT; i++)
if (mChannelList[i].active())
channelList[activeCounter++] = &mChannelList[i];
@@ -239,10 +235,9 @@ void Mixer::mix()
// Erase copied audio samples
audio.data().erase(audio.data().filled());
//ICELogSpecial(<<"Length of mixer stream " << audio.data().filled());
// ICELogSpecial(<<"Length of mixer stream " << audio.data().filled());
}
else
if (activeCounter == 2)
else if (activeCounter == 2)
{
Stream& audio1 = *channelList[0];
Stream& audio2 = *channelList[1];
@@ -257,7 +252,7 @@ void Mixer::mix()
available = maxsize - filled;
short sample = 0;
for (int i=0; i<available; i++)
for (int i = 0; i < available; i++)
{
short sample1 = filled1 > i ? audio1.data().shortAt(i) : 0;
short sample2 = filled2 > i ? audio2.data().shortAt(i) : 0;
@@ -265,8 +260,8 @@ void Mixer::mix()
mOutput.add(sample);
}
audio1.data().erase(available*2);
audio2.data().erase(available*2);
audio1.data().erase(available * 2);
audio2.data().erase(available * 2);
}
else
{
@@ -275,7 +270,7 @@ void Mixer::mix()
sample = 0;
sourceCounter = 0;
processed = 0;
for (int i=0; i<activeCounter; i++)
for (int i = 0; i < activeCounter; i++)
{
Stream& audio = *channelList[i];
processed++;
@@ -301,14 +296,13 @@ void Mixer::mix()
mOutput.add(outputBuffer, outputCounter * 2);
outputCounter = 0;
}
}
while (sourceCounter);
} while (sourceCounter);
processed = 0;
for (int i=0; i<activeCounter; i++)
for (int i = 0; i < activeCounter; i++)
{
Stream& audio = *channelList[i];
audio.data().erase(sampleCounter*2);
audio.data().erase(sampleCounter * 2);
}
}
}
@@ -321,7 +315,7 @@ int Mixer::getPcm(void* outputData, int outputLength)
if (mOutput.filled() < outputLength)
mix();
//ICELogSpecial(<<"Mixer has " << mOutput.filled() << " available bytes");
// ICELogSpecial(<<"Mixer has " << mOutput.filled() << " available bytes");
memset(outputData, 0, outputLength);
return mOutput.read(outputData, outputLength);
}
@@ -354,4 +348,3 @@ int Mixer::available()
{
return mOutput.filled();
}
+7 -10
View File
@@ -16,17 +16,14 @@
namespace Audio
{
class Mixer
{
protected:
class Mixer
{
protected:
class Stream
{
protected:
DataWindow mData;
Resampler mResampler8,
mResampler16,
mResampler32,
mResampler48;
Resampler mResampler8, mResampler16, mResampler32, mResampler48;
bool mActive;
void* mContext;
unsigned mSSRC;
@@ -55,7 +52,7 @@ namespace Audio
void mix();
Stream* allocateChannel(void* context, unsigned ssrc);
public:
public:
Mixer();
~Mixer();
@@ -66,7 +63,7 @@ namespace Audio
int getPcm(void* outputData, int outputLength);
int mixAndGetPcm(Audio::DataWindow& output);
int available();
};
} //end of namespace
};
} // namespace Audio
#endif
+20 -27
View File
@@ -7,8 +7,8 @@
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)
NullTimer::NullTimer(std::chrono::milliseconds interval, Delegate* delegate, const char* name)
: mShutdown(false), mDelegate(delegate), mInterval(interval), mThreadName(name)
{
start();
}
@@ -49,15 +49,13 @@ void NullTimer::run()
// Sleep for mInterval - mTail milliseconds
std::this_thread::sleep_for(mInterval - mTail);
mTail = mTail + std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now() - timestamp);
mTail =
mTail + std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now() - timestamp);
}
}
// --------------------- NullInputDevice -------------------------
NullInputDevice::NullInputDevice()
:mBuffer(nullptr)
{
}
NullInputDevice::NullInputDevice() : mBuffer(nullptr) {}
NullInputDevice::~NullInputDevice()
{
@@ -69,7 +67,8 @@ 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;
mTimeCounter = 0;
mDataCounter = 0;
// Creation of timer starts it also. So first onTimerSignal can come even before open() returns.
mTimer = std::make_shared<NullTimer>(std::chrono::milliseconds(AUDIO_MIC_BUFFER_LENGTH), this, "null_mic");
@@ -85,7 +84,7 @@ void NullInputDevice::internalClose()
free(mBuffer);
mBuffer = nullptr;
}
ICELogInfo( << "Pseudocaptured " << mTimeCounter << " milliseconds , " << mDataCounter << " bytes.");
ICELogInfo(<< "Pseudocaptured " << mTimeCounter << " milliseconds , " << mDataCounter << " bytes.");
}
void NullInputDevice::close()
@@ -95,7 +94,7 @@ void NullInputDevice::close()
Format NullInputDevice::getFormat()
{
assert (Format().sizeFromTime(AUDIO_MIC_BUFFER_LENGTH) == AUDIO_MIC_BUFFER_SIZE);
assert(Format().sizeFromTime(AUDIO_MIC_BUFFER_LENGTH) == AUDIO_MIC_BUFFER_SIZE);
return {}; // Return library-define default format
}
@@ -109,10 +108,7 @@ void NullInputDevice::onTimerSignal(NullTimer& timer)
}
// --------------------- NullOutputDevice --------------------------
NullOutputDevice::NullOutputDevice()
:mBuffer(nullptr)
{
}
NullOutputDevice::NullOutputDevice() : mBuffer(nullptr) {}
NullOutputDevice::~NullOutputDevice()
{
@@ -122,7 +118,8 @@ NullOutputDevice::~NullOutputDevice()
bool NullOutputDevice::open()
{
mTimeCounter = 0; mDataCounter = 0;
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<NullTimer>(std::chrono::milliseconds(AUDIO_SPK_BUFFER_LENGTH), this, "null_spk");
@@ -132,7 +129,8 @@ bool NullOutputDevice::open()
void NullOutputDevice::internalClose()
{
mTimer.reset();
free(mBuffer); mBuffer = nullptr;
free(mBuffer);
mBuffer = nullptr;
ICELogInfo(<< "Pseudoplayed " << mTimeCounter << " milliseconds, " << mDataCounter << " bytes.");
}
@@ -143,11 +141,11 @@ void NullOutputDevice::close()
Format NullOutputDevice::getFormat()
{
assert (Format().sizeFromTime(AUDIO_SPK_BUFFER_LENGTH) == AUDIO_SPK_BUFFER_SIZE);
assert(Format().sizeFromTime(AUDIO_SPK_BUFFER_LENGTH) == AUDIO_SPK_BUFFER_SIZE);
return Format();
}
void NullOutputDevice::onTimerSignal(NullTimer &timer)
void NullOutputDevice::onTimerSignal(NullTimer& timer)
{
mTimeCounter += AUDIO_SPK_BUFFER_LENGTH;
mDataCounter += AUDIO_SPK_BUFFER_SIZE;
@@ -156,17 +154,13 @@ void NullOutputDevice::onTimerSignal(NullTimer &timer)
}
// ---------------------- NullEnumerator --------------------------
NullEnumerator::NullEnumerator()
{}
NullEnumerator::NullEnumerator() {}
NullEnumerator::~NullEnumerator()
{}
NullEnumerator::~NullEnumerator() {}
void NullEnumerator::open(int direction)
{}
void NullEnumerator::open(int direction) {}
void NullEnumerator::close()
{}
void NullEnumerator::close() {}
int NullEnumerator::count()
{
@@ -191,4 +185,3 @@ int NullEnumerator::indexOfDefaultDevice()
{
return 0;
}
+6 -4
View File
@@ -27,13 +27,14 @@ protected:
void start();
void stop();
void run();
public:
/* Interval is in milliseconds. */
NullTimer(std::chrono::milliseconds interval, Delegate* delegate, const char* name = nullptr);
~NullTimer();
};
class NullInputDevice: public InputDevice, public NullTimer::Delegate
class NullInputDevice : public InputDevice, public NullTimer::Delegate
{
protected:
void* mBuffer = nullptr;
@@ -52,7 +53,7 @@ public:
void onTimerSignal(NullTimer& timer) override;
};
class NullOutputDevice: public OutputDevice, public NullTimer::Delegate
class NullOutputDevice : public OutputDevice, public NullTimer::Delegate
{
protected:
std::shared_ptr<NullTimer> mTimer;
@@ -60,6 +61,7 @@ protected:
int64_t mDataCounter = 0, mTimeCounter = 0;
void internalClose();
public:
NullOutputDevice();
virtual ~NullOutputDevice();
@@ -71,7 +73,7 @@ public:
void onTimerSignal(NullTimer& timer) override;
};
class NullEnumerator: public Enumerator
class NullEnumerator : public Enumerator
{
public:
NullEnumerator();
@@ -86,6 +88,6 @@ public:
int indexOfDefaultDevice() override;
};
}
} // namespace Audio
#endif
+6 -11
View File
@@ -11,14 +11,9 @@
using namespace Audio;
// -------------- Player -----------
Player::Player()
:mDelegate(nullptr), mPlayedTime(0)
{
}
Player::Player() : mDelegate(nullptr), mPlayedTime(0) {}
Player::~Player()
{
}
Player::~Player() {}
void Player::setDelegate(EndOfAudioDelegate* d)
{
@@ -68,15 +63,15 @@ void Player::onSpkData(const Format& f, void* buffer, int length)
continue;
}
int wasread = item.mFile->read((char*)buffer+produced, length-produced);
int wasread = item.mFile->read((char*)buffer + produced, length - produced);
mPlayedTime += float(wasread) / BYTES_PER_MILLISECOND;
produced += wasread;
if (wasread < length-produced)
if (wasread < length - produced)
{
if (item.mLoop)
{
item.mFile->rewind();
wasread = item.mFile->read((char*)buffer+produced, (length - produced));
wasread = item.mFile->read((char*)buffer + produced, (length - produced));
mPlayedTime += float(wasread) / BYTES_PER_MILLISECOND;
produced += wasread;
}
@@ -124,7 +119,7 @@ void Player::release(int usage)
if (!usageIter->second)
mUsage.erase(usageIter);
for (unsigned i=0; i<mPlaylist.size(); i++)
for (unsigned i = 0; i < mPlaylist.size(); i++)
if (mPlaylist[i].mUsageId == usage)
mPlaylist.erase(mPlaylist.begin() + i);
+8 -7
View File
@@ -16,10 +16,11 @@
namespace Audio
{
class Player: public DataConnection
{
class Player : public DataConnection
{
friend class DevicePair;
public:
public:
struct PlaylistItem
{
PWavFileReader mFile;
@@ -35,7 +36,7 @@ namespace Audio
virtual void onFilePlayed(PlaylistItem& item) = 0;
};
protected:
protected:
typedef std::map<int, int> UsageMap;
Audio::POutputDevice mOutput;
UsageMap mUsage; // References map
@@ -51,7 +52,7 @@ namespace Audio
void onFilePlayed();
void obtain(int usageId);
public:
public:
Player();
~Player();
@@ -66,6 +67,6 @@ namespace Audio
void clear();
int releasePlayed();
void retrieveUsageIds(std::vector<int>& ids);
};
}
};
} // namespace Audio
#endif
+28 -32
View File
@@ -10,7 +10,7 @@
#include "speex/speex_preprocess.h"
#ifdef WIN32
# include <malloc.h>
#include <malloc.h>
#endif
#include <assert.h>
#include <string.h>
@@ -18,14 +18,14 @@
using namespace Audio;
#ifndef SHRT_MAX
# define SHRT_MAX 32767 /* maximum (signed) short value */
#define SHRT_MAX 32767 /* maximum (signed) short value */
#endif
AgcFilter::AgcFilter(int channels)
{
static const float DefaultLevel = 0.8f;
for (int i=0; i<channels; i++)
for (int i = 0; i < channels; i++)
{
Channel c;
float level = DefaultLevel;
@@ -34,8 +34,7 @@ AgcFilter::AgcFilter(int channels)
c.mIgain = 65536;
if (level > 1.0f)
level = 1.0f;
else
if (level < 0.5f)
else if (level < 0.5f)
level = 0.5f;
c.mIpeak = (int)(SHRT_MAX * level * 65536);
@@ -45,13 +44,11 @@ AgcFilter::AgcFilter(int channels)
}
}
AgcFilter::~AgcFilter()
{
}
AgcFilter::~AgcFilter() {}
void AgcFilter::process(void *pcm, int length)
void AgcFilter::process(void* pcm, int length)
{
for (size_t i=0; i<mChannelList.size(); i++)
for (size_t i = 0; i < mChannelList.size(); i++)
processChannel((short*)pcm, length / (sizeof(short) * mChannelList.size()), i);
}
@@ -59,7 +56,7 @@ void AgcFilter::processChannel(short* pcm, int nrOfSamples, int channelIndex)
{
int i;
for(i=0; i<nrOfSamples; i++)
for (i = 0; i < nrOfSamples; i++)
{
long gain_new;
int sample;
@@ -68,14 +65,14 @@ void AgcFilter::processChannel(short* pcm, int nrOfSamples, int channelIndex)
/* get the abs of buffer[i] */
sample = pcm[sampleIndex];
sample = (sample < 0 ? -(sample):sample);
sample = (sample < 0 ? -(sample) : sample);
if(sample > (int)channel.mSampleMax)
if (sample > (int)channel.mSampleMax)
{
/* update the max */
channel.mSampleMax = (unsigned int)sample;
}
channel.mCounter ++;
channel.mCounter++;
/* Will we get an overflow with the current gain factor? */
if (((sample * channel.mIgain) >> 16) > channel.mIpeak)
@@ -83,7 +80,7 @@ void AgcFilter::processChannel(short* pcm, int nrOfSamples, int channelIndex)
/* Yes: Calculate new gain. */
channel.mIgain = ((channel.mIpeak / channel.mSampleMax) * 62259) >> 16;
channel.mSilenceCounter = 0;
pcm[sampleIndex] = (short) ((pcm[sampleIndex] * channel.mIgain) >> 16);
pcm[sampleIndex] = (short)((pcm[sampleIndex] * channel.mIgain) >> 16);
continue;
}
@@ -112,23 +109,23 @@ void AgcFilter::processChannel(short* pcm, int nrOfSamples, int channelIndex)
channel.mCounter = 0;
channel.mSampleMax = 1;
}
pcm[sampleIndex] = (short) ((pcm[sampleIndex] * channel.mIgain) >> 16);
pcm[sampleIndex] = (short)((pcm[sampleIndex] * channel.mIgain) >> 16);
}
}
// --- AecFilter ---
#ifdef USE_SPEEX_AEC
# include "speex/speex_echo.h"
#include "speex/speex_echo.h"
#include "Audio_Interface.h"
#if !defined(TARGET_WIN)
# include <alloca.h>
#include <alloca.h>
#endif
#endif
#ifdef USE_WEBRTC_AEC
# include "aec/echo_cancellation.h"
#include "aec/echo_cancellation.h"
#endif
#ifdef USE_WEBRTC_AEC
@@ -139,12 +136,12 @@ static void CheckWRACode(unsigned errorcode)
}
#endif
AecFilter::AecFilter(int tailTime, int frameTime, int rate)
:mCtx(nullptr), mFrameTime(frameTime), mRate(rate)
AecFilter::AecFilter(int tailTime, int frameTime, int rate) : mCtx(nullptr), mFrameTime(frameTime), mRate(rate)
{
#ifdef USE_SPEEX_AEC
if (AUDIO_CHANNELS == 2)
mCtx = speex_echo_state_init_mc(frameTime * (mRate / 1000), tailTime * (mRate / 1000), AUDIO_CHANNELS, AUDIO_CHANNELS );
mCtx = speex_echo_state_init_mc(frameTime * (mRate / 1000), tailTime * (mRate / 1000), AUDIO_CHANNELS,
AUDIO_CHANNELS);
else
mCtx = speex_echo_state_init(frameTime * (mRate / 1000), tailTime * (mRate / 1000));
int tmp = rate;
@@ -162,7 +159,7 @@ AecFilter::~AecFilter()
#ifdef USE_SPEEX_AEC
if (mCtx)
{
//speex_echo_state_destroy((SpeexEchoState*)mCtx);
// speex_echo_state_destroy((SpeexEchoState*)mCtx);
mCtx = nullptr;
}
#endif
@@ -173,7 +170,7 @@ AecFilter::~AecFilter()
#endif
}
void AecFilter::fromMic(void *data)
void AecFilter::fromMic(void* data)
{
#ifdef USE_SPEEX_AEC
short* output = (short*)alloca(Format().sizeFromTime(AUDIO_MIC_BUFFER_LENGTH));
@@ -183,12 +180,13 @@ void AecFilter::fromMic(void *data)
#ifdef USE_WEBRTC_AEC
short* inputframe = (short*)ALLOCA(framesize);
memcpy(inputframe, (char*)data+framesize*i, framesize);
CheckWRACode(WebRtcAec_Process(mCtx, (short*)inputframe, NULL, (short*)data+framesize/2*i, NULL, mFrameTime * mRate / 1000, 0,0));
memcpy(inputframe, (char*)data + framesize * i, framesize);
CheckWRACode(WebRtcAec_Process(mCtx, (short*)inputframe, NULL, (short*)data + framesize / 2 * i, NULL,
mFrameTime * mRate / 1000, 0, 0));
#endif
}
void AecFilter::toSpeaker(void *data)
void AecFilter::toSpeaker(void* data)
{
#ifdef USE_SPEEX_AEC
speex_echo_playback((SpeexEchoState*)mCtx, (short*)data);
@@ -205,10 +203,9 @@ int AecFilter::frametime()
}
DenoiseFilter::DenoiseFilter(int rate)
:mRate(rate)
DenoiseFilter::DenoiseFilter(int rate) : mRate(rate)
{
mCtx = speex_preprocess_state_init(mRate/100, mRate);
mCtx = speex_preprocess_state_init(mRate / 100, mRate);
}
DenoiseFilter::~DenoiseFilter()
@@ -224,7 +221,7 @@ void DenoiseFilter::fromMic(void* data, int timelength)
// Process by 10-ms blocks
spx_int16_t* in = (spx_int16_t*)data;
for (int blockIndex=0; blockIndex<timelength/10; blockIndex++)
for (int blockIndex = 0; blockIndex < timelength / 10; blockIndex++)
{
spx_int16_t* block = in + blockIndex * (mRate / 100) * AUDIO_CHANNELS;
speex_preprocess_run((SpeexPreprocessState*)mCtx, block);
@@ -235,4 +232,3 @@ int DenoiseFilter::rate()
{
return mRate;
}
+17 -16
View File
@@ -11,9 +11,9 @@
namespace Audio
{
class AgcFilter
{
protected:
class AgcFilter
{
protected:
struct Channel
{
unsigned int mSampleMax;
@@ -24,16 +24,17 @@ namespace Audio
};
std::vector<Channel> mChannelList;
void processChannel(short* pcm, int nrOfSamples, int channelIndex);
public:
public:
AgcFilter(int channels);
~AgcFilter();
void process(void* pcm, int length);
};
};
class AecFilter
{
public:
class AecFilter
{
public:
AecFilter(int tailTime, int frameTime, int rate);
~AecFilter();
@@ -42,28 +43,28 @@ namespace Audio
void fromMic(void* data);
int frametime();
protected:
protected:
void* mCtx; /// The echo canceller context's pointer.
Mutex mGuard; /// Mutex to protect this instance.
int mFrameTime; /// Duration of single audio frame (in milliseconds)
int mRate;
};
};
class DenoiseFilter
{
public:
class DenoiseFilter
{
public:
DenoiseFilter(int rate);
~DenoiseFilter();
void fromMic(void* data, int timelength);
int rate();
protected:
protected:
Mutex mGuard; /// Mutex to protect this instance.
void* mCtx; /// The denoiser context pointer.
int mRate; /// Duration of single audio frame (in milliseconds)
};
};
}
} // namespace Audio
#endif
+31 -42
View File
@@ -17,8 +17,7 @@ namespace Audio
{
SpeexResampler::SpeexResampler()
{}
SpeexResampler::SpeexResampler() {}
void SpeexResampler::start(int channels, int sourceRate, int destRate)
{
@@ -35,8 +34,8 @@ void SpeexResampler::start(int channels, int sourceRate, int destRate)
if (sourceRate != destRate)
{
// Defer context creation until first request
//mContext = speex_resampler_init(channels, sourceRate, destRate, AUDIO_RESAMPLER_QUALITY, &mErrorCode);
//assert(mContext != NULL);
// mContext = speex_resampler_init(channels, sourceRate, destRate, AUDIO_RESAMPLER_QUALITY, &mErrorCode);
// assert(mContext != NULL);
}
}
@@ -59,8 +58,8 @@ SpeexResampler::~SpeexResampler()
stop();
}
size_t SpeexResampler::processBuffer(const void* src, size_t sourceLength, size_t& sourceProcessed,
void* dest, size_t destCapacity)
size_t SpeexResampler::processBuffer(const void* src, size_t sourceLength, size_t& sourceProcessed, void* dest,
size_t destCapacity)
{
assert(mSourceRate != 0 && mDestRate != 0);
@@ -77,8 +76,7 @@ size_t SpeexResampler::processBuffer(const void* src, size_t sourceLength, size_
if (!mContext)
{
mContext = speex_resampler_init(mChannels, mSourceRate, mDestRate,
AUDIO_RESAMPLER_QUALITY, &mErrorCode);
mContext = speex_resampler_init(mChannels, mSourceRate, mDestRate, AUDIO_RESAMPLER_QUALITY, &mErrorCode);
if (!mContext)
return 0;
}
@@ -103,11 +101,9 @@ size_t SpeexResampler::processBuffer(const void* src, size_t sourceLength, size_
unsigned inLen = sourceLength / (sizeof(short) * mChannels);
outLen /= sizeof(short) * mChannels;
assert(mContext != NULL);
spx_uint32_t in_len = static_cast<spx_uint32_t>(inLen),
out_len = static_cast<spx_uint32_t>(outLen);
spx_uint32_t in_len = static_cast<spx_uint32_t>(inLen), out_len = static_cast<spx_uint32_t>(outLen);
int speexCode = speex_resampler_process_interleaved_int((SpeexResamplerState *)mContext,
(spx_int16_t*)src, &in_len,
int speexCode = speex_resampler_process_interleaved_int((SpeexResamplerState*)mContext, (spx_int16_t*)src, &in_len,
(spx_int16_t*)dest, &out_len);
assert(speexCode == RESAMPLER_ERR_SUCCESS);
@@ -147,27 +143,27 @@ size_t SpeexResampler::getSize() const
}
// -------------------------- ChannelConverter --------------------
int ChannelConverter::stereoToMono(const void *source, int sourceLength, void *dest, int destLength)
int ChannelConverter::stereoToMono(const void* source, int sourceLength, void* dest, int destLength)
{
assert(destLength == sourceLength / 2);
const short* input = (const short*)source;
short* output = (short*)dest;
for (int sampleIndex = 0; sampleIndex < destLength/2; sampleIndex++)
for (int sampleIndex = 0; sampleIndex < destLength / 2; sampleIndex++)
{
output[sampleIndex] = (input[sampleIndex*2] + input[sampleIndex*2+1]) >> 1;
output[sampleIndex] = (input[sampleIndex * 2] + input[sampleIndex * 2 + 1]) >> 1;
}
return sourceLength / 2;
}
int ChannelConverter::monoToStereo(const void *source, int sourceLength, void *dest, int destLength)
int ChannelConverter::monoToStereo(const void* source, int sourceLength, void* dest, int destLength)
{
assert (destLength == sourceLength * 2);
assert(destLength == sourceLength * 2);
const short* input = (const short*)source;
short* output = (short*)dest;
// Convert starting from the end of buffer to allow inplace conversion
for (int sampleIndex = sourceLength/2 - 1; sampleIndex >= 0; sampleIndex--)
for (int sampleIndex = sourceLength / 2 - 1; sampleIndex >= 0; sampleIndex--)
{
output[2*sampleIndex] = output[2*sampleIndex+1] = input[sampleIndex];
output[2 * sampleIndex] = output[2 * sampleIndex + 1] = input[sampleIndex];
}
return sourceLength * 2;
}
@@ -184,13 +180,14 @@ Resampler48kTo16k::~Resampler48kTo16k()
WebRtcSpl_ResetResample48khzTo16khz(&mContext);
}
int Resampler48kTo16k::process(const void *source, int sourceLen, void *dest, int destLen)
int Resampler48kTo16k::process(const void* source, int sourceLen, void* dest, int destLen)
{
const short* input = (const short*)source; int inputLen = sourceLen / 2;
short* output = (short*)dest; //int outputCapacity = destLen / 2;
const short* input = (const short*)source;
int inputLen = sourceLen / 2;
short* output = (short*)dest; // int outputCapacity = destLen / 2;
assert(inputLen % 480 == 0);
int frames = inputLen / 480;
for (int i=0; i<frames; i++)
for (int i = 0; i < frames; i++)
WebRtcSpl_Resample48khzTo16khz(input + i * 480, output + i * 160, &mContext, mTemp);
return sourceLen / 3;
@@ -207,13 +204,14 @@ Resampler16kto48k::~Resampler16kto48k()
WebRtcSpl_ResetResample16khzTo48khz(&mContext);
}
int Resampler16kto48k::process(const void *source, int sourceLen, void *dest, int destLen)
int Resampler16kto48k::process(const void* source, int sourceLen, void* dest, int destLen)
{
const WebRtc_Word16* input = (const WebRtc_Word16*)source; int inputLen = sourceLen / 2;
WebRtc_Word16* output = (WebRtc_Word16*)dest; //int outputCapacity = destLen / 2;
const WebRtc_Word16* input = (const WebRtc_Word16*)source;
int inputLen = sourceLen / 2;
WebRtc_Word16* output = (WebRtc_Word16*)dest; // int outputCapacity = destLen / 2;
assert(inputLen % 160 == 0);
int frames = inputLen / 160;
for (int i=0; i<frames; i++)
for (int i = 0; i < frames; i++)
WebRtcSpl_Resample16khzTo48khz(input + i * 160, output + i * 480, &mContext, mTemp);
return sourceLen * 3;
@@ -222,18 +220,12 @@ int Resampler16kto48k::process(const void *source, int sourceLen, void *dest, in
#endif
// ---------------- UniversalResampler -------------------
UniversalResampler::UniversalResampler()
{
UniversalResampler::UniversalResampler() {}
}
UniversalResampler::~UniversalResampler() {}
UniversalResampler::~UniversalResampler()
{
}
size_t UniversalResampler::resample(int sourceRate, const void *sourceBuffer, size_t sourceLength,
size_t& sourceProcessed, int destRate, void *destBuffer, size_t destCapacity)
size_t UniversalResampler::resample(int sourceRate, const void* sourceBuffer, size_t sourceLength,
size_t& sourceProcessed, int destRate, void* destBuffer, size_t destCapacity)
{
assert(destBuffer && sourceBuffer);
size_t result;
@@ -252,10 +244,7 @@ size_t UniversalResampler::resample(int sourceRate, const void *sourceBuffer, si
return result;
}
void UniversalResampler::preload()
{
}
void UniversalResampler::preload() {}
size_t UniversalResampler::getDestLength(int sourceRate, int destRate, size_t sourceLength)
{
@@ -289,4 +278,4 @@ PResampler UniversalResampler::findResampler(int sourceRate, int destRate)
return r;
}
} // end of namespace
} // namespace Audio
+36 -37
View File
@@ -7,7 +7,7 @@
#define __AUDIO_RESAMPLER_H
#ifdef USE_WEBRTC_RESAMPLER
# include "signal_processing_library/signal_processing_library.h"
#include "signal_processing_library/signal_processing_library.h"
#endif
#include <vector>
@@ -16,9 +16,9 @@
namespace Audio
{
class SpeexResampler
{
public:
class SpeexResampler
{
public:
SpeexResampler();
~SpeexResampler();
@@ -26,8 +26,8 @@ namespace Audio
void stop();
bool isOpened() const;
size_t processBuffer(const void* source, size_t sourceLength, size_t& sourceProcessed,
void* dest, size_t destCapacity);
size_t processBuffer(const void* source, size_t sourceLength, size_t& sourceProcessed, void* dest,
size_t destCapacity);
int sourceRate() const;
int destRate() const;
size_t getDestLength(size_t sourceLen) const;
@@ -36,29 +36,27 @@ namespace Audio
// Returns instance + speex encoder size in bytes
size_t getSize() const;
protected:
protected:
void* mContext = nullptr;
int mErrorCode = 0;
int mSourceRate = 0,
mDestRate = 0,
mChannels = 0;
int mSourceRate = 0, mDestRate = 0, mChannels = 0;
short mLastSample = 0;
};
};
typedef SpeexResampler Resampler;
typedef std::shared_ptr<Resampler> PResampler;
typedef SpeexResampler Resampler;
typedef std::shared_ptr<Resampler> PResampler;
class ChannelConverter
{
public:
class ChannelConverter
{
public:
static int stereoToMono(const void* source, int sourceLength, void* dest, int destLength);
static int monoToStereo(const void* source, int sourceLength, void* dest, int destLength);
};
};
// Operates with AUDIO_CHANNELS number of channels
class UniversalResampler
{
public:
// Operates with AUDIO_CHANNELS number of channels
class UniversalResampler
{
public:
UniversalResampler();
~UniversalResampler();
@@ -67,40 +65,41 @@ namespace Audio
size_t getDestLength(int sourceRate, int destRate, size_t sourceLength);
size_t getSourceLength(int sourceRate, int destRate, size_t destLength);
protected:
protected:
typedef std::pair<int, int> RatePair;
typedef std::map<RatePair, PResampler> ResamplerMap;
ResamplerMap mResamplerMap;
PResampler findResampler(int sourceRate, int destRate);
void preload();
};
};
#ifdef USE_WEBRTC_RESAMPLER
// n*10 milliseconds buffers required!
class Resampler48kTo16k
{
public:
#ifdef USE_WEBRTC_RESAMPLER
// n*10 milliseconds buffers required!
class Resampler48kTo16k
{
public:
Resampler48kTo16k();
~Resampler48kTo16k();
int process(const void* source, int sourceLen, void* dest, int destLen);
protected:
protected:
WebRtc_Word32 mTemp[496];
WebRtcSpl_State48khzTo16khz mContext;
};
};
class Resampler16kto48k
{
public:
class Resampler16kto48k
{
public:
Resampler16kto48k();
~Resampler16kto48k();
int process(const void* source, int sourceLen, void* dest, int destLen);
protected:
protected:
WebRtc_Word32 mTemp[336];
WebRtcSpl_State16khzTo48khz mContext;
};
#endif
} // end of namespace
};
#endif
} // namespace Audio
#endif
+13 -19
View File
@@ -13,13 +13,14 @@
#include <assert.h>
#ifndef WORD
# define WORD unsigned short
#define WORD unsigned short
#endif
#ifndef DWORD
# define DWORD unsigned int
#define DWORD unsigned int
#endif
typedef struct {
typedef struct
{
WORD wFormatTag;
WORD nChannels;
DWORD nSamplesPerSec;
@@ -27,8 +28,7 @@ typedef struct {
WORD nBlockAlign;
WORD wBitsPerSample;
WORD cbSize;
}
WaveFormatEx;
} WaveFormatEx;
#define WAVE_FORMAT_PCM 1
@@ -39,15 +39,12 @@ WaveFormatEx;
using namespace Audio;
// ---------------------- WavFileReader -------------------------
WavFileReader::WavFileReader()
:mSamplerate(0), mLastError(0), mChannels(0), mBits(0), mDataLength(0)
WavFileReader::WavFileReader() : mSamplerate(0), mLastError(0), mChannels(0), mBits(0), mDataLength(0)
{
mDataOffset = 0;
}
WavFileReader::~WavFileReader()
{
}
WavFileReader::~WavFileReader() {}
#define THROW_READERROR throw Exception(ERR_WAVFILE_FAILED);
@@ -127,7 +124,7 @@ bool WavFileReader::open(const std::filesystem::path& p)
uint16_t formattag = 0;
readBuffer(&formattag, sizeof(formattag));
if (formattag != 1/*WAVE_FORMAT_PCM*/)
if (formattag != 1 /*WAVE_FORMAT_PCM*/)
THROW_READERROR;
mChannels = 0;
@@ -168,7 +165,7 @@ bool WavFileReader::open(const std::filesystem::path& p)
mDataOffset = mInput->tellg();
mResampler.start(AUDIO_CHANNELS, mSamplerate, AUDIO_SAMPLERATE);
}
catch(...)
catch (...)
{
mInput.reset();
mLastError = static_cast<unsigned>(-1);
@@ -234,8 +231,7 @@ size_t WavFileReader::read(short* buffer, size_t samples)
size_t readBytes = tryReadBuffer(temp, requiredBytes);
size_t processedBytes = 0;
size_t result = mResampler.processBuffer(temp, readBytes, processedBytes,
buffer, samples * 2 * AUDIO_CHANNELS);
size_t result = mResampler.processBuffer(temp, readBytes, processedBytes, buffer, samples * 2 * AUDIO_CHANNELS);
if (useHeap)
free(temp);
@@ -304,9 +300,7 @@ unsigned WavFileReader::lastError() const
#define BITS_PER_CHANNEL 16
WavFileWriter::WavFileWriter()
:mLengthOffset(0), mSamplerate(AUDIO_SAMPLERATE), mChannels(1), mWritten(0)
{}
WavFileWriter::WavFileWriter() : mLengthOffset(0), mSamplerate(AUDIO_SAMPLERATE), mChannels(1), mWritten(0) {}
WavFileWriter::~WavFileWriter()
{
@@ -358,7 +352,8 @@ bool WavFileWriter::open(const std::filesystem::path& p, int samplerate, int cha
writeBuffer(wavefmt, 8);
// Set the format description
uint32_t dwFmtSize = 16; /*= 16L*/;
uint32_t dwFmtSize = 16; /*= 16L*/
;
writeBuffer(&dwFmtSize, sizeof(dwFmtSize));
WaveFormatEx format;
@@ -435,4 +430,3 @@ std::filesystem::path WavFileWriter::path() const
LOCK;
return mPath;
}
+3 -3
View File
@@ -73,11 +73,11 @@ protected:
mutable std::recursive_mutex mFileMtx; /// Mutex to protect this instance.
size_t mWritten = 0; /// Amount of written data (in bytes)
size_t mLengthOffset = 0; /// Position of length field.
int mSamplerate = 0,
mChannels = 0;
int mSamplerate = 0, mChannels = 0;
void checkWriteResult(int result);
void writeBuffer(const void* buffer, size_t sz);
public:
WavFileWriter();
~WavFileWriter();
@@ -91,6 +91,6 @@ public:
typedef std::shared_ptr<WavFileWriter> PWavFileWriter;
}
} // namespace Audio
#endif
+30 -31
View File
@@ -44,7 +44,6 @@ WmmeInputDevice::Buffer::~Buffer()
GlobalUnlock(mHeaderHandle);
GlobalFree(mHeaderHandle);
}
}
bool WmmeInputDevice::Buffer::prepare(HWAVEIN device)
@@ -55,7 +54,7 @@ bool WmmeInputDevice::Buffer::prepare(HWAVEIN device)
mHeader->lpData = (LPSTR)mData;
resCode = waveInPrepareHeader(device, mHeader, sizeof *mHeader);
//if (resCode != MMSYSERR_NOERROR)
// if (resCode != MMSYSERR_NOERROR)
// LogCritical("Audio", << "Failed to prepare source header. Error code " << resCode << ".");
return resCode == MMSYSERR_NOERROR;
@@ -66,7 +65,7 @@ bool WmmeInputDevice::Buffer::unprepare(HWAVEIN device)
if (mHeader->dwFlags & WHDR_PREPARED)
{
MMRESULT resCode = waveInUnprepareHeader(device, mHeader, sizeof *mHeader);
//if (resCode != MMSYSERR_NOERROR)
// if (resCode != MMSYSERR_NOERROR)
// LogCritical("Audio", << "Failed to unprepare source header. Error code " << resCode << ".");
return resCode == MMSYSERR_NOERROR;
}
@@ -81,7 +80,7 @@ bool WmmeInputDevice::Buffer::isFinished()
bool WmmeInputDevice::Buffer::addToDevice(HWAVEIN device)
{
MMRESULT resCode = waveInAddBuffer(device, mHeader, sizeof(*mHeader));
//if (resCode != MMSYSERR_NOERROR)
// if (resCode != MMSYSERR_NOERROR)
// LogCritical("Audio", << "Failed to add buffer to source audio device. Error code is " << resCode << ".");
return resCode == MMSYSERR_NOERROR;
}
@@ -93,8 +92,8 @@ void* WmmeInputDevice::Buffer::data()
WmmeInputDevice::WmmeInputDevice(int deviceId)
:mDevHandle(NULL), mDoneSignal(INVALID_HANDLE_VALUE), mFakeMode(false),
mBufferIndex(0), mDeviceIndex(deviceId), mThreadHandle(0)
: mDevHandle(NULL), mDoneSignal(INVALID_HANDLE_VALUE), mFakeMode(false), mBufferIndex(0), mDeviceIndex(deviceId),
mThreadHandle(0)
{
mDoneSignal = ::CreateEvent(NULL, FALSE, FALSE, NULL);
mShutdownSignal = ::CreateEvent(NULL, FALSE, FALSE, NULL);
@@ -113,10 +112,11 @@ bool WmmeInputDevice::fakeMode()
return mFakeMode;
}
void CALLBACK WmmeInputDevice::callbackProc(HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
void CALLBACK WmmeInputDevice::callbackProc(HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1,
DWORD_PTR dwParam2)
{
WmmeInputDevice* impl;
switch(uMsg)
switch (uMsg)
{
case WIM_DATA:
impl = (WmmeInputDevice*)dwInstance;
@@ -147,7 +147,8 @@ void WmmeInputDevice::openDevice()
// Open wavein
MMRESULT mmres = waveInOpen(&mDevHandle, mDeviceIndex, &wfx, (DWORD_PTR)callbackProc, (DWORD_PTR)this, CALLBACK_FUNCTION);
MMRESULT mmres =
waveInOpen(&mDevHandle, mDeviceIndex, &wfx, (DWORD_PTR)callbackProc, (DWORD_PTR)this, CALLBACK_FUNCTION);
if (mmres != MMSYSERR_NOERROR)
{
mFakeMode = true;
@@ -158,13 +159,13 @@ void WmmeInputDevice::openDevice()
// Create the buffers for running
mBufferIndex = 0;
for (int i=0; i<AUDIO_MIC_BUFFER_COUNT; i++)
for (int i = 0; i < AUDIO_MIC_BUFFER_COUNT; i++)
mBufferList[i].prepare(mDevHandle);
for (int i=0; i<AUDIO_MIC_BUFFER_COUNT; i++)
for (int i = 0; i < AUDIO_MIC_BUFFER_COUNT; i++)
mBufferList[i].addToDevice(mDevHandle);
/*mmres = */waveInStart(mDevHandle);
/*mmres = */ waveInStart(mDevHandle);
}
bool WmmeInputDevice::open()
@@ -190,7 +191,7 @@ void WmmeInputDevice::closeDevice()
}
// Close buffers
for (int i=0; i<AUDIO_MIC_BUFFER_COUNT; i++)
for (int i = 0; i < AUDIO_MIC_BUFFER_COUNT; i++)
mBufferList[i].unprepare(mDevHandle);
// Close device
@@ -216,7 +217,6 @@ void WmmeInputDevice::close()
::SetEvent(mShutdownSignal);
::WaitForSingleObject(mThreadHandle, INFINITE);
mThreadHandle = 0;
}
bool WmmeInputDevice::tryReadBuffer(void* buffer)
@@ -244,7 +244,7 @@ void WmmeInputDevice::setFakeMode(bool fakeMode)
int WmmeInputDevice::readBuffer(void* buffer)
{
//Lock lock(mGuard);
// Lock lock(mGuard);
if (mRefCount <= 0 || mFakeMode)
return 0;
@@ -287,8 +287,7 @@ void WmmeInputDevice::threadProc(void* arg)
}
// --- WmmeOutputDevice ---
WmmeOutputDevice::Buffer::Buffer()
:mHeaderHandle(NULL), mDataHandle(NULL), mData(NULL), mHeader(NULL)
WmmeOutputDevice::Buffer::Buffer() : mHeaderHandle(NULL), mDataHandle(NULL), mData(NULL), mHeader(NULL)
{
mHeaderHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, AUDIO_SPK_BUFFER_SIZE);
if (!mHeaderHandle)
@@ -341,8 +340,8 @@ bool WmmeOutputDevice::Buffer::write(HWAVEOUT device)
}
WmmeOutputDevice::WmmeOutputDevice(int index)
:mDevice(NULL), mDeviceIndex(index), mPlayedTime(0), mPlayedCount(0), mBufferIndex(0), mThreadHandle(NULL),
mFailed(false), mShutdownMarker(false)
: mDevice(NULL), mDeviceIndex(index), mPlayedTime(0), mPlayedCount(0), mBufferIndex(0), mThreadHandle(NULL),
mFailed(false), mShutdownMarker(false)
{
mDoneSignal = ::CreateEvent(NULL, FALSE, FALSE, NULL);
mShutdownSignal = ::CreateEvent(NULL, FALSE, FALSE, NULL);
@@ -354,7 +353,8 @@ WmmeOutputDevice::~WmmeOutputDevice()
close();
// Destroy used signals
CloseHandle(mDoneSignal); CloseHandle(mShutdownSignal);
CloseHandle(mDoneSignal);
CloseHandle(mShutdownSignal);
}
bool WmmeOutputDevice::open()
@@ -395,10 +395,10 @@ void WmmeOutputDevice::openDevice()
throw Exception(ERR_WMME_FAILED, mmres);
// Prebuffer silence
for (unsigned i=0; i<AUDIO_SPK_BUFFER_COUNT; i++)
for (unsigned i = 0; i < AUDIO_SPK_BUFFER_COUNT; i++)
{
//bool dumb = false;
//mCallback(mBufferList[i].mData, SPK_BUFFER_SIZE, dumb, dumb);
// bool dumb = false;
// mCallback(mBufferList[i].mData, SPK_BUFFER_SIZE, dumb, dumb);
memset(mBufferList[i].mData, 0, AUDIO_SPK_BUFFER_SIZE);
mBufferList[i].prepare(mDevice);
mBufferList[i].write(mDevice);
@@ -430,13 +430,12 @@ bool WmmeOutputDevice::areBuffersFinished()
{
Lock l(mGuard);
bool result = true;
for (unsigned i=0; i<AUDIO_SPK_BUFFER_COUNT && result; i++)
for (unsigned i = 0; i < AUDIO_SPK_BUFFER_COUNT && result; i++)
{
bool finished = mBufferList[i].mHeader->dwFlags & WHDR_DONE ||
!mBufferList[i].mHeader->dwFlags;
bool finished = mBufferList[i].mHeader->dwFlags & WHDR_DONE || !mBufferList[i].mHeader->dwFlags;
if (finished)
{
/* if (mBufferList[i].mHeader->dwFlags & WHDR_PREPARED)
/* if (mBufferList[i].mHeader->dwFlags & WHDR_PREPARED)
mBufferList[i].Unprepare(mDevice); */
}
result &= finished;
@@ -465,7 +464,7 @@ void WmmeOutputDevice::threadProc(void* arg)
WaitForSingleObject(impl->mDoneSignal, 500);
// Iterate buffers to find played
for (i=0; i<AUDIO_SPK_BUFFER_COUNT; i++)
for (i = 0; i < AUDIO_SPK_BUFFER_COUNT; i++)
{
index = (impl->mBufferIndex + i) % AUDIO_SPK_BUFFER_COUNT;
Buffer& buffer = impl->mBufferList[index];
@@ -488,8 +487,7 @@ void WmmeOutputDevice::threadProc(void* arg)
exitCount++;
}
impl->mBufferIndex = (impl->mBufferIndex + i) % AUDIO_SPK_BUFFER_COUNT;
}
while (!exitSignal || exitCount < AUDIO_SPK_BUFFER_COUNT);
} while (!exitSignal || exitCount < AUDIO_SPK_BUFFER_COUNT);
impl->closeDevice();
}
@@ -540,7 +538,8 @@ bool WmmeOutputDevice::closing()
return mClosing;
}
void CALLBACK WmmeOutputDevice::callbackProc(HWAVEOUT hwo, UINT msg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
void CALLBACK WmmeOutputDevice::callbackProc(HWAVEOUT hwo, UINT msg, DWORD_PTR dwInstance, DWORD_PTR dwParam1,
DWORD_PTR dwParam2)
{
WmmeOutputDevice* impl;
+18 -18
View File
@@ -30,9 +30,9 @@
namespace Audio
{
class WmmeInputDevice: public InputDevice
{
public:
class WmmeInputDevice : public InputDevice
{
public:
WmmeInputDevice(int index);
~WmmeInputDevice();
@@ -45,7 +45,7 @@ namespace Audio
int readBuffer(void* buffer);
HWAVEIN handle();
protected:
protected:
class Buffer
{
public:
@@ -79,13 +79,14 @@ namespace Audio
void openDevice();
void closeDevice();
static void CALLBACK callbackProc(HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
static void CALLBACK callbackProc(HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1,
DWORD_PTR dwParam2);
static void threadProc(void* arg);
};
};
class WmmeOutputDevice: public OutputDevice
{
public:
class WmmeOutputDevice : public OutputDevice
{
public:
WmmeOutputDevice(int index);
~WmmeOutputDevice();
@@ -98,16 +99,18 @@ namespace Audio
bool fakeMode();
bool closing();
protected:
protected:
class Buffer
{
friend class WmmeOutputDevice;
public:
Buffer();
~Buffer();
bool prepare(HWAVEOUT device);
bool unprepare(HWAVEOUT device);
bool write(HWAVEOUT device);
protected:
WAVEHDR* mHeader;
void* mData;
@@ -121,9 +124,7 @@ namespace Audio
Buffer mBufferList[AUDIO_SPK_BUFFER_COUNT];
unsigned mPlayedTime; /// Amount of played time in milliseconds
bool mClosing;
HANDLE mDoneSignal,
mShutdownSignal,
mThreadHandle;
HANDLE mDoneSignal, mShutdownSignal, mThreadHandle;
volatile bool mShutdownMarker;
volatile LONG mPlayedCount;
@@ -134,14 +135,13 @@ namespace Audio
void closeDevice();
bool areBuffersFinished();
static void CALLBACK callbackProc(HWAVEOUT hwo, UINT msg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
static void CALLBACK callbackProc(HWAVEOUT hwo, UINT msg, DWORD_PTR dwInstance, DWORD_PTR dwParam1,
DWORD_PTR dwParam2);
static void threadProc(void* arg);
};
};
}
} // namespace Audio
#endif
-1
View File
@@ -1,2 +1 @@
#include "Audio_iOS.h"
+2 -4
View File
@@ -1,21 +1,19 @@
#ifndef __AUDIO_IOS
#define __AUDIO_IOS
class IosInputDevice: public InputDevice
class IosInputDevice : public InputDevice
{
protected:
public:
IosInputDevice();
~IosInputDevice();
void open();
void close();
};
class IosOutputDevice: public OutputDevice
class IosOutputDevice : public OutputDevice
{
protected:
public:
+74 -78
View File
@@ -15,10 +15,10 @@
#define CONFIG(X) mConfig->at(X)
#define CONFIG_EXISTS(X) mConfig->exists(X)
//#define MODIFY_VIA_BEHIND_NAT
// #define MODIFY_VIA_BEHIND_NAT
// NAT decorator
class NATDecorator: public resip::MessageDecorator
class NATDecorator : public resip::MessageDecorator
{
protected:
UserAgent& mUserAgent;
@@ -35,29 +35,26 @@ public:
NATDecorator(UserAgent& endpoint);
virtual ~NATDecorator();
virtual void decorateMessage(resip::SipMessage &msg, const resip::Tuple &source, const resip::Tuple &destination, const resip::Data& sigcompId);
virtual void decorateMessage(resip::SipMessage& msg, const resip::Tuple& source, const resip::Tuple& destination,
const resip::Data& sigcompId);
virtual void rollbackMessage(resip::SipMessage& msg);
virtual MessageDecorator* clone() const;
};
NATDecorator::NATDecorator(UserAgent& ua)
:mUserAgent(ua), mViaPort(0), mContactsPort(0)
{
}
NATDecorator::NATDecorator(UserAgent& ua) : mUserAgent(ua), mViaPort(0), mContactsPort(0) {}
NATDecorator::~NATDecorator()
{
}
NATDecorator::~NATDecorator() {}
void NATDecorator::decorateMessage(resip::SipMessage &msg, const resip::Tuple &source, const resip::Tuple &destination, const resip::Data& sigcompId)
void NATDecorator::decorateMessage(resip::SipMessage& msg, const resip::Tuple& source, const resip::Tuple& destination,
const resip::Data& sigcompId)
{
// Make a copy to allow rollback
mMessage = msg;
std::stringstream dump;
mMessage.encode(dump);
//ICELogDebug(<< "Decorating message: \n" << dump.str());
// ICELogDebug(<< "Decorating message: \n" << dump.str());
// Check From: header and find the account
resip::NameAddr from;
@@ -101,11 +98,11 @@ void NATDecorator::decorateMessage(resip::SipMessage &msg, const resip::Tuple &s
uri.port() = account->mExternalAddress.port();
if (account->mConfig->at(CONFIG_SIPS).asBool())
{
//uri.scheme() = "sips";
//uri.param(resip::p_transport) = "tls";
// uri.scheme() = "sips";
// uri.param(resip::p_transport) = "tls";
}
//uri.scheme() = account->mConfig->at(CONFIG_SIPS).asBool() ? "sips" : "sip";
// uri.scheme() = account->mConfig->at(CONFIG_SIPS).asBool() ? "sips" : "sip";
}
}
}
@@ -141,7 +138,7 @@ void NATDecorator::rollbackMessage(resip::SipMessage& msg)
{
uri.host() = mContactsHost;
uri.port() = mContactsPort;
//uri.scheme() = mContactsScheme;
// uri.scheme() = mContactsScheme;
}
}
}
@@ -153,19 +150,16 @@ resip::MessageDecorator* NATDecorator::clone() const
}
Account::Account(PVariantMap config, UserAgent& agent)
:mAgent(agent), mId(0), mConfig(config), mRegistrationState(RegistrationState::None),
mRegistration(NULL)
: mAgent(agent), mId(0), mConfig(config), mRegistrationState(RegistrationState::None), mRegistration(NULL)
{
mProfile = std::make_shared<resip::UserProfile>(agent.mProfile);
mId = Account::generateId();
setup(*config);
}
Account::~Account()
{
}
Account::~Account() {}
void Account::setup(VariantMap &config)
void Account::setup(VariantMap& config)
{
// Credentials
@@ -176,8 +170,8 @@ void Account::setup(VariantMap &config)
mProfile->setDigestCredential(resip::Data(config[CONFIG_DOMAIN].asStdString()),
resip::Data(config[CONFIG_USERNAME].asStdString()),
resip::Data(config[CONFIG_PASSWORD].asStdString()));
ICELogInfo( << "Credentials are set to domain " << config[CONFIG_DOMAIN].asStdString() <<
", username to " << config[CONFIG_USERNAME].asStdString());
ICELogInfo(<< "Credentials are set to domain " << config[CONFIG_DOMAIN].asStdString() << ", username to "
<< config[CONFIG_USERNAME].asStdString());
// Proxy
mProfile->unsetOutboundProxy();
@@ -234,7 +228,7 @@ void Account::setup(VariantMap &config)
if (config[CONFIG_DOMAINPORT].asInt() != 0)
from.uri().port() = config[CONFIG_DOMAINPORT].asInt();
else
from.uri().port();// = 5060;
from.uri().port(); // = 5060;
from.uri().user() = resip::Data(config[CONFIG_USERNAME].asStdString());
from.uri().host() = resip::Data(config[CONFIG_DOMAIN].asStdString());
@@ -266,10 +260,12 @@ void Account::start()
// Create registration
mRegistration = new ResipSession(*mAgent.mDum);
auto regmessage = mAgent.mDum->makeRegistration(mProfile->getDefaultFrom(), mProfile, mConfig->at(CONFIG_REGISTERDURATION).asInt(), mRegistration);
auto regmessage = mAgent.mDum->makeRegistration(mProfile->getDefaultFrom(), mProfile,
mConfig->at(CONFIG_REGISTERDURATION).asInt(), mRegistration);
for (UserInfo::const_iterator iter = mUserInfo.begin(); iter != mUserInfo.end(); iter++)
regmessage->header(resip::ExtensionHeader(iter->first.c_str())).push_back(resip::StringCategory(iter->second.c_str()));
regmessage->header(resip::ExtensionHeader(iter->first.c_str()))
.push_back(resip::StringCategory(iter->second.c_str()));
mRegistrationState = RegistrationState::Registering;
@@ -278,10 +274,10 @@ void Account::start()
// Check if STUN IP is required
bool noStunServerIp = !CONFIG_EXISTS(CONFIG_STUNSERVER_IP);
//bool hasStunServerName = !CONFIG(CONFIG_STUNSERVER_NAME).asStdString().empty();
// bool hasStunServerName = !CONFIG(CONFIG_STUNSERVER_NAME).asStdString().empty();
if (noStunServerIp)
{
ICELogInfo(<<"No STUN server name or IP is not specified. Has to resolve/discover STUN server IP.");
ICELogInfo(<< "No STUN server name or IP is not specified. Has to resolve/discover STUN server IP.");
mRefreshStunServerIpTimer.start(CONFIG(CONFIG_DNS_CACHE_TIME).asInt() * 1000);
mRefreshStunServerIpTimer.isTimeToSend();
queryStunServerIp();
@@ -305,8 +301,7 @@ void Account::stop()
mRegistrationHandle->removeAll();
mRegistrationHandle = resip::ClientRegistrationHandle();
}
else
if (mRegistration)
else if (mRegistration)
{
mRegistration->end();
}
@@ -361,7 +356,8 @@ void Account::publishPresence(bool online, const std::string& content, int secon
if (mPublication.isValid())
mPublication->update(&p);
else
mAgent.mDum->send(mAgent.mDum->makePublication(contact(SecureScheme::TlsOnly), mProfile, p, resip::Symbols::Presence, seconds));
mAgent.mDum->send(mAgent.mDum->makePublication(contact(SecureScheme::TlsOnly), mProfile, p,
resip::Symbols::Presence, seconds));
}
void Account::stopPublish()
@@ -387,8 +383,8 @@ PClientObserver Account::observe(const std::string& target, const std::string& p
if (mConfig->exists(CONFIG_SUBSCRIPTION_REFRESHTIME))
refresh = CONFIG(CONFIG_SUBSCRIPTION_REFRESHTIME).asInt();
msg = mAgent.mDum->makeSubscription(resip::NameAddr(resip::Data(target)), mProfile,
resip::Data(package), expires, refresh, observer->mSession);
msg = mAgent.mDum->makeSubscription(resip::NameAddr(resip::Data(target)), mProfile, resip::Data(package), expires,
refresh, observer->mSession);
msg->header(resip::h_Accepts) = mAgent.mDum->getMasterProfile()->getSupportedMimeTypes(resip::NOTIFY);
mAgent.mClientObserverMap[observer->mSessionId] = observer;
@@ -409,12 +405,14 @@ int Account::sendMsg(const std::string& peer, const void* ptr, unsigned length,
resip::Mime type;
std::string::size_type p = mime.find('/');
if (p != std::string::npos)
type = resip::Mime(resip::Data(mime.substr(0, p)), resip::Data(mime.substr(p+1)));
type = resip::Mime(resip::Data(mime.substr(0, p)), resip::Data(mime.substr(p + 1)));
else
type = resip::Mime(resip::Data(mime), resip::Data());
resip::ClientPagerMessageHandle msgHandle = mAgent.mDum->makePagerMessage(resip::NameAddr(resip::Data(peer)), mProfile, s);
unique_ptr<resip::Contents> contentPtr(new resip::PlainContents(resip::Data(std::string((const char*)ptr, length)),type));
resip::ClientPagerMessageHandle msgHandle =
mAgent.mDum->makePagerMessage(resip::NameAddr(resip::Data(peer)), mProfile, s);
unique_ptr<resip::Contents> contentPtr(
new resip::PlainContents(resip::Data(std::string((const char*)ptr, length)), type));
int result = s->sessionId();
msgHandle->page(std::move(contentPtr));
@@ -451,12 +449,13 @@ resip::NameAddr Account::contact(SecureScheme ss)
void Account::queryStunServerIp()
{
ICELogInfo(<<"Looking for STUN/TURN server IP");
ICELogInfo(<< "Looking for STUN/TURN server IP");
if (!mConfig->exists(CONFIG_STUNSERVER_NAME))
{
// Send request to find STUN or TURN service
std::string target = std::string(mConfig->at(CONFIG_RELAY).asBool() ? "_turn" : "_stun") + "._udp." + mConfig->at(CONFIG_DOMAIN).asStdString();
std::string target = std::string(mConfig->at(CONFIG_RELAY).asBool() ? "_turn" : "_stun") + "._udp." +
mConfig->at(CONFIG_DOMAIN).asStdString();
// Start lookup
mAgent.mStack->getDnsStub().lookup<resip::RR_SRV>(resip::Data(target), this);
@@ -475,7 +474,7 @@ void Account::queryStunServerIp()
}
}
void Account::prepareIceStack(Session *session, ice::AgentRole icerole)
void Account::prepareIceStack(Session* session, ice::AgentRole icerole)
{
ice::ServerConfig config;
ice::NetworkAddress addr;
@@ -495,8 +494,8 @@ void Account::prepareIceStack(Session *session, ice::AgentRole icerole)
config.mUseIPv4 = mAgent.config()[CONFIG_IPV4].asBool();
config.mUseIPv6 = mAgent.config()[CONFIG_IPV6].asBool();
//config.mDetectNetworkChange = true;
//config.mNetworkCheckInterval = 5000;
// config.mDetectNetworkChange = true;
// config.mNetworkCheckInterval = 5000;
session->mIceStack = std::shared_ptr<ice::Stack>(ice::Stack::makeICEBox(config));
session->mIceStack->setEventHandler(session, this);
@@ -509,7 +508,7 @@ void Account::process()
queryStunServerIp();
}
void Account::onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessage &response)
void Account::onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessage& response)
{
// Save registration handle
mRegistrationHandle = h;
@@ -522,7 +521,7 @@ void Account::onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessa
const resip::Via& via = response.header(resip::h_Vias).front();
// Get the sent host
const resip::Data& sentHost = via.sentHost();//response.header(h_Contacts).front().uri().host();
const resip::Data& sentHost = via.sentHost(); // response.header(h_Contacts).front().uri().host();
// Get the sentPort
int sentPort = via.sentPort();
@@ -553,12 +552,13 @@ void Account::onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessa
}
mUsedTransport = response.getReceivedTransportTuple().getType();
//bool streamTransport = mUsedTransport == resip::TCP || mUsedTransport == resip::TLS;
// bool streamTransport = mUsedTransport == resip::TCP || mUsedTransport == resip::TLS;
// Retry registration for stream based transport too
if ( (hostChanged || portChanged) && mRegistrationState == RegistrationState::Registering /*&& !streamTransport*/ && mConfig->at(CONFIG_EXTERNALIP).asBool())
if ((hostChanged || portChanged) && mRegistrationState == RegistrationState::Registering /*&& !streamTransport*/ &&
mConfig->at(CONFIG_EXTERNALIP).asBool())
{
//mRegistrationHandle->requestRefresh();
// mRegistrationHandle->requestRefresh();
// Unregister at first
mRegistrationHandle->removeAll();
mRegistrationState = RegistrationState::Reregistering;
@@ -570,12 +570,12 @@ void Account::onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessa
mAgent.onAccountStart(mAgent.getAccount(this));
}
void Account::onRemoved(resip::ClientRegistrationHandle h, const resip::SipMessage &response)
void Account::onRemoved(resip::ClientRegistrationHandle h, const resip::SipMessage& response)
{
// Check if this unregistering is a part of rport pr
if (mRegistrationState == RegistrationState::Reregistering)
{
//if (/*this->mUseExternalIP && */response.getSource().getType() == resip::UDP)
// if (/*this->mUseExternalIP && */response.getSource().getType() == resip::UDP)
{
resip::Uri hostport(contact(SecureScheme::TlsOnly).uri());
hostport.host() = resip::Data(mExternalAddress.ip());
@@ -585,19 +585,24 @@ void Account::onRemoved(resip::ClientRegistrationHandle h, const resip::SipMessa
const char* transportName = nullptr;
switch (mUsedTransport)
{
case resip::TCP: transportName = "tcp"; break;
case resip::TLS: transportName = "tls"; break;
case resip::TCP:
transportName = "tcp";
break;
case resip::TLS:
transportName = "tls";
break;
}
hostport.param(resip::p_transport) = resip::Data(transportName);
}
mProfile->setOverrideHostAndPort(hostport);
//mProfile->setDefaultFrom(from);
// mProfile->setDefaultFrom(from);
}
mProfile->setRegId(mConfig->at(CONFIG_REGID).asInt());
auto regmessage = mAgent.mDum->makeRegistration(mProfile->getDefaultFrom(), mProfile, UA_REGISTRATION_TIME);
for (UserInfo::const_iterator iter = mUserInfo.begin(); iter != mUserInfo.end(); iter++)
regmessage->header(resip::ExtensionHeader(iter->first.c_str())).push_back(resip::StringCategory(iter->second.c_str()));
regmessage->header(resip::ExtensionHeader(iter->first.c_str()))
.push_back(resip::StringCategory(iter->second.c_str()));
mAgent.mDum->send(regmessage);
return;
@@ -625,16 +630,17 @@ void Account::onDnsResult(const resip::DNSResult<resip::DnsHostRecord>& result)
if (result.status == 0)
{
resip::Data foundAddress = result.records.front().host();
ICELogInfo( << "Success to resolve STUN/TURN address to " << foundAddress.c_str());
ICELogInfo(<< "Success to resolve STUN/TURN address to " << foundAddress.c_str());
mConfig->at(CONFIG_STUNSERVER_IP) = std::string(foundAddress.c_str());
// Here the IP address of STUN/TURN server is found. If account is registered already - it means account is ready.
// Here the IP address of STUN/TURN server is found. If account is registered already - it means account is
// ready.
if (mRegistrationState == RegistrationState::Registered)
mAgent.onAccountStart(mAgent.getAccount(this));
}
else
{
ICELogError( << "Failed to resolve STUN or TURN server IP address.");
ICELogError(<< "Failed to resolve STUN or TURN server IP address.");
if (mRegistrationState == RegistrationState::Registered)
{
int startCode = mConfig->at(CONFIG_STUNSERVER_NAME).asStdString().empty() ? 0 : 503;
@@ -643,10 +649,7 @@ void Account::onDnsResult(const resip::DNSResult<resip::DnsHostRecord>& result)
}
}
void Account::onDnsResult(const resip::DNSResult<resip::DnsAAAARecord>&)
{
}
void Account::onDnsResult(const resip::DNSResult<resip::DnsAAAARecord>&) {}
void Account::onDnsResult(const resip::DNSResult<resip::DnsSrvRecord>& result)
{
@@ -654,14 +657,14 @@ void Account::onDnsResult(const resip::DNSResult<resip::DnsSrvRecord>& result)
{
// Find lowest priority
int priority = 0x7FFFFFFF;
for (size_t i=0; i<result.records.size(); i++)
for (size_t i = 0; i < result.records.size(); i++)
if (result.records[i].priority() < priority)
priority = result.records[i].priority();
size_t index = 0;
int weight = 0;
for (size_t i=0; i<result.records.size(); i++)
for (size_t i = 0; i < result.records.size(); i++)
{
if (result.records[i].priority() == priority && result.records[i].weight() >= weight)
{
@@ -674,15 +677,15 @@ void Account::onDnsResult(const resip::DNSResult<resip::DnsSrvRecord>& result)
const char* host = result.records[index].target().c_str();
ICELogInfo( << "Success to find STUN/TURN server on " << result.records[index].target().c_str() <<
":" << (int)result.records[index].port());
ICELogInfo(<< "Success to find STUN/TURN server on " << result.records[index].target().c_str() << ":"
<< (int)result.records[index].port());
if (inet_addr(host) == INADDR_NONE)
{
// Try to resolve domain name now
mAgent.mStack->getDnsStub().lookup<resip::RR_A>(result.records[index].target(), this);
//mStack->getDnsStub().lookup<resip::RR_AAAA>(result.records[index].target(), this);
// mStack->getDnsStub().lookup<resip::RR_AAAA>(result.records[index].target(), this);
}
else
{
@@ -691,23 +694,16 @@ void Account::onDnsResult(const resip::DNSResult<resip::DnsSrvRecord>& result)
}
else
{
ICELogError( << "Failed to find STUN or TURN service for specified domain.");
//mAgent::shutdown();
ICELogError(<< "Failed to find STUN or TURN service for specified domain.");
// mAgent::shutdown();
}
}
void Account::onDnsResult(const resip::DNSResult<resip::DnsNaptrRecord>&)
{
void Account::onDnsResult(const resip::DNSResult<resip::DnsNaptrRecord>&) {}
}
void Account::onDnsResult(const resip::DNSResult<resip::DnsCnameRecord>&) {}
void Account::onDnsResult(const resip::DNSResult<resip::DnsCnameRecord>&)
{
}
bool Account::isResponsibleFor(const resip::NameAddr &addr)
bool Account::isResponsibleFor(const resip::NameAddr& addr)
{
std::string user = addr.uri().user().c_str();
std::string domain = addr.uri().host().c_str();
@@ -724,7 +720,7 @@ bool Account::isResponsibleFor(const resip::NameAddr &addr)
return false;
}
void Account::setUserInfo(const UserInfo &info)
void Account::setUserInfo(const UserInfo& info)
{
mUserInfo = info;
if (mRegistrationHandle.isValid())
+2 -1
View File
@@ -22,10 +22,11 @@
class UserAgent;
class Session;
class Account: public resip::DnsResultSink
class Account : public resip::DnsResultSink
{
friend class UserAgent;
friend class NATDecorator;
public:
Account(PVariantMap config, UserAgent& agent);
~Account();
+33 -21
View File
@@ -17,8 +17,7 @@
#define LOG_SUBSYSTEM "engine"
AudioProvider::AudioProvider(UserAgent& agent, MT::Terminal& terminal)
:mUserAgent(agent), mTerminal(terminal), mState(0),
mRemoteTelephoneCodec(0), mRemoteNoSdp(false)
: mUserAgent(agent), mTerminal(terminal), mState(0), mRemoteTelephoneCodec(0), mRemoteNoSdp(false)
{
mActive = mfActive;
mRemoteState = msSendRecv;
@@ -26,12 +25,11 @@ AudioProvider::AudioProvider(UserAgent& agent, MT::Terminal& terminal)
if (mUserAgent.config().exists(CONFIG_CODEC_PRIORITY))
mCodecPriority.setupFrom(mUserAgent.config()[CONFIG_CODEC_PRIORITY].asVMap());
mSrtpSuite = SRTP_NONE;
setStateImpl((int)StreamState::SipRecv | (int)StreamState::SipSend | (int)StreamState::Receiving | (int)StreamState::Sending);
setStateImpl((int)StreamState::SipRecv | (int)StreamState::SipSend | (int)StreamState::Receiving |
(int)StreamState::Sending);
}
AudioProvider::~AudioProvider()
{
}
AudioProvider::~AudioProvider() {}
std::string AudioProvider::streamName()
{
@@ -55,7 +53,7 @@ void AudioProvider::setDestinationAddress(const RtpPair<InternetAddress>& addr)
mActiveStream->setDestination(addr);
}
void AudioProvider::configureMediaObserver(MT::Stream::MediaObserver *observer, void* userTag)
void AudioProvider::configureMediaObserver(MT::Stream::MediaObserver* observer, void* userTag)
{
mMediaObserver = observer;
mMediaObserverTag = userTag;
@@ -71,13 +69,14 @@ void AudioProvider::processData(const PDatagramSocket& s, const void* dataBuffe
if (RtpHelper::isRtpOrRtcp(dataBuffer, dataSize))
{
ICELogMedia(<<"Adding new data to stream processing");
ICELogMedia(<< "Adding new data to stream processing");
mActiveStream->dataArrived(s, dataBuffer, dataSize, source);
}
}
// This method is called by user agent to send ICE packet from mediasocket
void AudioProvider::sendData(const PDatagramSocket& s, InternetAddress& destination, const void* buffer, unsigned int size)
void AudioProvider::sendData(const PDatagramSocket& s, InternetAddress& destination, const void* buffer,
unsigned int size)
{
s->sendDatagram(destination, buffer, size);
}
@@ -105,7 +104,7 @@ void AudioProvider::updateSdpOffer(resip::SdpContents::Session::Medium& sdp, Sdp
// Use CodecListPriority mCodecPriority adapter to work with codec priorities
if (mAvailableCodecs.empty())
{
for (int i=0; i<mCodecPriority.count(mTerminal.codeclist()); i++)
for (int i = 0; i < mCodecPriority.count(mTerminal.codeclist()); i++)
mCodecPriority.codecAt(mTerminal.codeclist(), i).updateSdp(sdp.codecs(), direction);
sdp.addCodec(resip::SdpContents::Session::Codec::TelephoneEvent);
}
@@ -122,22 +121,35 @@ void AudioProvider::updateSdpOffer(resip::SdpContents::Session::Medium& sdp, Sdp
switch (mActive)
{
case mfActive:
switch(mRemoteState)
switch (mRemoteState)
{
case msSendonly: attr = "recvonly"; break;
case msInactive: attr = "recvonly"; break;
case msSendonly:
attr = "recvonly";
break;
case msInactive:
attr = "recvonly";
break;
case msRecvonly:
case msSendRecv: break; // Do nothing here
case msSendRecv:
break; // Do nothing here
}
break;
case mfPaused:
switch (mRemoteState)
{
case msRecvonly: attr = "sendonly"; break;
case msSendonly: attr = "inactive"; break;
case msInactive: attr = "inactive"; break;
case msSendRecv: attr = "sendonly"; break;
case msRecvonly:
attr = "sendonly";
break;
case msSendonly:
attr = "inactive";
break;
case msInactive:
attr = "inactive";
break;
case msSendRecv:
attr = "sendonly";
break;
}
break;
}
@@ -227,7 +239,7 @@ bool AudioProvider::processSdpOffer(const resip::SdpContents::Session::Medium& m
// Use CodecListPriority mCodecPriority to work with codec priorities
int pt;
for (int localIndex=0; localIndex<mCodecPriority.count(mTerminal.codeclist()); localIndex++)
for (int localIndex = 0; localIndex < mCodecPriority.count(mTerminal.codeclist()); localIndex++)
{
MT::Codec::Factory& factory = mCodecPriority.codecAt(mTerminal.codeclist(), localIndex);
if ((pt = factory.processSdp(media.codecs(), sdpDirection)) != -1)
@@ -367,9 +379,9 @@ void AudioProvider::setupMirror(bool enable)
mActiveStream->setupMirror(enable);
}
void AudioProvider::setStateImpl(unsigned int state) {
void AudioProvider::setStateImpl(unsigned int state)
{
mState = state;
if (mActiveStream)
mActiveStream->setState(state);
}
+6 -7
View File
@@ -18,10 +18,9 @@
class UserAgent;
class AudioProvider: public DataProvider
class AudioProvider : public DataProvider
{
public:
AudioProvider(UserAgent& agent, MT::Terminal& terminal);
virtual ~AudioProvider();
@@ -38,7 +37,8 @@ public:
void processData(const PDatagramSocket& s, const void* dataBuffer, int dataSize, InternetAddress& source) override;
// This method is called by user agent to send ICE packet from mediasocket
void sendData(const PDatagramSocket& s, InternetAddress& destination, const void* dataBuffer, unsigned int datasize) override;
void sendData(const PDatagramSocket& s, InternetAddress& destination, const void* dataBuffer,
unsigned int datasize) override;
// Updates SDP offer
void updateSdpOffer(resip::SdpContents::Session::Medium& sdp, SdpDirection direction) override;
@@ -96,9 +96,9 @@ protected:
int mSrtpTag = 1; // RFC 4568 tag of the negotiated crypto attribute
struct RemoteCodec
{
RemoteCodec(MT::Codec::Factory* factory, int payloadType)
:mFactory(factory), mRemotePayloadType(payloadType)
{ }
RemoteCodec(MT::Codec::Factory* factory, int payloadType) : mFactory(factory), mRemotePayloadType(payloadType)
{
}
MT::Codec::Factory* mFactory;
int mRemotePayloadType;
@@ -115,7 +115,6 @@ protected:
// Implements setState() logic. This allows to be called from constructor (it is not virtual function)
void setStateImpl(unsigned state);
};
#endif
+8 -10
View File
@@ -10,7 +10,7 @@ bool DataProvider::isSupported(const char* name)
{
return !strcmp(name, "audio");
//return (!strcmp(name, "screen") || !strcmp(name, "data") || !strcmp(name, "audio") || !strcmp(name, "video"));
// return (!strcmp(name, "screen") || !strcmp(name, "data") || !strcmp(name, "audio") || !strcmp(name, "video"));
}
void DataProvider::pause()
@@ -20,7 +20,7 @@ void DataProvider::pause()
// Stop receive RTP stream
if (state() & (int)StreamState::Receiving)
setState( state() & ~(int)StreamState::Receiving );
setState(state() & ~(int)StreamState::Receiving);
mActive = mfPaused;
}
@@ -28,10 +28,10 @@ void DataProvider::pause()
void DataProvider::resume()
{
// Tell remote peer about resumed receiving in SDP
//setState( state() | STATE_SIPRECV );
// setState( state() | STATE_SIPRECV );
// Start receive RTP stream
setState( state() | (int)StreamState::Receiving );
setState(state() | (int)StreamState::Receiving);
mActive = mfActive;
}
@@ -44,17 +44,15 @@ bool DataProvider::processSdpOffer(const resip::SdpContents::Session::Medium& me
mRemoteState = msSendonly;
setState(state() & ~(int)StreamState::Sending);
}
else
if (media.exists("recvonly"))
else if (media.exists("recvonly"))
{
mRemoteState = msRecvonly;
setState(state() & ~(int)StreamState::Receiving);
}
else
if (media.exists("inactive"))
else if (media.exists("inactive"))
{
mRemoteState = msInactive;
setState(state() & ~((int)StreamState::Sending | (int)StreamState::Receiving) );
setState(state() & ~((int)StreamState::Sending | (int)StreamState::Receiving));
}
else
{
@@ -66,7 +64,7 @@ bool DataProvider::processSdpOffer(const resip::SdpContents::Session::Medium& me
break;
case mfPaused:
setState(state() | (int)StreamState::Sending );
setState(state() | (int)StreamState::Sending);
break;
}
}
+4 -2
View File
@@ -45,10 +45,12 @@ public:
virtual void setDestinationAddress(const RtpPair<InternetAddress>& addr) = 0;
// Processes incoming data
virtual void processData(const PDatagramSocket& s, const void* dataBuffer, int dataSize, InternetAddress& address) = 0;
virtual void processData(const PDatagramSocket& s, const void* dataBuffer, int dataSize,
InternetAddress& address) = 0;
// This method is called by user agent to send ICE packet from mediasocket
virtual void sendData(const PDatagramSocket& s, InternetAddress& destination, const void* dataBuffer, unsigned int datasize) = 0;
virtual void sendData(const PDatagramSocket& s, InternetAddress& destination, const void* dataBuffer,
unsigned int datasize) = 0;
// Updates SDP offer
virtual void updateSdpOffer(resip::SdpContents::Session::Medium& sdp, SdpDirection direction) = 0;
+188 -215
View File
@@ -30,27 +30,32 @@
#include "resip/dum/InviteSession.hxx"
#if defined(TARGET_OSX)
# include "resip/stack/ssl/MacSecurity.hxx"
#include "resip/stack/ssl/MacSecurity.hxx"
#endif
#if defined(TARGET_WIN)
# include "resip/stack/ssl/WinSecurity.hxx"
#include "resip/stack/ssl/WinSecurity.hxx"
#endif
#define LOG_SUBSYSTEM "engine"
#define LOCK Lock l(mGuard)
#define CAST2RESIPSESSION(x) (x.isValid() ? (x->getAppDialogSet().isValid() ? dynamic_cast<ResipSession*>(x->getAppDialogSet().get()) : NULL) : NULL)
#define CAST2RESIPSESSION(x) \
(x.isValid() ? (x->getAppDialogSet().isValid() ? dynamic_cast<ResipSession*>(x->getAppDialogSet().get()) : NULL) \
: NULL)
typedef resip::SdpContents::Session::Medium Medium;
typedef resip::SdpContents::Session::MediumContainer MediumContainer;
class TransportLogger: public resip::Transport::SipMessageLoggingHandler
class TransportLogger : public resip::Transport::SipMessageLoggingHandler
{
public:
void outboundMessage(const resip::Tuple &source, const resip::Tuple &destination, const resip::SipMessage &msg) override
void outboundMessage(const resip::Tuple& source, const resip::Tuple& destination,
const resip::SipMessage& msg) override
{
std::ostringstream dest_buffer; dest_buffer << destination;
std::ostringstream msg_buffer; msg_buffer << msg;
std::ostringstream dest_buffer;
dest_buffer << destination;
std::ostringstream msg_buffer;
msg_buffer << msg;
std::string msg_text = msg_buffer.str();
#if defined(TARGET_ANDROID)
if (msg_text.size() > 512)
@@ -59,7 +64,7 @@ public:
msg_text = strx::prefixLines(msg_text, "<---");
auto lines = strx::split(msg_text);
for (const auto& l: lines)
for (const auto& l : lines)
ICELogDebug(<< l);
}
else
@@ -72,13 +77,18 @@ public:
// Note: retransmissions store already encoded messages, so callback doesn't send SipMessage it sends
// the encoded version of the SipMessage instead. If you need a SipMessage you will need to
// re-parse back into a SipMessage in the callback handler.
void outboundRetransmit(const resip::Tuple &source, const resip::Tuple &destination, const resip::SendData &data) override
{}
void inboundMessage(const resip::Tuple& source, const resip::Tuple& destination, const resip::SipMessage &msg) override
void outboundRetransmit(const resip::Tuple& source, const resip::Tuple& destination,
const resip::SendData& data) override
{
std::ostringstream source_buffer; source_buffer << source;
std::ostringstream msg_buffer; msg_buffer << msg;
}
void inboundMessage(const resip::Tuple& source, const resip::Tuple& destination,
const resip::SipMessage& msg) override
{
std::ostringstream source_buffer;
source_buffer << source;
std::ostringstream msg_buffer;
msg_buffer << msg;
std::string msg_text = msg_buffer.str();
#if defined(TARGET_ANDROID)
if (msg_text.size() > 512)
@@ -86,7 +96,7 @@ public:
ICELogDebug(<< "Received from " << source_buffer.str() << " :");
msg_text = strx::prefixLines(msg_text, "--->");
auto lines = strx::split(msg_text);
for (const auto& l: lines)
for (const auto& l : lines)
ICELogDebug(<< l);
}
else
@@ -95,7 +105,6 @@ public:
ICELogDebug(<< "Received from " << source_buffer.str() << "\n" << strx::prefixLines(msg_buffer.str(), "--->"));
#endif
}
};
//-------------- UserAgent -----------------------
@@ -142,7 +151,7 @@ void UserAgent::start()
LOCK;
if (mStack)
{
ICELogError(<<"Endpoint is started already.");
ICELogError(<< "Endpoint is started already.");
return;
}
@@ -160,11 +169,16 @@ void UserAgent::start()
while (std::getline(ss, line))
{
line = strx::trim(line);
ice::NetworkAddress addr(line.c_str(), 0); addr.setPort(80); // Fake port to make ICEAddress initialized
ice::NetworkAddress addr(line.c_str(), 0);
addr.setPort(80); // Fake port to make ICEAddress initialized
switch (addr.family())
{
case AF_INET: nslist.push_back(resip::GenericIPAddress(*addr.sockaddr4())); break;
case AF_INET6: nslist.push_back(resip::GenericIPAddress(*addr.sockaddr6())); break;
case AF_INET:
nslist.push_back(resip::GenericIPAddress(*addr.sockaddr4()));
break;
case AF_INET6:
nslist.push_back(resip::GenericIPAddress(*addr.sockaddr6()));
break;
}
}
}
@@ -190,7 +204,7 @@ void UserAgent::start()
resip::Data cert = resip::Data(mConfig[CONFIG_ROOTCERT].asStdString());
mStack->getSecurity()->addRootCertPEM(cert);
}
catch(resip::BaseException& /*e*/)
catch (resip::BaseException& /*e*/)
{
ICELogError(<< "Failed to preload root certificate");
}
@@ -202,8 +216,16 @@ void UserAgent::start()
mTransportList.clear();
resip::InternalTransport* t;
#define ADD_TRANSPORT4(X) if ((t = dynamic_cast<resip::InternalTransport*>(mStack->addTransport(X, 0, resip::V4)))) { /*t->setTransportLogger(this);*/ mTransportList.push_back(t);}
#define ADD_TRANSPORT6(X) if ((t = dynamic_cast<resip::InternalTransport*>(mStack->addTransport(X, 0, resip::V6)))) { /*t->setTransportLogger(this);*/ mTransportList.push_back(t);}
#define ADD_TRANSPORT4(X) \
if ((t = dynamic_cast<resip::InternalTransport*>(mStack->addTransport(X, 0, resip::V4)))) \
{ /*t->setTransportLogger(this);*/ \
mTransportList.push_back(t); \
}
#define ADD_TRANSPORT6(X) \
if ((t = dynamic_cast<resip::InternalTransport*>(mStack->addTransport(X, 0, resip::V6)))) \
{ /*t->setTransportLogger(this);*/ \
mTransportList.push_back(t); \
}
switch (mConfig[CONFIG_TRANSPORT].asInt())
{
@@ -314,20 +336,20 @@ void UserAgent::shutdown()
if (!mStack)
return;
ICELogInfo( << "Attempt to stop endpoint.");
ICELogInfo(<< "Attempt to stop endpoint.");
{
LOCK;
for (auto& observerIter: mClientObserverMap)
for (auto& observerIter : mClientObserverMap)
observerIter.second->stop();
for (auto& observerIter: mServerObserverMap)
for (auto& observerIter : mServerObserverMap)
observerIter.second->stop();
for (auto& sessionIter: mSessionMap)
for (auto& sessionIter : mSessionMap)
sessionIter.second->stop();
for (auto& accountIter: mAccountSet)
for (auto& accountIter : mAccountSet)
accountIter->stop();
}
}
@@ -342,17 +364,19 @@ void UserAgent::refresh()
{
LOCK;
for (auto& acc: mAccountSet)
for (auto& acc : mAccountSet)
acc->refresh();
for (auto& observer: mClientObserverMap)
for (auto& observer : mClientObserverMap)
observer.second->refresh();
}
void UserAgent::onDumCanBeDeleted()
{
delete mDum; mDum = nullptr;
delete mStack; mStack = nullptr;
delete mDum;
mDum = nullptr;
delete mStack;
mStack = nullptr;
mClientObserverMap.clear();
mServerObserverMap.clear();
@@ -371,14 +395,12 @@ void UserAgent::stop()
mTransportList.clear();
// Dump statistics here
ICELogInfo(<< "Remaining "
<< Session::InstanceCounter.load() << " session(s), "
ICELogInfo(<< "Remaining " << Session::InstanceCounter.load() << " session(s), "
<< ResipSession::InstanceCounter.load() << " resip DialogSet(s), "
<< resip::ClientRegistration::InstanceCounter.load() << " ClientRegistration(s)");
mDum->shutdown(this);
onDumCanBeDeleted();
}
@@ -390,12 +412,12 @@ void UserAgent::process()
bool connectionFailed = false;
mStack->buildFdSet(fdset);
//unsigned int t1 = mStack->getTimeTillNextProcessMS();
// unsigned int t1 = mStack->getTimeTillNextProcessMS();
int ret = fdset.selectMilliSeconds(0);
if (ret >= 0) // Got any results or time to send new packets?
{
Lock l(mGuard);
//ICELogDebug(<< "Smth on SIP socket(s)");
// ICELogDebug(<< "Smth on SIP socket(s)");
mStack->process(fdset);
// Check if there failed connections
@@ -417,7 +439,8 @@ void UserAgent::process()
this->onSipConnectionFailed();
}
// Erase one terminated session. The rule is : seession must not have references from resiprocate and reference count has to be 1.
// Erase one terminated session. The rule is : seession must not have references from resiprocate and reference
// count has to be 1.
{
Lock l(mGuard);
SessionMap::iterator sessionIter;
@@ -456,21 +479,25 @@ void UserAgent::process()
session.processQueuedOffer();
// Generate outgoing data while available
int iceStreamId = -1, iceComponentId = -1; void* iceTag = NULL; bool iceResponse;
int iceStreamId = -1, iceComponentId = -1;
void* iceTag = NULL;
bool iceResponse;
ice::PByteBuffer buffer;
while ((buffer = session.mIceStack->generateOutgoingData(iceResponse, iceStreamId, iceComponentId, iceTag)))
{
// Find corresponding data provider
for (unsigned i=0; i < session.mStreamList.size(); ++i)
for (unsigned i = 0; i < session.mStreamList.size(); ++i)
{
Session::Stream& stream = session.mStreamList[i];
if (stream.provider() && stream.iceInfo().mStreamId == iceStreamId)
{
// Send generated packet via provider's method to allow custom scheme of encryption
ICELogDebug(<<"Sending ICE packet to " << buffer->remoteAddress().toStdString() << " with " << buffer->comment());
ICELogDebug(<< "Sending ICE packet to " << buffer->remoteAddress().toStdString() << " with "
<< buffer->comment());
RtpPair<PDatagramSocket>& pair = buffer->remoteAddress().family() == AF_INET6 ? stream.socket6() : stream.socket4();
RtpPair<PDatagramSocket>& pair =
buffer->remoteAddress().family() == AF_INET6 ? stream.socket6() : stream.socket4();
PDatagramSocket s = iceComponentId == ICE_RTP_ID ? pair.mRtp : pair.mRtcp;
if (s)
stream.provider()->sendData(s, buffer->remoteAddress(), buffer->data(), buffer->size());
@@ -491,10 +518,12 @@ void UserAgent::addRootCert(const ByteBuffer& data)
if (!mStack)
return;
resip::Data b(data.data(), data.size());
try {
try
{
mStack->getSecurity()->addRootCertPEM(b);
}
catch(...) {
catch (...)
{
// Ignore silently
}
}
@@ -538,8 +567,7 @@ std::string UserAgent::formatSipAddress(const std::string& sip)
{
if (sip.find("sip:") == std::string::npos && sip.find("sips:") == std::string::npos)
result = "<sip:" + sip + ">";
else
if (sip[0] != '<' && sip.find('<') == std::string::npos)
else if (sip[0] != '<' && sip.find('<') == std::string::npos)
result = "<" + sip + ">";
else
result = sip;
@@ -583,7 +611,7 @@ UserAgent::SipAddress UserAgent::parseSipAddress(const std::string& sip)
{
resip::Data d(formatSipAddress(sip));
resip::NameAddr nameaddr(d);
//resip::Uri uri(d);
// resip::Uri uri(d);
if (!nameaddr.isWellFormed())
result.mValid = false;
else
@@ -633,14 +661,9 @@ void UserAgent::onCandidateGathered(PSession s, const char* address)
// Called when new connectivity check is finished
void UserAgent::onCheckFinished(PSession s, const char* description)
{
void UserAgent::onCheckFinished(PSession s, const char* description) {}
}
void UserAgent::onLog(const char* msg)
{
}
void UserAgent::onLog(const char* msg) {}
void UserAgent::sendOffer(Session* session)
{
@@ -653,10 +676,12 @@ void UserAgent::sendOffer(Session* session)
if (session->mOriginVersion == 1)
{
// Construct INVITE session
auto msg = mDum->makeInviteSession(session->mRemotePeer, session->account()->mProfile, &sdp, session->mResipSession);
auto msg =
mDum->makeInviteSession(session->mRemotePeer, session->account()->mProfile, &sdp, session->mResipSession);
// Include user headers
for (Session::UserHeaders::const_iterator iter = session->mUserHeaders.begin(); iter != session->mUserHeaders.end(); iter++)
for (Session::UserHeaders::const_iterator iter = session->mUserHeaders.begin();
iter != session->mUserHeaders.end(); iter++)
{
const std::string& name = iter->first;
const std::string& value = iter->second;
@@ -680,7 +705,7 @@ void UserAgent::sendOffer(Session* session)
void UserAgent::onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessage& response)
{
ICELogInfo (<< "Registration got 200 response.");
ICELogInfo(<< "Registration got 200 response.");
Lock l(mGuard);
// Find account by registration handle
@@ -692,7 +717,7 @@ void UserAgent::onSuccess(resip::ClientRegistrationHandle h, const resip::SipMes
// Called when all of my bindings have been removed
void UserAgent::onRemoved(resip::ClientRegistrationHandle h, const resip::SipMessage& response)
{
ICELogInfo( << "Registration is removed.");
ICELogInfo(<< "Registration is removed.");
Lock l(mGuard);
@@ -712,7 +737,7 @@ int UserAgent::onRequestRetry(resip::ClientRegistrationHandle h, int retrySecond
// Registration retry interval is enabled in the Profile)
void UserAgent::onFailure(resip::ClientRegistrationHandle h, const resip::SipMessage& response)
{
ICELogInfo (<< "Registration failed with code " << response.header(resip::h_StatusLine).statusCode());
ICELogInfo(<< "Registration failed with code " << response.header(resip::h_StatusLine).statusCode());
Lock l(mGuard);
PAccount account = getAccount(response.header(resip::h_From));
@@ -723,41 +748,31 @@ void UserAgent::onFailure(resip::ClientRegistrationHandle h, const resip::SipMes
#pragma endregion
bool UserAgent::operator()(resip::Log::Level level,
const resip::Subsystem& subsystem,
const resip::Data& appName,
const char* file,
int line,
const resip::Data& message,
const resip::Data& messageWithHeaders,
const resip::Data& instanceName)
bool UserAgent::operator()(resip::Log::Level level, const resip::Subsystem& subsystem, const resip::Data& appName,
const char* file, int line, const resip::Data& message,
const resip::Data& messageWithHeaders, const resip::Data& instanceName)
{
std::string filename = file;
std::stringstream ss;
ss << "File " << strx::extractFilename(filename).c_str() << ", line " << line << ": " << message.c_str();
if (level <= resip::Log::Crit)
ICELogCritical(<< ss.str())
else
if (level <= resip::Log::Warning)
ICELogError(<< ss.str().c_str())
else
if (level < resip::Log::Debug)
ICELogInfo(<< ss.str().c_str())
else
ICELogDebug(<< ss.str().c_str())
return false;
ICELogCritical(<< ss.str()) else if (level <= resip::Log::Warning)
ICELogError(<< ss.str().c_str()) else if (level < resip::Log::Debug)
ICELogInfo(<< ss.str().c_str()) else ICELogDebug(<< ss.str().c_str()) return false;
}
#pragma region INVITE handler
/// called when an initial INVITE or the intial response to an outoing invite
void UserAgent::onNewSession(resip::ClientInviteSessionHandle h, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg)
void UserAgent::onNewSession(resip::ClientInviteSessionHandle h, resip::InviteSession::OfferAnswerType oat,
const resip::SipMessage& msg)
{
}
void UserAgent::onNewSession(resip::ServerInviteSessionHandle h, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg)
void UserAgent::onNewSession(resip::ServerInviteSessionHandle h, resip::InviteSession::OfferAnswerType oat,
const resip::SipMessage& msg)
{
ResipSession* rs = CAST2RESIPSESSION(h);
if (!rs)
@@ -783,7 +798,7 @@ void UserAgent::onNewSession(resip::ServerInviteSessionHandle h, resip::InviteSe
// Save remote address
s->setRemoteAddress(h->peerAddr().uri().getAor().c_str());
ICELogInfo( << "Session " << s->sessionId() << ": incoming.");
ICELogInfo(<< "Session " << s->sessionId() << ": incoming.");
h->provisional(100);
@@ -793,15 +808,11 @@ void UserAgent::onNewSession(resip::ServerInviteSessionHandle h, resip::InviteSe
}
/// Received a failure response from UAS
void UserAgent::onFailure(resip::ClientInviteSessionHandle, const resip::SipMessage& msg)
{
}
void UserAgent::onFailure(resip::ClientInviteSessionHandle, const resip::SipMessage& msg) {}
/// called when an in-dialog provisional response is received that contains an SDP body
void UserAgent::onEarlyMedia(resip::ClientInviteSessionHandle h, const resip::SipMessage&, const resip::SdpContents&)
{
}
void UserAgent::onEarlyMedia(resip::ClientInviteSessionHandle h, const resip::SipMessage&, const resip::SdpContents&) {}
/// called when dialog enters the Early state - typically after getting 18x
@@ -819,7 +830,6 @@ void UserAgent::onProvisional(resip::ClientInviteSessionHandle h, const resip::S
int responseCode = msg.header(resip::h_StatusLine).statusCode();
onSessionProvisional(s, responseCode);
}
}
@@ -835,7 +845,7 @@ void UserAgent::onConnected(resip::ClientInviteSessionHandle h, const resip::Sip
if (!s->mOfferAnswerCounter)
{
ICELogInfo (<< "Session " << s->sessionId() << ": connected.");
ICELogInfo(<< "Session " << s->sessionId() << ": connected.");
// Transfer user headers
if (h.isValid())
@@ -843,7 +853,7 @@ void UserAgent::onConnected(resip::ClientInviteSessionHandle h, const resip::Sip
onSessionEstablished(s, EV_SIP, RtpPair<InternetAddress>());
for (unsigned i=0; i<s->mStreamList.size(); i++)
for (unsigned i = 0; i < s->mStreamList.size(); i++)
{
if (s->mStreamList[i].provider())
s->mStreamList[i].provider()->sessionEstablished(EV_SIP);
@@ -864,7 +874,7 @@ void UserAgent::onConnected(resip::InviteSessionHandle h, const resip::SipMessag
if (!s)
return;
ICELogInfo (<< "Session " << s->mSessionId << ": connected.");
ICELogInfo(<< "Session " << s->mSessionId << ": connected.");
// Transfer user headers
if (h.isValid())
@@ -872,7 +882,7 @@ void UserAgent::onConnected(resip::InviteSessionHandle h, const resip::SipMessag
onSessionEstablished(s, EV_SIP, RtpPair<InternetAddress>());
for (unsigned i=0; i<s->mStreamList.size(); i++)
for (unsigned i = 0; i < s->mStreamList.size(); i++)
{
if (s->mStreamList[i].provider())
s->mStreamList[i].provider()->sessionEstablished(EV_SIP);
@@ -880,7 +890,8 @@ void UserAgent::onConnected(resip::InviteSessionHandle h, const resip::SipMessag
}
void UserAgent::onTerminated(resip::InviteSessionHandle h, resip::InviteSessionHandler::TerminatedReason reason, const resip::SipMessage* related)
void UserAgent::onTerminated(resip::InviteSessionHandle h, resip::InviteSessionHandler::TerminatedReason reason,
const resip::SipMessage* related)
{
ResipSession* rs = CAST2RESIPSESSION(h);
if (!rs)
@@ -889,7 +900,7 @@ void UserAgent::onTerminated(resip::InviteSessionHandle h, resip::InviteSessionH
if (!s)
return;
ICELogInfo( << "Session " << s->mSessionId << ": terminated.");
ICELogInfo(<< "Session " << s->mSessionId << ": terminated.");
int errorcode = 0;
if (related)
@@ -907,9 +918,7 @@ void UserAgent::onTerminated(resip::InviteSessionHandle h, resip::InviteSessionH
/// called when a fork that was created through a 1xx never receives a 2xx
/// because another fork answered and this fork was canceled by a proxy.
void UserAgent::onForkDestroyed(resip::ClientInviteSessionHandle)
{
}
void UserAgent::onForkDestroyed(resip::ClientInviteSessionHandle) {}
/// called when a 3xx with valid targets is encountered in an early dialog
@@ -918,9 +927,7 @@ void UserAgent::onForkDestroyed(resip::ClientInviteSessionHandle)
/// Basically an onTermintated that conveys more information.
/// checking for 3xx respones in onTerminated will not work as there may
/// be no valid targets.
void UserAgent::onRedirected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg)
{
}
void UserAgent::onRedirected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg) {}
/// Called when an SDP answer is received - has nothing to do with user
/// answering the call
@@ -936,7 +943,7 @@ void UserAgent::onAnswer(resip::InviteSessionHandle h, const resip::SipMessage&
bool iceAvailable = true;
ICELogInfo( << "Session " << s->mSessionId << ": got answer.");
ICELogInfo(<< "Session " << s->mSessionId << ": got answer.");
// Check for remote ICE credentials
std::string icePwd, iceUfrag;
@@ -947,7 +954,7 @@ void UserAgent::onAnswer(resip::InviteSessionHandle h, const resip::SipMessage&
if (s->mStreamList.size() < sdp.session().media().size())
{
ICELogError( << "SDP answer has wrong number of streams");
ICELogError(<< "SDP answer has wrong number of streams");
h->end();
return;
}
@@ -963,14 +970,14 @@ void UserAgent::onAnswer(resip::InviteSessionHandle h, const resip::SipMessage&
std::list<resip::SdpContents::Session::Medium>::const_iterator mediaIter;
unsigned streamIndex = 0;
for (mediaIter = sdp.session().media().begin(), streamIndex = 0;
mediaIter != sdp.session().media().end() && streamIndex < s->mStreamList.size();
++mediaIter, ++streamIndex)
mediaIter != sdp.session().media().end() && streamIndex < s->mStreamList.size(); ++mediaIter, ++streamIndex)
{
Session::Stream& stream = s->mStreamList[streamIndex];
const resip::SdpContents::Session::Medium& remoteStream = *mediaIter;
// Update remote default ip if available
const std::list<resip::SdpContents::Session::Connection>& streamConnections = remoteStream.getMediumConnections();
const std::list<resip::SdpContents::Session::Connection>& streamConnections =
remoteStream.getMediumConnections();
if (streamConnections.size())
remoteDefaultIP = streamConnections.front().getAddress().c_str();
@@ -985,10 +992,10 @@ void UserAgent::onAnswer(resip::InviteSessionHandle h, const resip::SipMessage&
if (stream.provider())
{
stream.provider()->sessionTerminated(); // close corresponding media
stream.setProvider( PDataProvider() ); // free provider
SocketHeap::instance().freeSocketPair( stream.socket4() ); // close provider's socket ip4
SocketHeap::instance().freeSocketPair( stream.socket6() ); // close provider's socket ip6
s->mIceStack->removeStream( stream.iceInfo().mStreamId ); // remove stream from ice stack
stream.setProvider(PDataProvider()); // free provider
SocketHeap::instance().freeSocketPair(stream.socket4()); // close provider's socket ip4
SocketHeap::instance().freeSocketPair(stream.socket6()); // close provider's socket ip6
s->mIceStack->removeStream(stream.iceInfo().mStreamId); // remove stream from ice stack
}
continue;
}
@@ -1016,10 +1023,11 @@ void UserAgent::onAnswer(resip::InviteSessionHandle h, const resip::SipMessage&
// Corresponding turn allocation will be removed in this case.
try
{
if (!s->mIceStack->processSdpOffer(stream.iceInfo().mStreamId, candidateVector, remoteDefaultIP, remoteDefaultPort, mConfig[CONFIG_DEFERRELAYED].asBool()))
if (!s->mIceStack->processSdpOffer(stream.iceInfo().mStreamId, candidateVector, remoteDefaultIP,
remoteDefaultPort, mConfig[CONFIG_DEFERRELAYED].asBool()))
iceAvailable = false;
}
catch(...)
catch (...)
{
iceAvailable = false;
}
@@ -1027,16 +1035,15 @@ void UserAgent::onAnswer(resip::InviteSessionHandle h, const resip::SipMessage&
// Process media description with provider
if (stream.provider())
{
if (stream.provider()->processSdpOffer( remoteStream, Sdp_Answer ))
if (stream.provider()->processSdpOffer(remoteStream, Sdp_Answer))
{
InternetAddress addr(remoteDefaultIP, remoteDefaultPort), addr2(remoteDefaultIP, remoteDefaultPort+1);
InternetAddress addr(remoteDefaultIP, remoteDefaultPort), addr2(remoteDefaultIP, remoteDefaultPort + 1);
// See if remote stream has "rtcp" or "rtcp-mux" attributes
if (remoteStream.exists("rtcp"))
addr2.setPort( strx::toInt(remoteStream.getValues("rtcp").front().c_str(), remoteDefaultPort+1) );
else
if (remoteStream.exists("rtcp-mux"))
addr2.setPort( remoteDefaultPort );
addr2.setPort(strx::toInt(remoteStream.getValues("rtcp").front().c_str(), remoteDefaultPort + 1));
else if (remoteStream.exists("rtcp-mux"))
addr2.setPort(remoteDefaultPort);
stream.provider()->setDestinationAddress(RtpPair<InternetAddress>(addr, addr2));
mediasupported = true;
}
@@ -1101,7 +1108,7 @@ void UserAgent::onOffer(resip::InviteSessionHandle h, const resip::SipMessage& m
if (sdp.session().exists("ice-ufrag"))
iceUfrag = sdp.session().getValues("ice-ufrag").front().c_str();
//ice::Stack& ice = *s->mIceStack;
// ice::Stack& ice = *s->mIceStack;
uint64_t version = sdp.session().origin().getVersion();
std::string remoteIp = sdp.session().connection().getAddress().c_str();
@@ -1111,13 +1118,12 @@ void UserAgent::onOffer(resip::InviteSessionHandle h, const resip::SipMessage& m
{
code = s->processSdp(version, iceAvailable, icePwd, iceUfrag, remoteIp, sdp.session().media());
}
else
if (version == s->mRemoteOriginVersion)
else if (version == s->mRemoteOriginVersion)
{
// Timer, answer with previous SDP
//session->processTimer();
// session->processTimer();
}
if (version == s->mRemoteOriginVersion+1)
if (version == s->mRemoteOriginVersion + 1)
{
// Updated offer. Here we must check if ICE has to be restarted.
code = s->processSdp(version, iceAvailable, icePwd, iceUfrag, remoteIp, sdp.session().media());
@@ -1149,64 +1155,43 @@ void UserAgent::onOffer(resip::InviteSessionHandle h, const resip::SipMessage& m
/// called when an Invite w/out SDP is sent, or any other context which
/// requires an SDP offer from the user
void UserAgent::onOfferRequired(resip::InviteSessionHandle, const resip::SipMessage& msg)
{
}
void UserAgent::onOfferRequired(resip::InviteSessionHandle, const resip::SipMessage& msg) {}
/// called if an offer in a UPDATE or re-INVITE was rejected - not real
/// useful. A SipMessage is provided if one is available
void UserAgent::onOfferRejected(resip::InviteSessionHandle, const resip::SipMessage* msg)
{
}
void UserAgent::onOfferRejected(resip::InviteSessionHandle, const resip::SipMessage* msg) {}
/// called when INFO message is received
void UserAgent::onInfo(resip::InviteSessionHandle, const resip::SipMessage& msg)
{
}
void UserAgent::onInfo(resip::InviteSessionHandle, const resip::SipMessage& msg) {}
/// called when response to INFO message is received
void UserAgent::onInfoSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg)
{
}
void UserAgent::onInfoSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg) {}
void UserAgent::onInfoFailure(resip::InviteSessionHandle, const resip::SipMessage& msg)
{
}
void UserAgent::onInfoFailure(resip::InviteSessionHandle, const resip::SipMessage& msg) {}
/// called when MESSAGE message is received
void UserAgent::onMessage(resip::InviteSessionHandle, const resip::SipMessage& msg)
{
}
void UserAgent::onMessage(resip::InviteSessionHandle, const resip::SipMessage& msg) {}
/// called when response to MESSAGE message is received
void UserAgent::onMessageSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg)
{
}
void UserAgent::onMessageSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg) {}
void UserAgent::onMessageFailure(resip::InviteSessionHandle, const resip::SipMessage& msg)
{
}
void UserAgent::onMessageFailure(resip::InviteSessionHandle, const resip::SipMessage& msg) {}
/// called when an REFER message is received. The refer is accepted or
/// rejected using the server subscription. If the offer is accepted,
/// DialogUsageManager::makeInviteSessionFromRefer can be used to create an
/// InviteSession that will send notify messages using the ServerSubscription
void UserAgent::onRefer(resip::InviteSessionHandle, resip::ServerSubscriptionHandle, const resip::SipMessage& msg)
{
}
void UserAgent::onRefer(resip::InviteSessionHandle, resip::ServerSubscriptionHandle, const resip::SipMessage& msg) {}
void UserAgent::onReferNoSub(resip::InviteSessionHandle, const resip::SipMessage& msg)
{
}
void UserAgent::onReferNoSub(resip::InviteSessionHandle, const resip::SipMessage& msg) {}
/// called when an REFER message receives a failure response
void UserAgent::onReferRejected(resip::InviteSessionHandle, const resip::SipMessage& msg)
{
}
void UserAgent::onReferRejected(resip::InviteSessionHandle, const resip::SipMessage& msg) {}
/// called when an REFER message receives an accepted response
void UserAgent::onReferAccepted(resip::InviteSessionHandle, resip::ClientSubscriptionHandle, const resip::SipMessage& msg)
void UserAgent::onReferAccepted(resip::InviteSessionHandle, resip::ClientSubscriptionHandle,
const resip::SipMessage& msg)
{
}
@@ -1215,25 +1200,21 @@ void UserAgent::onDnsResult(const resip::DNSResult<resip::DnsHostRecord>& result
if (result.status == 0)
{
resip::Data foundAddress = result.records.front().host();
ICELogInfo( << "Success to resolve STUN/TURN address to " << foundAddress.c_str());
ICELogInfo(<< "Success to resolve STUN/TURN address to " << foundAddress.c_str());
mConfig[CONFIG_STUNSERVER_IP] = std::string(foundAddress.c_str());
onStart(0);
}
else
{
ICELogError( << "Failed to resolve STUN or TURN server IP address.");
ICELogError(<< "Failed to resolve STUN or TURN server IP address.");
int startCode = mConfig[CONFIG_STUNSERVER_NAME].asStdString().empty() ? 0 : 503;
onStart(startCode);
}
}
void UserAgent::onDnsResult(const resip::DNSResult<resip::DnsAAAARecord>& result)
{
}
void UserAgent::onDnsResult(const resip::DNSResult<resip::DnsAAAARecord>& result) {}
void UserAgent::onDnsResult(const resip::DNSResult<resip::DnsSrvRecord>& result)
{
}
void UserAgent::onDnsResult(const resip::DNSResult<resip::DnsSrvRecord>& result) {}
void UserAgent::onDnsResult(const resip::DNSResult<resip::DnsNaptrRecord>& result)
{
@@ -1281,28 +1262,20 @@ int UserAgent::onRequestRetry(resip::ClientPublicationHandle, int retrySeconds,
}
void UserAgent::onPublicationSuccess(PAccount account) {}
void UserAgent::onPublicationSuccess(PAccount account)
{
}
void UserAgent::onPublicationTerminated(PAccount account, int code)
{
}
void UserAgent::onPublicationTerminated(PAccount account, int code) {}
#pragma endregion
#pragma region Subscriptions
void UserAgent::onClientObserverStart(PClientObserver observer)
{
}
void UserAgent::onClientObserverStart(PClientObserver observer) {}
void UserAgent::onClientObserverStop(PClientObserver observer, int code)
{
}
void UserAgent::onClientObserverStop(PClientObserver observer, int code) {}
void UserAgent::onPresenceUpdate(PClientObserver observer, const std::string& peer, bool online, const std::string& content)
void UserAgent::onPresenceUpdate(PClientObserver observer, const std::string& peer, bool online,
const std::string& content)
{
}
@@ -1351,13 +1324,9 @@ void UserAgent::onTerminated(resip::ServerSubscriptionHandle h)
}
}
void UserAgent::onServerObserverStart(PServerObserver observer)
{
}
void UserAgent::onServerObserverStart(PServerObserver observer) {}
void UserAgent::onServerObserverStop(PServerObserver observer, int code)
{
}
void UserAgent::onServerObserverStop(PServerObserver observer, int code) {}
void UserAgent::onUpdate(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify)
{
@@ -1393,14 +1362,13 @@ void UserAgent::onUpdate(resip::ClientSubscriptionHandle h, const resip::SipMess
bool online = pidf->getSimpleStatus(&body);
onPresenceUpdate(observer, observer->peer(), online, std::string(body.c_str(), body.size()));
}
else
if (resip::MultipartRelatedContents* mr = dynamic_cast<resip::MultipartRelatedContents*>(contents))
else if (resip::MultipartRelatedContents* mr = dynamic_cast<resip::MultipartRelatedContents*>(contents))
{
resip::MultipartRelatedContents::Parts& parts = mr->parts();
for( resip::MultipartRelatedContents::Parts::const_iterator i = parts.begin(); i != parts.end(); ++i)
for (resip::MultipartRelatedContents::Parts::const_iterator i = parts.begin(); i != parts.end(); ++i)
{
resip::Contents* c = *i;
assert( c );
assert(c);
resip::Mime m = c->getType();
if (resip::Rlmi* rlmi = dynamic_cast<resip::Rlmi*>(c))
{
@@ -1414,7 +1382,7 @@ void UserAgent::onUpdate(resip::ClientSubscriptionHandle h, const resip::SipMess
resip::Data tag = c.getTag();
if (tag != "list")
{
ICELogError( << "Failed to find <list> tag in rlmi");
ICELogError(<< "Failed to find <list> tag in rlmi");
}
else
{
@@ -1422,7 +1390,7 @@ void UserAgent::onUpdate(resip::ClientSubscriptionHandle h, const resip::SipMess
{
if (c.getTag() != "resource")
{
ICELogError( << "Failed to find <resource> tag in rlmi");
ICELogError(<< "Failed to find <resource> tag in rlmi");
}
else
{
@@ -1442,14 +1410,13 @@ void UserAgent::onUpdate(resip::ClientSubscriptionHandle h, const resip::SipMess
// Save result
if (instance)
availableContacts.push_back( attrIter->second );
availableContacts.push_back(attrIter->second);
}
}
}
}
}
else
if (resip::Pidf* pidf = dynamic_cast<resip::Pidf*>(c))
else if (resip::Pidf* pidf = dynamic_cast<resip::Pidf*>(c))
{
resip::Data body = pidf->getBodyData();
bool online = pidf->getSimpleStatus(&body);
@@ -1459,7 +1426,8 @@ void UserAgent::onUpdate(resip::ClientSubscriptionHandle h, const resip::SipMess
onPresenceUpdate(observer, entity.c_str(), online, std::string(body.c_str(), body.size()));
// Drop corresponding record from availableContacts
std::vector<resip::Data>::iterator ci = std::find(availableContacts.begin(), availableContacts.end(), entity);
std::vector<resip::Data>::iterator ci =
std::find(availableContacts.begin(), availableContacts.end(), entity);
if (ci != availableContacts.end())
availableContacts.erase(ci);
}
@@ -1467,7 +1435,7 @@ void UserAgent::onUpdate(resip::ClientSubscriptionHandle h, const resip::SipMess
}
}
for (unsigned i=0; i<availableContacts.size(); i++)
for (unsigned i = 0; i < availableContacts.size(); i++)
onPresenceUpdate(observer, availableContacts[i].c_str(), false, std::string());
}
@@ -1491,7 +1459,7 @@ int UserAgent::onRequestRetry(resip::ClientSubscriptionHandle, int retrySeconds,
return -1;
}
//subscription can be ended through a notify or a failure response.
// subscription can be ended through a notify or a failure response.
void UserAgent::onTerminated(resip::ClientSubscriptionHandle h, const resip::SipMessage* msg)
{
// TODO - check for refer notication
@@ -1531,22 +1499,16 @@ void UserAgent::onNewSubscription(resip::ClientSubscriptionHandle h, const resip
}
/// called to allow app to adorn a message.
void UserAgent::onReadyToSend(resip::ClientSubscriptionHandle, resip::SipMessage& msg)
{
}
void UserAgent::onReadyToSend(resip::ClientSubscriptionHandle, resip::SipMessage& msg) {}
void UserAgent::onNotifyNotReceived(resip::ClientSubscriptionHandle)
{
}
void UserAgent::onNotifyNotReceived(resip::ClientSubscriptionHandle) {}
/// Called when a TCP or TLS flow to the server has terminated. This can be caused by socket
/// errors, or missing CRLF keep alives pong responses from the server.
// Called only if clientOutbound is enabled on the UserProfile and the first hop server
/// supports RFC5626 (outbound).
/// Default implementation is to re-form the subscription using a new flow
void UserAgent::onFlowTerminated(resip::ClientSubscriptionHandle)
{
}
void UserAgent::onFlowTerminated(resip::ClientSubscriptionHandle) {}
#pragma endregion
#pragma region PagerHandler
@@ -1560,14 +1522,16 @@ void UserAgent::onSuccess(resip::ClientPagerMessageHandle h, const resip::SipMes
onMessageSent(getAccount(status.header(resip::h_From)), s->sessionId(), s->remoteAddress(), s->tag());
}
void UserAgent::onFailure(resip::ClientPagerMessageHandle h, const resip::SipMessage& status, std::unique_ptr<resip::Contents> contents)
void UserAgent::onFailure(resip::ClientPagerMessageHandle h, const resip::SipMessage& status,
std::unique_ptr<resip::Contents> contents)
{
if (!h.isValid())
return;
ResipSession* s = CAST2RESIPSESSION(h);
if (!s)
return;
onMessageFailed(getAccount(status.header(resip::h_From)), s->sessionId(), s->remoteAddress(), status.header(resip::h_StatusLine).statusCode(), s->tag());
onMessageFailed(getAccount(status.header(resip::h_From)), s->sessionId(), s->remoteAddress(),
status.header(resip::h_StatusLine).statusCode(), s->tag());
}
void UserAgent::onMessageArrived(resip::ServerPagerMessageHandle h, const resip::SipMessage& message)
@@ -1590,20 +1554,20 @@ void UserAgent::onMessageArrived(resip::ServerPagerMessageHandle h, const resip:
void UserAgent::updateInterfaceList()
{
//ICEImpl::ICENetworkHelper::instance().reload();
// ICEImpl::ICENetworkHelper::instance().reload();
}
void UserAgent::onMessageArrived(PAccount /*account*/, const std::string& /*peer*/, const void* /*ptr*/, unsigned /*length*/)
void UserAgent::onMessageArrived(PAccount /*account*/, const std::string& /*peer*/, const void* /*ptr*/,
unsigned /*length*/)
{
}
void UserAgent::onMessageFailed(PAccount /*account*/, int /*id*/, const std::string& /*peer*/, int /*code*/, void* /*tag*/)
void UserAgent::onMessageFailed(PAccount /*account*/, int /*id*/, const std::string& /*peer*/, int /*code*/,
void* /*tag*/)
{
}
void UserAgent::onMessageSent(PAccount /*account*/, int /*id*/, const std::string& /*peer*/, void* /*tag*/)
{
}
void UserAgent::onMessageSent(PAccount /*account*/, int /*id*/, const std::string& /*peer*/, void* /*tag*/) {}
VariantMap& UserAgent::config()
{
@@ -1678,7 +1642,8 @@ PSession UserAgent::getUserSession(int sessionId)
PAccount UserAgent::getAccount(const resip::NameAddr& myAddr)
{
PAccount acc;
for (AccountSet::iterator accountIter = mAccountSet.begin(); accountIter != mAccountSet.end() && !acc; accountIter++)
for (AccountSet::iterator accountIter = mAccountSet.begin(); accountIter != mAccountSet.end() && !acc;
accountIter++)
if ((*accountIter)->isResponsibleFor(myAddr))
acc = *accountIter;
@@ -1688,7 +1653,8 @@ PAccount UserAgent::getAccount(const resip::NameAddr& myAddr)
PAccount UserAgent::getAccount(Account* account)
{
PAccount acc;
for (AccountSet::iterator accountIter = mAccountSet.begin(); accountIter != mAccountSet.end() && !acc; accountIter++)
for (AccountSet::iterator accountIter = mAccountSet.begin(); accountIter != mAccountSet.end() && !acc;
accountIter++)
if (accountIter->get() == account)
acc = *accountIter;
@@ -1697,7 +1663,14 @@ PAccount UserAgent::getAccount(Account* account)
PAccount UserAgent::getAccount(int sessionId)
{
auto profileIter = std::find_if(mAccountSet.begin(), mAccountSet.end(), [=](const AccountSet::value_type& v) {if (v->mRegistration) return v->mRegistration->sessionId() == sessionId; else return false;});
auto profileIter = std::find_if(mAccountSet.begin(), mAccountSet.end(),
[=](const AccountSet::value_type& v)
{
if (v->mRegistration)
return v->mRegistration->sessionId() == sessionId;
else
return false;
});
return (profileIter != mAccountSet.end()) ? *profileIter : PAccount();
}
+35 -26
View File
@@ -87,7 +87,8 @@ enum
CONFIG_ICEUSERNAME, // Optional username for TURN server. String value.
CONFIG_ICEPASSWORD, // Optional password for TURN server. String value.
CONFIG_SIPS, // Marks if account credentials are sips: scheme. Boolean value.
CONFIG_STUNSERVER_IP, // Optional IP address of STUN/TURN server. String value. It is better to use CONFIG_STUNSERVER_NAME.
CONFIG_STUNSERVER_IP, // Optional IP address of STUN/TURN server. String value. It is better to use
// CONFIG_STUNSERVER_NAME.
CONFIG_STUNSERVER_NAME, // Host name of STUN/TURN server. stun.xten.com for example. String value.
CONFIG_STUNSERVER_PORT, // Port number of STUN/TURN server. Integer value.
CONFIG_USERAGENT, // Name of user agent in SIP headers. String value.
@@ -98,7 +99,8 @@ enum
CONFIG_DNS_CACHE_TIME, // DNS cache time; default is 86400 seconds
CONFIG_PRESENCE_ID, // Tuple ID used in presence publishing; determines source device
CONFIG_ROOTCERT, // Additional root cert in PEM format; string.
CONFIG_CACHECREDENTIALS, // Attempt to cache credentials that comes in response from PBX. Use them when possible to reduce number of steps of SIP transaction
CONFIG_CACHECREDENTIALS, // Attempt to cache credentials that comes in response from PBX. Use them when possible to
// reduce number of steps of SIP transaction
CONFIG_RTCP_ATTR, // Use "rtcp" attribute in sdp. Default value is true.
CONFIG_MULTIPLEXING, // Do rtp/rtcp multiplexing
CONFIG_DEFERRELAYED, // Defer relayed media path
@@ -139,11 +141,11 @@ enum
RemoteBye,
LocalCancel,
RemoteCancel,
Rejected, //Only as UAS, UAC has distinct onFailure callback
Rejected, // Only as UAS, UAC has distinct onFailure callback
Referred
};
class UserAgent: public resip::ClientRegistrationHandler,
class UserAgent : public resip::ClientRegistrationHandler,
public resip::InviteSessionHandler,
public resip::DumShutdownHandler,
public resip::ExternalLogger,
@@ -153,15 +155,17 @@ class UserAgent: public resip::ClientRegistrationHandler,
public resip::ClientPagerMessageHandler,
public resip::ServerPagerMessageHandler,
public resip::ClientPublicationHandler
//public resip::InternalTransport::TransportLogger
// public resip::InternalTransport::TransportLogger
{
friend class Account;
friend class Session;
friend class ResipSession;
friend class NATDecorator;
friend class WatcherQueue;
public:
/* Compares two sip addresses. Returns true if they represent the same entity - user and domain are the same. Otherwise returns false. */
/* Compares two sip addresses. Returns true if they represent the same entity - user and domain are the same.
* Otherwise returns false. */
static bool compareSipAddresses(const std::string& sip1, const std::string& sip2);
static std::string formatSipAddress(const std::string& sip);
static bool isSipAddressValid(const std::string& sip);
@@ -187,7 +191,8 @@ public:
This is asynchronous method. onStop() event will be called later */
void shutdown();
/* Emergency stop. Please always call shutdown() before this. Kills registration, sessions & presence - everything. onStop() is called in context of this method. */
/* Emergency stop. Please always call shutdown() before this. Kills registration, sessions & presence - everything.
* onStop() is called in context of this method. */
void stop();
/* Checks if user agent is active (started). */
@@ -268,7 +273,8 @@ public:
virtual void onClientObserverStop(PClientObserver observer, int code);
virtual void onServerObserverStop(PServerObserver observer, int code);
virtual void onPresenceUpdate(PClientObserver observer, const std::string& peer, bool online, const std::string& content);
virtual void onPresenceUpdate(PClientObserver observer, const std::string& peer, bool online,
const std::string& content);
virtual void onMessageArrived(PAccount account, const std::string& peer, const void* ptr, unsigned length);
virtual void onMessageFailed(PAccount account, int id, const std::string& peer, int code, void* tag);
virtual void onMessageSent(PAccount account, int id, const std::string& peer, void* tag);
@@ -280,14 +286,17 @@ public:
// InviteSessionHandler implementation
#pragma region InviteSessionHandler implementation
/// called when an initial INVITE or the intial response to an outoing invite
virtual void onNewSession(resip::ClientInviteSessionHandle, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg) override;
virtual void onNewSession(resip::ServerInviteSessionHandle, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg) override;
virtual void onNewSession(resip::ClientInviteSessionHandle, resip::InviteSession::OfferAnswerType oat,
const resip::SipMessage& msg) override;
virtual void onNewSession(resip::ServerInviteSessionHandle, resip::InviteSession::OfferAnswerType oat,
const resip::SipMessage& msg) override;
/// Received a failure response from UAS
virtual void onFailure(resip::ClientInviteSessionHandle, const resip::SipMessage& msg) override;
/// called when an in-dialog provisional response is received that contains an SDP body
virtual void onEarlyMedia(resip::ClientInviteSessionHandle, const resip::SipMessage&, const resip::SdpContents&) override;
virtual void onEarlyMedia(resip::ClientInviteSessionHandle, const resip::SipMessage&,
const resip::SdpContents&) override;
/// called when dialog enters the Early state - typically after getting 18x
virtual void onProvisional(resip::ClientInviteSessionHandle, const resip::SipMessage&) override;
@@ -298,7 +307,8 @@ public:
/// called when a dialog initiated as a UAS enters the connected state
virtual void onConnected(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
virtual void onTerminated(resip::InviteSessionHandle, resip::InviteSessionHandler::TerminatedReason reason, const resip::SipMessage* related=0) override;
virtual void onTerminated(resip::InviteSessionHandle, resip::InviteSessionHandler::TerminatedReason reason,
const resip::SipMessage* related = 0) override;
/// called when a fork that was created through a 1xx never receives a 2xx
/// because another fork answered and this fork was canceled by a proxy.
@@ -345,7 +355,8 @@ public:
/// rejected using the server subscription. If the offer is accepted,
/// DialogUsageManager::makeInviteSessionFromRefer can be used to create an
/// InviteSession that will send notify messages using the ServerSubscription
virtual void onRefer(resip::InviteSessionHandle, resip::ServerSubscriptionHandle, const resip::SipMessage& msg) override;
virtual void onRefer(resip::InviteSessionHandle, resip::ServerSubscriptionHandle,
const resip::SipMessage& msg) override;
virtual void onReferNoSub(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
@@ -353,7 +364,8 @@ public:
virtual void onReferRejected(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
/// called when an REFER message receives an accepted response
virtual void onReferAccepted(resip::InviteSessionHandle, resip::ClientSubscriptionHandle, const resip::SipMessage& msg) override;
virtual void onReferAccepted(resip::InviteSessionHandle, resip::ClientSubscriptionHandle,
const resip::SipMessage& msg) override;
#pragma endregion
// ClientRegistrationHandler implementation
@@ -377,14 +389,9 @@ public:
#pragma region ExternalLogger implementation
/** return true to also do default logging, false to suppress default logging. */
virtual bool operator()(resip::Log::Level level,
const resip::Subsystem& subsystem,
const resip::Data& appName,
const char* file,
int line,
const resip::Data& message,
const resip::Data& messageWithHeaders,
const resip::Data& instanceName) override;
virtual bool operator()(resip::Log::Level level, const resip::Subsystem& subsystem, const resip::Data& appName,
const char* file, int line, const resip::Data& message,
const resip::Data& messageWithHeaders, const resip::Data& instanceName) override;
#pragma endregion
#pragma region DnsResultSink implementation
@@ -413,13 +420,13 @@ public:
void onUpdatePending(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder) override;
void onUpdateActive(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder) override;
//unknown Subscription-State value
// unknown Subscription-State value
void onUpdateExtension(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder) override;
int onRequestRetry(resip::ClientSubscriptionHandle, int retrySeconds, const resip::SipMessage& notify) override;
//subscription can be ended through a notify or a failure response.
// subscription can be ended through a notify or a failure response.
void onTerminated(resip::ClientSubscriptionHandle, const resip::SipMessage* msg) override;
//not sure if this has any value.
// not sure if this has any value.
void onNewSubscription(resip::ClientSubscriptionHandle, const resip::SipMessage& notify) override;
/// called to allow app to adorn a message.
@@ -438,11 +445,13 @@ public:
#pragma region PagerHandler
void onSuccess(resip::ClientPagerMessageHandle, const resip::SipMessage& status) override;
void onFailure(resip::ClientPagerMessageHandle, const resip::SipMessage& status, std::unique_ptr<resip::Contents> contents) override;
void onFailure(resip::ClientPagerMessageHandle, const resip::SipMessage& status,
std::unique_ptr<resip::Contents> contents) override;
void onMessageArrived(resip::ServerPagerMessageHandle, const resip::SipMessage& message) override;
#pragma endregion
void onDumCanBeDeleted() override;
protected:
// Mutex to protect this instance
Mutex mGuard;
+8 -11
View File
@@ -1,19 +1,16 @@
#include "EP_NetworkQueue.h"
#include "EP_Engine.h"
WatcherQueue::WatcherQueue(UserAgent& ua)
:mActiveId(0), mAgent(ua)
{}
WatcherQueue::WatcherQueue(UserAgent& ua) : mActiveId(0), mAgent(ua) {}
WatcherQueue::~WatcherQueue()
{}
WatcherQueue::~WatcherQueue() {}
int WatcherQueue::add(const std::string& peer, const std::string& package, void* tag)
{
ice::Lock l(mGuard);
// Check if queue has similar item
for (unsigned i=0; i<mItemList.size(); i++)
for (unsigned i = 0; i < mItemList.size(); i++)
{
Item& item = mItemList[i];
if (item.mTarget == peer && item.mPackage == package && item.mState != Item::State_Deleting)
@@ -43,7 +40,7 @@ void WatcherQueue::remove(int id)
ice::Lock l(mGuard);
// Check if queue has similar item
for (auto& item: mItemList)
for (auto& item : mItemList)
{
if (item.mId == id && id)
{
@@ -60,7 +57,7 @@ void WatcherQueue::refresh(int id)
ice::Lock l(mGuard);
// Check if queue has similar item
for (auto& item: mItemList)
for (auto& item : mItemList)
{
if (item.mId == id && id)
{
@@ -77,7 +74,7 @@ void WatcherQueue::process()
{
// Find next item to process
ItemList::iterator i = mItemList.begin();
for (;i != mItemList.end() && !i->scheduled(); i++)
for (; i != mItemList.end() && !i->scheduled(); i++)
;
if (i == mItemList.end())
return;
@@ -161,7 +158,7 @@ void WatcherQueue::onEstablished(int id, int code)
WatcherQueue::ItemList::iterator WatcherQueue::findById(int id)
{
for (ItemList::iterator i=mItemList.begin(); i != mItemList.end(); i++)
for (ItemList::iterator i = mItemList.begin(); i != mItemList.end(); i++)
if (i->mId == id)
return i;
return mItemList.end();
@@ -170,7 +167,7 @@ WatcherQueue::ItemList::iterator WatcherQueue::findById(int id)
void WatcherQueue::clear()
{
ice::Lock l(mGuard);
for (ItemList::iterator i=mItemList.begin(); i != mItemList.end(); i++)
for (ItemList::iterator i = mItemList.begin(); i != mItemList.end(); i++)
{
if (i->mHandle.isValid())
i->mHandle->end();
+3 -3
View File
@@ -35,12 +35,12 @@ public:
void* mTag = nullptr; // User tag
int mId = 0; // Related session ID - it is always non-zero (zero is here for initialization only)
Item()
{}
Item() {}
bool scheduled()
{
return mState == State_ScheduledToAdd || mState == State_ScheduledToDelete || mState == State_ScheduledToRefresh;
return mState == State_ScheduledToAdd || mState == State_ScheduledToDelete ||
mState == State_ScheduledToRefresh;
}
};
WatcherQueue(UserAgent& agent);
+4 -13
View File
@@ -9,13 +9,9 @@
#include <resip/stack/Pidf.hxx>
#include <resip/dum/ClientSubscription.hxx>
ClientObserver::ClientObserver()
{
}
ClientObserver::ClientObserver() {}
ClientObserver::~ClientObserver()
{
}
ClientObserver::~ClientObserver() {}
void ClientObserver::refresh()
{
@@ -27,8 +23,7 @@ void ClientObserver::stop()
{
if (mHandle.isValid())
mHandle->end();
else
if (mSession)
else if (mSession)
{
mSession->runTerminatedEvent(ResipSession::Type_Subscription);
if (mSession)
@@ -42,11 +37,7 @@ std::string ClientObserver::peer()
return mPeer;
}
ServerObserver::ServerObserver()
:mState(State_Incoming)
{
}
ServerObserver::ServerObserver() : mState(State_Incoming) {}
ServerObserver::~ServerObserver()
{
+2
View File
@@ -23,6 +23,7 @@ class ClientObserver
{
friend class Account;
friend class UserAgent;
public:
ClientObserver();
~ClientObserver();
@@ -43,6 +44,7 @@ typedef std::shared_ptr<ClientObserver> PClientObserver;
class ServerObserver
{
friend class UserAgent;
public:
ServerObserver();
~ServerObserver();
+13 -12
View File
@@ -16,8 +16,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef _WIN32
# include <winsock2.h>
# include <windows.h>
#include <winsock2.h>
#include <windows.h>
#endif
#include <algorithm>
@@ -44,7 +44,6 @@ ReliableTunnel::ReliableTunnel(const char* streamname)
mBandwidth = 0;
mExitSignal = ::CreateEvent(NULL, FALSE, FALSE, NULL);
mDataSignal = ::CreateEvent(NULL, FALSE, FALSE, NULL);
}
ReliableTunnel::~ReliableTunnel()
@@ -141,7 +140,7 @@ DatagramSocket& ReliableTunnel::socket(int family)
bool ReliableTunnel::processSdpOffer(const resip::SdpContents::Session::Medium& media)
{
//check for default port number
// check for default port number
mDestination.setPort(media.port());
return true;
@@ -152,13 +151,13 @@ void ReliableTunnel::thread()
// Construct event array
while (true)
{
HANDLE eventarray[2] = { mDataSignal, mExitSignal };
HANDLE eventarray[2] = {mDataSignal, mExitSignal};
DWORD rescode = ::WaitForMultipleObjects(2, eventarray, FALSE, INFINITE);
if (rescode == WAIT_OBJECT_0)
{
resip::Lock l(mNewQueuedGuard);
for (unsigned i = 0; i<mNewQueued.size(); i++)
for (unsigned i = 0; i < mNewQueued.size(); i++)
mStack.queueOutgoing(mNewQueued[i].c_str(), mNewQueued[i].size());
mNewQueued.clear();
@@ -237,12 +236,13 @@ void ReliableTunnel::encrypt(void* dataPtr, int dataSize)
return;
#ifdef USE_OPENSSL
for (unsigned i=0; i<dataSize / blockSize(); i++)
BF_ecb_encrypt((unsigned char*)dataPtr + i * blockSize(), (unsigned char*)dataPtr + i * blockSize(), &mCipher, BF_ENCRYPT);
for (unsigned i = 0; i < dataSize / blockSize(); i++)
BF_ecb_encrypt((unsigned char*)dataPtr + i * blockSize(), (unsigned char*)dataPtr + i * blockSize(), &mCipher,
BF_ENCRYPT);
#endif
#ifdef USE_CRYPTOPP
for (unsigned i=0; i<dataSize / blockSize(); i++)
for (unsigned i = 0; i < dataSize / blockSize(); i++)
mEncryptor.ProcessBlock((unsigned char*)dataPtr + i * blockSize());
#endif
}
@@ -253,12 +253,13 @@ void ReliableTunnel::decrypt(void* dataPtr, int dataSize)
if (mEncryptionKey.empty())
return;
#ifdef USE_OPENSSL
for (unsigned i=0; i<dataSize / blockSize(); i++)
BF_ecb_encrypt((unsigned char*)dataPtr + i * blockSize(), (unsigned char*)dataPtr + i * blockSize(), &mCipher, BF_DECRYPT);
for (unsigned i = 0; i < dataSize / blockSize(); i++)
BF_ecb_encrypt((unsigned char*)dataPtr + i * blockSize(), (unsigned char*)dataPtr + i * blockSize(), &mCipher,
BF_DECRYPT);
#endif
#ifdef USE_CRYPTOPP
for (unsigned i=0; i<dataSize / blockSize(); i++)
for (unsigned i = 0; i < dataSize / blockSize(); i++)
mDecryptor.ProcessBlock((unsigned char*)dataPtr + i * blockSize());
#endif
}
+4 -5
View File
@@ -26,13 +26,13 @@
#include "../ICE/ICEReliableTransport.h"
#ifdef USE_CRYPTOPP
# include "../Libs/CryptoPP/blowfish.h"
#include "../Libs/CryptoPP/blowfish.h"
#endif
#ifdef USE_OPENSSL
# include "../Libs/openssl/include/openssl/blowfish.h"
#include "../Libs/openssl/include/openssl/blowfish.h"
#endif
class ReliableTunnel: public DataProvider, public resip::ThreadIf, public ICEImpl::ReliableTransport::Encryption
class ReliableTunnel : public DataProvider, public resip::ThreadIf, public ICEImpl::ReliableTransport::Encryption
{
public:
ReliableTunnel(const char* streamname);
@@ -111,8 +111,7 @@ protected:
// Mutex to protect queuing/sending outgoing data
resip::Mutex mOutgoingMtx;
std::vector<std::string>
mNewQueued;
std::vector<std::string> mNewQueued;
resip::Mutex mNewQueuedGuard;
resip::Mutex mStackGuard;
+89 -83
View File
@@ -16,18 +16,15 @@
typedef resip::SdpContents::Session::Medium Medium;
typedef resip::SdpContents::Session::MediumContainer MediumContainer;
#define IS_MULTIPLEX() mUserAgent->mConfig[CONFIG_MULTIPLEXING].asBool() ? SocketHeap::DoMultiplexing : SocketHeap::DontMultiplexing
#define IS_MULTIPLEX() \
mUserAgent->mConfig[CONFIG_MULTIPLEXING].asBool() ? SocketHeap::DoMultiplexing : SocketHeap::DontMultiplexing
//------------ ResipSessionAppDialog ------------
#pragma region ResipSessionAppDialog
ResipSessionAppDialog::ResipSessionAppDialog(resip::HandleManager& ham) : AppDialog(ham)
{
}
ResipSessionAppDialog::ResipSessionAppDialog(resip::HandleManager& ham) : AppDialog(ham) {}
ResipSessionAppDialog::~ResipSessionAppDialog()
{
}
ResipSessionAppDialog::~ResipSessionAppDialog() {}
#pragma endregion
@@ -54,7 +51,7 @@ ResipSession::~ResipSession()
mSession->mResipSession = nullptr;
runTerminatedEvent(Type_Auto, 0, 0);
}
catch(...)
catch (...)
{
}
@@ -94,7 +91,8 @@ void ResipSession::runTerminatedEvent(Type type, int code, int reason)
case Type_Subscription:
if (mSession)
{
UserAgent::ClientObserverMap::iterator observerIter = mUserAgent->mClientObserverMap.find(mSession->sessionId());
UserAgent::ClientObserverMap::iterator observerIter =
mUserAgent->mClientObserverMap.find(mSession->sessionId());
if (observerIter != mUserAgent->mClientObserverMap.end())
mUserAgent->onClientObserverStop(observerIter->second, code);
}
@@ -186,14 +184,9 @@ std::shared_ptr<resip::UserProfile> ResipSession::selectUASUserProfile(const res
#pragma endregion
#pragma region Session::Stream
Session::Stream::Stream()
:mRtcpAttr(false), mRtcpMuxAttr(false)
{
}
Session::Stream::Stream() : mRtcpAttr(false), mRtcpMuxAttr(false) {}
Session::Stream::~Stream()
{
}
Session::Stream::~Stream() {}
void Session::Stream::setProvider(PDataProvider provider)
{
@@ -290,14 +283,15 @@ Session::~Session()
mResipSession->setSession(NULL);
clearProvidersAndSockets();
}
catch(...)
{}
catch (...)
{
}
InstanceCounter--;
}
void Session::start(const std::string& peer)
{
ICELogInfo( << "Attempt to start session to " << peer);
ICELogInfo(<< "Attempt to start session to " << peer);
Lock l(mGuard);
if (mResipSession)
@@ -334,7 +328,7 @@ void Session::stop()
{
ICELogInfo(<< "Stopping session " << mSessionId);
Lock l(mGuard);
for (unsigned i=0; i<mStreamList.size(); i++)
for (unsigned i = 0; i < mStreamList.size(); i++)
{
Session::Stream& dataStream = mStreamList[i];
@@ -344,8 +338,8 @@ void Session::stop()
dataStream.provider()->sessionTerminated();
// Free socket
SocketHeap::instance().freeSocketPair( dataStream.socket4() );
SocketHeap::instance().freeSocketPair( dataStream.socket6() );
SocketHeap::instance().freeSocketPair(dataStream.socket4());
SocketHeap::instance().freeSocketPair(dataStream.socket6());
// Drop the references so the destructor's cleanup does not free them again
dataStream.setSocket4(RtpPair<PDatagramSocket>());
@@ -366,7 +360,8 @@ void Session::accept()
Lock locksession(mGuard);
// If ICE candidate gathering is not finished - just mark session as accepted. It will be accepted in ICE handling code.
// If ICE candidate gathering is not finished - just mark session as accepted. It will be accepted in ICE handling
// code.
mAcceptedByUser = true;
if (mGatheredCandidates || mIceStack->state() == ice::IceNone)
@@ -405,7 +400,7 @@ void Session::accept()
void Session::reject(int code)
{
ICELogInfo( << "Attempt to reject session " << mSessionId);
ICELogInfo(<< "Attempt to reject session " << mSessionId);
Lock l(mGuard);
@@ -450,7 +445,7 @@ void Session::getSessionInfo(Session::InfoOptions options, VariantMap& info)
// Iterate all session providers
Stream* media = nullptr;
for (Stream& stream: mStreamList)
for (Stream& stream : mStreamList)
{
if (!stream.provider())
continue;
@@ -473,7 +468,9 @@ void Session::getSessionInfo(Session::InfoOptions options, VariantMap& info)
info[SessionInfo_SentRtp] = static_cast<int>(stat.mSentRtp);
info[SessionInfo_SentRtcp] = static_cast<int>(stat.mSentRtcp);
if (stat.mFirstRtpTime)
info[SessionInfo_Duration] = static_cast<int>(std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - *(stat.mFirstRtpTime)).count());
info[SessionInfo_Duration] = static_cast<int>(
std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - *(stat.mFirstRtpTime))
.count());
else
info[SessionInfo_Duration] = 0;
@@ -481,7 +478,8 @@ void Session::getSessionInfo(Session::InfoOptions options, VariantMap& info)
info[SessionInfo_PacketLoss] = static_cast<int>((stat.mPacketLoss * 1000) / stat.mReceivedRtp);
if (media && mIceStack)
info[SessionInfo_AudioPeer] = mIceStack->remoteAddress(media->iceInfo().mStreamId, media->iceInfo().mComponentId.mRtp).toStdString();
info[SessionInfo_AudioPeer] =
mIceStack->remoteAddress(media->iceInfo().mStreamId, media->iceInfo().mComponentId.mRtp).toStdString();
info[SessionInfo_Jitter] = stat.mJitter;
if (stat.mRttDelay.is_initialized())
@@ -505,7 +503,8 @@ PAccount Session::account()
return mAccount;
}
void Session::onReceivedData(PDatagramSocket socket, InternetAddress& src, const void* receivedPtr, unsigned receivedSize)
void Session::onReceivedData(PDatagramSocket socket, InternetAddress& src, const void* receivedPtr,
unsigned receivedSize)
{
Lock l(mGuard);
@@ -513,7 +512,7 @@ void Session::onReceivedData(PDatagramSocket socket, InternetAddress& src, const
return;
// Check if it STUN packet and must be processed by ICE stack
//ICELogDebug (<< "Received UDP packet from " << src.ip() << ":" << src.port());
// ICELogDebug (<< "Received UDP packet from " << src.ip() << ":" << src.port());
ice::ByteBuffer received(receivedPtr, receivedSize);
received.setRemoteAddress(src);
@@ -531,7 +530,7 @@ void Session::onReceivedData(PDatagramSocket socket, InternetAddress& src, const
if (received.size() >= 4)
{
bool turnPrefix = false;
for (unsigned i=0; i<mTurnPrefixList.size() && !turnPrefix; i++)
for (unsigned i = 0; i < mTurnPrefixList.size() && !turnPrefix; i++)
turnPrefix |= ice::Stack::isChannelData(received, mTurnPrefixList[i]);
if (turnPrefix)
received.erase(0, 4);
@@ -546,7 +545,7 @@ void Session::onReceivedData(PDatagramSocket socket, InternetAddress& src, const
{
ice::ByteBuffer buffer(receivedPtr, receivedSize);
buffer.setRemoteAddress(src);
/*bool processed = */mIceStack->processIncomingData(stream, component, buffer);
/*bool processed = */ mIceStack->processIncomingData(stream, component, buffer);
}
}
else
@@ -594,8 +593,7 @@ void Session::onGathered(ice::Stack* stack, void* tag)
if (mRole == Initiator)
mUserAgent->sendOffer(this);
else
if (mRole == Acceptor)
else if (mRole == Acceptor)
{
// Mark session as gathered ICE candidates
mGatheredCandidates = true;
@@ -616,7 +614,7 @@ void Session::onSuccess(ice::Stack* stack, void* tag)
RtpPair<InternetAddress> t;
for (unsigned i=0; i<this->mStreamList.size(); i++)
for (unsigned i = 0; i < this->mStreamList.size(); i++)
{
PDataProvider p = mStreamList[i].provider();
if (p)
@@ -638,8 +636,8 @@ void Session::onSuccess(ice::Stack* stack, void* tag)
mUserAgent->onSessionEstablished(mUserAgent->getUserSession(mSessionId), EV_ICE, t);
//time to resend updated media info over SIP
//TODO:
// time to resend updated media info over SIP
// TODO:
}
void Session::onFailed(ice::Stack* stack, void* tag)
@@ -647,17 +645,17 @@ void Session::onFailed(ice::Stack* stack, void* tag)
ICELogError(<< "ICE connectivity check failed for session " << mSessionId);
mUserAgent->onConnectivityFailed(mUserAgent->getUserSession(mSessionId));
//if (mInviteHandle.isValid())
// if (mInviteHandle.isValid())
// mInviteHandle->end();
}
void Session::onNetworkChange(ice::Stack *stack, void *tag)
void Session::onNetworkChange(ice::Stack* stack, void* tag)
{
ICELogInfo(<< "Network change detected by ICE stack for session " << mSessionId);
mUserAgent->onNetworkChange(mUserAgent->getUserSession(mSessionId));
}
void Session::buildSdp(resip::SdpContents &sdp, SdpDirection sdpDirection)
void Session::buildSdp(resip::SdpContents& sdp, SdpDirection sdpDirection)
{
sdp.session().name() = "ICE_UA";
sdp.session().origin().user() = "user";
@@ -675,8 +673,12 @@ void Session::buildSdp(resip::SdpContents &sdp, SdpDirection sdpDirection)
ice::NetworkAddress defaultAddr = mIceStack->defaultAddress(mStreamList.front().iceInfo().mStreamId, ICE_RTP_ID);
// Set IP address for origin and connection
sdp.session().origin().setAddress(resip::Data(defaultAddr.ip()), defaultAddr.family() == AF_INET ? resip::SdpContents::IP4 : resip::SdpContents::IP6);
sdp.session().connection().setAddress(resip::Data(defaultAddr.ip()), defaultAddr.family() == AF_INET ? resip::SdpContents::IP4 : resip::SdpContents::IP6);
sdp.session().origin().setAddress(resip::Data(defaultAddr.ip()), defaultAddr.family() == AF_INET
? resip::SdpContents::IP4
: resip::SdpContents::IP6);
sdp.session().connection().setAddress(resip::Data(defaultAddr.ip()), defaultAddr.family() == AF_INET
? resip::SdpContents::IP4
: resip::SdpContents::IP6);
// Add ICE credentials
if (mIceStack->state() > ice::IceNone)
@@ -686,7 +688,7 @@ void Session::buildSdp(resip::SdpContents &sdp, SdpDirection sdpDirection)
}
// Iterate media streams
for (unsigned i=0; i<mStreamList.size(); i++)
for (unsigned i = 0; i < mStreamList.size(); i++)
{
Stream& stream = mStreamList[i];
if (!stream.provider())
@@ -698,18 +700,18 @@ void Session::buildSdp(resip::SdpContents &sdp, SdpDirection sdpDirection)
rtcpPort = mIceStack->defaultAddress(mStreamList[i].iceInfo().mStreamId, ICE_RTCP_ID);
// Define media stream SDP's header
resip::SdpContents::Session::Medium media(resip::Data(provider.streamName()), rtpPort.port(), 0, resip::Data(provider.streamProfile()));
resip::SdpContents::Session::Medium media(resip::Data(provider.streamName()), rtpPort.port(), 0,
resip::Data(provider.streamProfile()));
// Add "rtcp" attribute
if (mUserAgent->mConfig[CONFIG_RTCP_ATTR].asBool())
{
if (mUserAgent->mConfig[CONFIG_MULTIPLEXING].asBool())
rtcpPort = rtpPort;
else
if (rtcpPort.isEmpty())
else if (rtcpPort.isEmpty())
{
rtcpPort = rtpPort;
rtcpPort.setPort( rtpPort.port() + 1);
rtcpPort.setPort(rtpPort.port() + 1);
}
media.addAttribute("rtcp", resip::Data(rtcpPort.port()));
@@ -732,7 +734,7 @@ void Session::buildSdp(resip::SdpContents &sdp, SdpDirection sdpDirection)
if (mIceStack->hasComponent(ii.mStreamId, ii.mComponentId.mRtcp))
mIceStack->fillCandidateList(ii.mStreamId, ii.mComponentId.mRtcp, candidates);
for (unsigned c=0; c<candidates.size(); c++)
for (unsigned c = 0; c < candidates.size(); c++)
media.addAttribute("candidate", candidates[c].c_str());
}
@@ -766,7 +768,7 @@ void Session::addProvider(PDataProvider provider)
return;
// Avoid duplicating providers
for (unsigned i=0; i<mStreamList.size(); i++)
for (unsigned i = 0; i < mStreamList.size(); i++)
if (mStreamList[i].provider() == provider)
return;
@@ -777,18 +779,18 @@ void Session::addProvider(PDataProvider provider)
{
if (!streamIter->provider() && (streamIter->socket4().mRtp->isValid() || streamIter->socket6().mRtp->isValid()))
{
streamIter->setProvider( provider );
streamIter->setProvider(provider);
provider->setSocket(streamIter->socket4(), streamIter->socket6());
return;
}
}
Stream s;
s.setProvider( provider );
s.setProvider(provider);
// Allocate socket for provider
s.setSocket4( SocketHeap::instance().allocSocketPair(AF_INET, this, IS_MULTIPLEX()) );
s.setSocket6( SocketHeap::instance().allocSocketPair(AF_INET6, this, IS_MULTIPLEX()) );
s.setSocket4(SocketHeap::instance().allocSocketPair(AF_INET, this, IS_MULTIPLEX()));
s.setSocket6(SocketHeap::instance().allocSocketPair(AF_INET6, this, IS_MULTIPLEX()));
s.provider()->setSocket(s.socket4(), s.socket6());
// Create ICE stream/component
@@ -797,10 +799,11 @@ void Session::addProvider(PDataProvider provider)
ii.mPort4 = s.socket4().mRtp->localport();
ii.mPort6 = s.socket6().mRtp->localport();
ii.mComponentId.mRtp = mIceStack->addComponent(ii.mStreamId, NULL, s.socket4().mRtp->localport(),
s.socket6().mRtp->localport());
ii.mComponentId.mRtp =
mIceStack->addComponent(ii.mStreamId, NULL, s.socket4().mRtp->localport(), s.socket6().mRtp->localport());
if (!mUserAgent->mConfig[CONFIG_MULTIPLEXING].asBool())
ii.mComponentId.mRtcp = mIceStack->addComponent(ii.mStreamId, NULL, s.socket4().mRtcp->localport(), s.socket6().mRtcp->localport());
ii.mComponentId.mRtcp =
mIceStack->addComponent(ii.mStreamId, NULL, s.socket4().mRtcp->localport(), s.socket6().mRtcp->localport());
s.setIceInfo(ii);
@@ -857,7 +860,7 @@ void Session::setTag(void* tag)
void Session::pause()
{
for (unsigned i=0; i<mStreamList.size(); i++)
for (unsigned i = 0; i < mStreamList.size(); i++)
{
Stream& s = mStreamList[i];
if (s.provider())
@@ -868,7 +871,7 @@ void Session::pause()
void Session::resume()
{
for (unsigned i=0; i<mStreamList.size(); i++)
for (unsigned i = 0; i < mStreamList.size(); i++)
{
Stream& s = mStreamList[i];
if (s.provider())
@@ -880,9 +883,9 @@ void Session::resume()
void Session::refreshMediaPath()
{
// Recreate media sockets
for (unsigned i=0; i<mStreamList.size(); i++)
for (unsigned i = 0; i < mStreamList.size(); i++)
{
Stream& s= mStreamList[i];
Stream& s = mStreamList[i];
PDataProvider p = s.provider();
if (!p)
continue;
@@ -891,7 +894,7 @@ void Session::refreshMediaPath()
SocketHeap::instance().freeSocketPair(p->socket(AF_INET));
// Bring new socket to provider and stream
RtpPair<PDatagramSocket> s4 = SocketHeap::instance().allocSocketPair(AF_INET, this, IS_MULTIPLEX() ),
RtpPair<PDatagramSocket> s4 = SocketHeap::instance().allocSocketPair(AF_INET, this, IS_MULTIPLEX()),
s6 = SocketHeap::instance().allocSocketPair(AF_INET6, this, IS_MULTIPLEX());
p->setSocket(s4, s6);
@@ -929,7 +932,7 @@ int Session::processSdp(uint64_t version, bool iceAvailable, std::string icePwd,
// Ask about provider if needed
if (!stream.provider())
stream.setProvider( mUserAgent->onProviderNeeded(remoteStream.name().c_str()) );
stream.setProvider(mUserAgent->onProviderNeeded(remoteStream.name().c_str()));
// Check the stream validity
if (!stream.provider())
@@ -938,8 +941,8 @@ int Session::processSdp(uint64_t version, bool iceAvailable, std::string icePwd,
continue;
// See for rtcp & rtcp-mux attribute
stream.setRtcpAttr( remoteStream.exists("rtcp") );
stream.setRtcpMuxAttr( remoteStream.exists("rtcp-mux") );
stream.setRtcpAttr(remoteStream.exists("rtcp"));
stream.setRtcpMuxAttr(remoteStream.exists("rtcp-mux"));
// Set destination address
if (!remoteStream.getConnections().empty())
@@ -951,12 +954,12 @@ int Session::processSdp(uint64_t version, bool iceAvailable, std::string icePwd,
targetAddr.mRtcp.setIp(remoteIp);
if (stream.rtcpMuxAttr())
targetAddr.mRtcp.setPort( remoteStream.port() );
targetAddr.mRtcp.setPort(remoteStream.port());
else if (stream.rtcpAttr())
targetAddr.mRtcp.setPort(
strx::toInt(remoteStream.getValues("rtcp").front().c_str(), remoteStream.port() + 1));
else
if (stream.rtcpAttr())
targetAddr.mRtcp.setPort( strx::toInt(remoteStream.getValues("rtcp").front().c_str(), remoteStream.port() + 1 ) );
else
targetAddr.mRtcp.setPort( remoteStream.port() + 1);
targetAddr.mRtcp.setPort(remoteStream.port() + 1);
stream.provider()->setDestinationAddress(targetAddr);
@@ -974,9 +977,9 @@ int Session::processSdp(uint64_t version, bool iceAvailable, std::string icePwd,
stream.setSocket4(SocketHeap::instance().allocSocketPair(AF_INET, this, IS_MULTIPLEX()));
stream.setSocket6(SocketHeap::instance().allocSocketPair(AF_INET6, this, IS_MULTIPLEX()));
}
catch(...)
catch (...)
{
ICELogError( << "Cannot create media socket.");
ICELogError(<< "Cannot create media socket.");
return 503;
}
@@ -1005,13 +1008,15 @@ int Session::processSdp(uint64_t version, bool iceAvailable, std::string icePwd,
// See what remote peer offers - offer only single ice component if it relies on multiplexing
if (!targetAddr.multiplexed() && !mUserAgent->mConfig[CONFIG_MULTIPLEXING].asBool())
ii.mComponentId.mRtcp = mIceStack->addComponent(ii.mStreamId, NULL, stream.socket4().mRtcp->localport(), stream.socket6().mRtcp->localport());
ii.mComponentId.mRtcp = mIceStack->addComponent(ii.mStreamId, NULL, stream.socket4().mRtcp->localport(),
stream.socket6().mRtcp->localport());
stream.setIceInfo(ii);
}
if (iceAvailable)
{
if (mIceStack->remotePassword(stream.iceInfo().mStreamId) != icePwd || mIceStack->remoteUfrag(stream.iceInfo().mStreamId) != iceUfrag)
if (mIceStack->remotePassword(stream.iceInfo().mStreamId) != icePwd ||
mIceStack->remoteUfrag(stream.iceInfo().mStreamId) != iceUfrag)
{
iceRestart = true;
mIceStack->setRemotePassword(icePwd, stream.iceInfo().mStreamId);
@@ -1032,9 +1037,11 @@ int Session::processSdp(uint64_t version, bool iceAvailable, std::string icePwd,
if (candidateVector.empty())
iceAvailable = false;
// Ask ICE stack to process this information. This call will remove also second component if it is not defined in remote sdp.
// Ask ICE stack to process this information. This call will remove also second component if it is not defined
// in remote sdp.
if (iceAvailable)
iceAvailable = mIceStack->processSdpOffer(stream.iceInfo().mStreamId, candidateVector, remoteIp, remotePort, mUserAgent->mConfig[CONFIG_DEFERRELAYED].asBool());
iceAvailable = mIceStack->processSdpOffer(stream.iceInfo().mStreamId, candidateVector, remoteIp, remotePort,
mUserAgent->mConfig[CONFIG_DEFERRELAYED].asBool());
}
// See if there are compatible media streams
@@ -1081,22 +1088,22 @@ int Session::release()
void Session::clearProvidersAndSockets()
{
for (unsigned i=0; i<mStreamList.size(); i++)
for (unsigned i = 0; i < mStreamList.size(); i++)
{
Session::Stream& ds = mStreamList[i];
if (ds.provider())
{
ds.provider()->sessionDeleted();
SocketHeap::instance().freeSocketPair( ds.socket4() );
SocketHeap::instance().freeSocketPair( ds.socket6() );
SocketHeap::instance().freeSocketPair(ds.socket4());
SocketHeap::instance().freeSocketPair(ds.socket6());
}
}
}
void Session::clearProviders()
{
for (unsigned i=0; i<mStreamList.size(); i++)
for (unsigned i = 0; i < mStreamList.size(); i++)
{
Session::Stream& ds = mStreamList[i];
@@ -1132,14 +1139,13 @@ void Session::processQueuedOffer()
//-------------- ResipSessionFactory ---------
#pragma region ResipSessionFactory
ResipSessionFactory::ResipSessionFactory(UserAgent* agent)
:mAgent(agent)
{}
ResipSessionFactory::ResipSessionFactory(UserAgent* agent) : mAgent(agent) {}
resip::AppDialogSet* ResipSessionFactory::createAppDialogSet(resip::DialogUsageManager& dum, const resip::SipMessage& msg)
resip::AppDialogSet* ResipSessionFactory::createAppDialogSet(resip::DialogUsageManager& dum,
const resip::SipMessage& msg)
{
ResipSession* s = new ResipSession(dum);
s->setUa( mAgent );
s->setUa(mAgent);
return s;
}
+6 -8
View File
@@ -77,9 +77,7 @@ enum SessionInfo
};
class Session :
public SocketSink,
public ice::StageHandler
class Session : public SocketSink, public ice::StageHandler
{
public:
class Command
@@ -91,8 +89,7 @@ public:
// Describes ice stream/component
struct IceInfo
{
IceInfo()
:mStreamId(-1)
IceInfo() : mStreamId(-1)
{
mPort4 = mPort6 = 0;
mComponentId.mRtp = mComponentId.mRtcp = -1;
@@ -342,10 +339,10 @@ public:
virtual ~ResipSessionAppDialog();
};
class ResipSession: public resip::AppDialogSet
class ResipSession : public resip::AppDialogSet
{
friend class UserAgent;
friend class Account;
friend class UserAgent;
friend class Account;
public:
enum Type
@@ -406,6 +403,7 @@ class ResipSessionFactory : public resip::AppDialogSetFactory
public:
ResipSessionFactory(UserAgent* agent);
virtual resip::AppDialogSet* createAppDialogSet(resip::DialogUsageManager& dum, const resip::SipMessage& msg);
protected:
UserAgent* mAgent;
};
+4 -4
View File
@@ -9,7 +9,7 @@
#define USE_SPEEX_AEC
// TODO: test implementation with webrtc aec; be careful - it needs fixes!
//#define USE_WEBRTC_AEC
// #define USE_WEBRTC_AEC
#define USER
@@ -36,8 +36,8 @@
// Defined these two lines to get dumping of audio input/output
//#define AUDIO_DUMPINPUT
//#define AUDIO_DUMPOUTPUT
// #define AUDIO_DUMPINPUT
// #define AUDIO_DUMPOUTPUT
#define UA_REGISTRATION_TIME 3600
@@ -107,7 +107,7 @@
#define MT_MIRROR_PREBUFFER (MT_SAMPLERATE / 10)
#if defined(TARGET_OSX) || defined(TARGET_LINUX)
# define TEXT(X) X
#define TEXT(X) X
#endif
// In milliseconds
+2 -8
View File
@@ -5,12 +5,6 @@
#include "HL_AsyncCommand.h"
AsyncCommand::AsyncCommand()
{
AsyncCommand::AsyncCommand() {}
}
AsyncCommand::~AsyncCommand()
{
}
AsyncCommand::~AsyncCommand() {}
+119 -71
View File
@@ -7,9 +7,11 @@ const char kBase64Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
class Base64 {
public:
static bool Encode(const std::string &in, std::string *out) {
class Base64
{
public:
static bool Encode(const std::string& in, std::string* out)
{
int i = 0, j = 0;
size_t enc_len = 0;
unsigned char a3[3];
@@ -20,12 +22,15 @@ class Base64 {
int input_len = in.size();
std::string::const_iterator input = in.begin();
while (input_len--) {
while (input_len--)
{
a3[i++] = *(input++);
if (i == 3) {
if (i == 3)
{
a3_to_a4(a4, a3);
for (i = 0; i < 4; i++) {
for (i = 0; i < 4; i++)
{
(*out)[enc_len++] = kBase64Alphabet[a4[i]];
}
@@ -33,18 +38,22 @@ class Base64 {
}
}
if (i) {
for (j = i; j < 3; j++) {
if (i)
{
for (j = i; j < 3; j++)
{
a3[j] = '\0';
}
a3_to_a4(a4, a3);
for (j = 0; j < i + 1; j++) {
for (j = 0; j < i + 1; j++)
{
(*out)[enc_len++] = kBase64Alphabet[a4[j]];
}
while ((i++ < 3)) {
while ((i++ < 3))
{
(*out)[enc_len++] = '=';
}
}
@@ -52,22 +61,27 @@ class Base64 {
return (enc_len == out->size());
}
static bool Encode(const char *input, size_t input_length, char *out, size_t out_length) {
static bool Encode(const char* input, size_t input_length, char* out, size_t out_length)
{
int i = 0, j = 0;
char *out_begin = out;
char* out_begin = out;
unsigned char a3[3];
unsigned char a4[4];
size_t encoded_length = EncodedLength(input_length);
if (out_length < encoded_length) return false;
if (out_length < encoded_length)
return false;
while (input_length--) {
while (input_length--)
{
a3[i++] = *input++;
if (i == 3) {
if (i == 3)
{
a3_to_a4(a4, a3);
for (i = 0; i < 4; i++) {
for (i = 0; i < 4; i++)
{
*out++ = kBase64Alphabet[a4[i]];
}
@@ -75,18 +89,22 @@ class Base64 {
}
}
if (i) {
for (j = i; j < 3; j++) {
if (i)
{
for (j = i; j < 3; j++)
{
a3[j] = '\0';
}
a3_to_a4(a4, a3);
for (j = 0; j < i + 1; j++) {
for (j = 0; j < i + 1; j++)
{
*out++ = kBase64Alphabet[a4[j]];
}
while ((i++ < 3)) {
while ((i++ < 3))
{
*out++ = '=';
}
}
@@ -94,7 +112,8 @@ class Base64 {
return (out == (out_begin + encoded_length));
}
static bool Decode(const std::string &in, std::string *out) {
static bool Decode(const std::string& in, std::string* out)
{
int i = 0, j = 0;
size_t dec_len = 0;
unsigned char a3[3];
@@ -105,20 +124,25 @@ class Base64 {
out->resize(DecodedLength(in));
while (input_len--) {
if (*input == '=') {
while (input_len--)
{
if (*input == '=')
{
break;
}
a4[i++] = *(input++);
if (i == 4) {
for (i = 0; i <4; i++) {
if (i == 4)
{
for (i = 0; i < 4; i++)
{
a4[i] = b64_lookup(a4[i]);
}
a4_to_a3(a3,a4);
a4_to_a3(a3, a4);
for (i = 0; i < 3; i++) {
for (i = 0; i < 3; i++)
{
(*out)[dec_len++] = a3[i];
}
@@ -126,18 +150,22 @@ class Base64 {
}
}
if (i) {
for (j = i; j < 4; j++) {
if (i)
{
for (j = i; j < 4; j++)
{
a4[j] = '\0';
}
for (j = 0; j < 4; j++) {
for (j = 0; j < 4; j++)
{
a4[j] = b64_lookup(a4[j]);
}
a4_to_a3(a3,a4);
a4_to_a3(a3, a4);
for (j = 0; j < i - 1; j++) {
for (j = 0; j < i - 1; j++)
{
(*out)[dec_len++] = a3[j];
}
}
@@ -145,30 +173,37 @@ class Base64 {
return (dec_len == out->size());
}
static bool Decode(const char *input, size_t input_length, char *out, size_t out_length) {
static bool Decode(const char* input, size_t input_length, char* out, size_t out_length)
{
int i = 0, j = 0;
char *out_begin = out;
char* out_begin = out;
unsigned char a3[3];
unsigned char a4[4];
size_t decoded_length = DecodedLength(input, input_length);
if (out_length < decoded_length) return false;
if (out_length < decoded_length)
return false;
while (input_length--) {
if (*input == '=') {
while (input_length--)
{
if (*input == '=')
{
break;
}
a4[i++] = *(input++);
if (i == 4) {
for (i = 0; i <4; i++) {
if (i == 4)
{
for (i = 0; i < 4; i++)
{
a4[i] = b64_lookup(a4[i]);
}
a4_to_a3(a3,a4);
a4_to_a3(a3, a4);
for (i = 0; i < 3; i++) {
for (i = 0; i < 3; i++)
{
*out++ = a3[i];
}
@@ -176,18 +211,22 @@ class Base64 {
}
}
if (i) {
for (j = i; j < 4; j++) {
if (i)
{
for (j = i; j < 4; j++)
{
a4[j] = '\0';
}
for (j = 0; j < 4; j++) {
for (j = 0; j < 4; j++)
{
a4[j] = b64_lookup(a4[j]);
}
a4_to_a3(a3,a4);
a4_to_a3(a3, a4);
for (j = 0; j < i - 1; j++) {
for (j = 0; j < i - 1; j++)
{
*out++ = a3[j];
}
}
@@ -195,62 +234,71 @@ class Base64 {
return (out == (out_begin + decoded_length));
}
static int DecodedLength(const char *in, size_t in_length) {
static int DecodedLength(const char* in, size_t in_length)
{
int numEq = 0;
const char *in_end = in + in_length;
while (*--in_end == '=') ++numEq;
const char* in_end = in + in_length;
while (*--in_end == '=')
++numEq;
return ((6 * in_length) / 8) - numEq;
}
static int DecodedLength(const std::string &in) {
static int DecodedLength(const std::string& in)
{
int numEq = 0;
int n = in.size();
for (std::string::const_reverse_iterator it = in.rbegin(); *it == '='; ++it) {
for (std::string::const_reverse_iterator it = in.rbegin(); *it == '='; ++it)
{
++numEq;
}
return ((6 * n) / 8) - numEq;
}
inline static int EncodedLength(size_t length) {
return (length + 2 - ((length + 2) % 3)) / 3 * 4;
inline static int EncodedLength(size_t length) { return (length + 2 - ((length + 2) % 3)) / 3 * 4; }
inline static int EncodedLength(const std::string& in) { return EncodedLength(in.length()); }
inline static void StripPadding(std::string* in)
{
while (!in->empty() && *(in->rbegin()) == '=')
in->resize(in->size() - 1);
}
inline static int EncodedLength(const std::string &in) {
return EncodedLength(in.length());
}
inline static void StripPadding(std::string *in) {
while (!in->empty() && *(in->rbegin()) == '=') in->resize(in->size() - 1);
}
private:
static inline void a3_to_a4(unsigned char * a4, unsigned char * a3) {
private:
static inline void a3_to_a4(unsigned char* a4, unsigned char* a3)
{
a4[0] = (a3[0] & 0xfc) >> 2;
a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4);
a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6);
a4[3] = (a3[2] & 0x3f);
}
static inline void a4_to_a3(unsigned char * a3, unsigned char * a4) {
static inline void a4_to_a3(unsigned char* a3, unsigned char* a4)
{
a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4);
a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2);
a3[2] = ((a4[2] & 0x3) << 6) + a4[3];
}
static inline unsigned char b64_lookup(unsigned char c) {
if(c >='A' && c <='Z') return c - 'A';
if(c >='a' && c <='z') return c - 71;
if(c >='0' && c <='9') return c + 4;
if(c == '+') return 62;
if(c == '/') return 63;
static inline unsigned char b64_lookup(unsigned char c)
{
if (c >= 'A' && c <= 'Z')
return c - 'A';
if (c >= 'a' && c <= 'z')
return c - 71;
if (c >= '0' && c <= '9')
return c + 4;
if (c == '+')
return 62;
if (c == '/')
return 63;
return 255;
}
};
#endif // HL_BASE64_H
+168 -155
View File
@@ -11,11 +11,11 @@
namespace Calc
{
class Parser;
namespace Ast
{
enum class Type
{
class Parser;
namespace Ast
{
enum class Type
{
None,
And,
Or,
@@ -32,33 +32,22 @@ namespace Calc
Number,
String,
Var
};
};
class Item;
typedef Item* PItem;
class Item;
typedef Item* PItem;
class Item
{
class Item
{
friend class Calc::Parser;
public:
bool isVariable() const
{
return mType == Type::Var;
}
bool isFixed() const
{
return mType == Type::Number || mType == Type::String;
}
bool isOperation() const
{
return mType >= Type::And && mType <= Type::Div;
}
public:
bool isVariable() const { return mType == Type::Var; }
bool isFixed() const { return mType == Type::Number || mType == Type::String; }
bool hasBrackets() const
{
return mHasBrackets;
}
bool isOperation() const { return mType >= Type::And && mType <= Type::Div; }
bool hasBrackets() const { return mHasBrackets; }
int getOperatorLevel() const
{
@@ -94,25 +83,13 @@ namespace Calc
assert(0);
}
Type getType() const
{
return mType;
}
Type getType() const { return mType; }
std::string getName() const
{
return mName;
}
std::string getName() const { return mName; }
Variant& value()
{
return mValue;
}
Variant& value() { return mValue; }
std::vector<PItem>& children()
{
return mChildren;
}
std::vector<PItem>& children() { return mChildren; }
typedef std::map<std::string, std::string> NameMap;
@@ -126,21 +103,54 @@ namespace Calc
oss << " ";
switch (mType)
{
case Type::Number: oss << mValue.asStdString(); break;
case Type::String: oss << '"' << mValue.asStdString() << '"'; break;
case Type::Var: { NameMap::const_iterator iter = nm.find(mName); oss << ((iter != nm.end()) ? iter->second : mName);} break;
case Type::Add: oss << "+"; break;
case Type::Mul: oss << "*"; break;
case Type::Div: oss << "/"; break;
case Type::Sub: oss << "-"; break;
case Type::Equal: oss << "=="; break;
case Type::NotEqual: oss << "!="; break;
case Type::Less: oss << "<"; break;
case Type::LessOrEqual: oss << "<="; break;
case Type::Greater: oss << ">"; break;
case Type::GreatorOrEqual: oss << ">="; break;
case Type::Or: oss << "or"; break;
case Type::And: oss << "and"; break;
case Type::Number:
oss << mValue.asStdString();
break;
case Type::String:
oss << '"' << mValue.asStdString() << '"';
break;
case Type::Var:
{
NameMap::const_iterator iter = nm.find(mName);
oss << ((iter != nm.end()) ? iter->second : mName);
}
break;
case Type::Add:
oss << "+";
break;
case Type::Mul:
oss << "*";
break;
case Type::Div:
oss << "/";
break;
case Type::Sub:
oss << "-";
break;
case Type::Equal:
oss << "==";
break;
case Type::NotEqual:
oss << "!=";
break;
case Type::Less:
oss << "<";
break;
case Type::LessOrEqual:
oss << "<=";
break;
case Type::Greater:
oss << ">";
break;
case Type::GreatorOrEqual:
oss << ">=";
break;
case Type::Or:
oss << "or";
break;
case Type::And:
oss << "and";
break;
default:
throw std::runtime_error("operator expected");
}
@@ -167,23 +177,56 @@ namespace Calc
switch (mType)
{
case Type::Number:
case Type::String: result = mValue; break;
case Type::Var: { auto iter = vm.find(mName); if (iter != vm.end()) return iter->second; else throw std::runtime_error("Variable " + mName + " did not find."); }
case Type::String:
result = mValue;
break;
case Type::Add: result = left + right; break;
case Type::Mul: result = left * right; break;
case Type::Div: result = left / right; break;
case Type::Sub: result = left - right; break;
case Type::Equal: result = left == right; break;
case Type::NotEqual: result = left != right; break;
case Type::Less: result = left < right; break;
case Type::LessOrEqual: result = left <= right; break;
case Type::Greater: result = left > right; break;
case Type::GreatorOrEqual: result = left >= right; break;
case Type::Or: result = left.asBool() || right.asBool(); break;
case Type::And: result = left.asBool() && right.asBool(); break;
case Type::Var:
{
auto iter = vm.find(mName);
if (iter != vm.end())
return iter->second;
else
throw std::runtime_error("Variable " + mName + " did not find.");
}
break;
case Type::Add:
result = left + right;
break;
case Type::Mul:
result = left * right;
break;
case Type::Div:
result = left / right;
break;
case Type::Sub:
result = left - right;
break;
case Type::Equal:
result = left == right;
break;
case Type::NotEqual:
result = left != right;
break;
case Type::Less:
result = left < right;
break;
case Type::LessOrEqual:
result = left <= right;
break;
case Type::Greater:
result = left > right;
break;
case Type::GreatorOrEqual:
result = left >= right;
break;
case Type::Or:
result = left.asBool() || right.asBool();
break;
case Type::And:
result = left.asBool() && right.asBool();
break;
default:
assert(0);
}
@@ -192,30 +235,30 @@ namespace Calc
~Item()
{
for (auto node: mChildren)
for (auto node : mChildren)
delete node;
mChildren.clear();
}
private:
private:
Type mType = Type::None;
std::string mName;
Variant mValue;
std::vector<PItem> mChildren;
bool mHasBrackets = false;
};
}
};
} // namespace Ast
static bool ishex(int c)
{
static bool ishex(int c)
{
if (isdigit(c))
return true;
return (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}
}
class Parser
{
private:
class Parser
{
private:
enum class LexemType
{
None,
@@ -234,15 +277,9 @@ namespace Calc
LexemType mType = LexemType::None;
std::string mValue;
operator bool () const
{
return mType != LexemType::None;
}
operator bool() const { return mType != LexemType::None; }
std::string toString() const
{
return std::to_string((int)mType) + " : " + mValue;
}
std::string toString() const { return std::to_string((int)mType) + " : " + mValue; }
};
Lexem mCurrentLexem;
@@ -252,20 +289,16 @@ namespace Calc
if (c == '(')
mCurrentLexem.mType = LexemType::OpenBracket;
else
if (c == ')')
else if (c == ')')
mCurrentLexem.mType = LexemType::CloseBracket;
else
if (isdigit(c))
else if (isdigit(c))
mCurrentLexem.mType = LexemType::Dec;
else
if (isalpha(c))
else if (isalpha(c))
mCurrentLexem.mType = LexemType::Var;
else
if (c == '+' || c == '-' || c == '/' || c == '*' || c == '=' || c == '<' || c == '>' || c == '&' || c == '|')
else if (c == '+' || c == '-' || c == '/' || c == '*' || c == '=' || c == '<' || c == '>' || c == '&' ||
c == '|')
mCurrentLexem.mType = LexemType::Oper;
else
if (c == '"')
else if (c == '"')
mCurrentLexem.mType = LexemType::Str;
else
return Lexem();
@@ -283,15 +316,9 @@ namespace Calc
if (mCurrentLexem.mType == LexemType::Oper)
{
if (mCurrentLexem.mValue == "+" ||
mCurrentLexem.mValue == "-" ||
mCurrentLexem.mValue == "*" ||
mCurrentLexem.mValue == "/" ||
mCurrentLexem.mValue == ">=" ||
mCurrentLexem.mValue == "<=" ||
mCurrentLexem.mValue == "==" ||
mCurrentLexem.mValue == "||" ||
mCurrentLexem.mValue == "&&")
if (mCurrentLexem.mValue == "+" || mCurrentLexem.mValue == "-" || mCurrentLexem.mValue == "*" ||
mCurrentLexem.mValue == "/" || mCurrentLexem.mValue == ">=" || mCurrentLexem.mValue == "<=" ||
mCurrentLexem.mValue == "==" || mCurrentLexem.mValue == "||" || mCurrentLexem.mValue == "&&")
{
// Lexem finished
result = mCurrentLexem;
@@ -357,8 +384,7 @@ namespace Calc
case LexemType::Dec:
if (c == 'x' && mCurrentLexem.mValue == "0")
mCurrentLexem.mType = LexemType::Hex;
else
if (isdigit(c) || c == '.')
else if (isdigit(c) || c == '.')
{
mCurrentLexem.mValue.push_back(c);
}
@@ -414,14 +440,14 @@ namespace Calc
if (putback)
input.putback(c);
else
if (!result)
else if (!result)
c = input.get();
}
checkNumericLexem();
// Recover partially processed lexem - maybe we finish processing at all but there is dec / float / string / variable
// Recover partially processed lexem - maybe we finish processing at all but there is dec / float / string /
// variable
if (mCurrentLexem.mType != LexemType::None && result.mType == LexemType::None)
result = mCurrentLexem;
@@ -441,38 +467,27 @@ namespace Calc
case LexemType::Oper:
if (l.mValue == "-")
result->mType = Ast::Type::Sub;
else
if (l.mValue == "+")
else if (l.mValue == "+")
result->mType = Ast::Type::Add;
else
if (l.mValue == "*")
else if (l.mValue == "*")
result->mType = Ast::Type::Mul;
else
if (l.mValue == "/")
else if (l.mValue == "/")
result->mType = Ast::Type::Div;
else
if (l.mValue == "<")
else if (l.mValue == "<")
result->mType = Ast::Type::Less;
else
if (l.mValue == "<=")
else if (l.mValue == "<=")
result->mType = Ast::Type::LessOrEqual;
else
if (l.mValue == ">")
else if (l.mValue == ">")
result->mType = Ast::Type::Greater;
else
if (l.mValue == ">=")
else if (l.mValue == ">=")
result->mType = Ast::Type::GreatorOrEqual;
else
if (l.mValue == "==")
else if (l.mValue == "==")
result->mType = Ast::Type::Equal;
else
if (l.mValue == "!=")
else if (l.mValue == "!=")
result->mType = Ast::Type::NotEqual;
else
if (l.mValue == "&&")
else if (l.mValue == "&&")
result->mType = Ast::Type::And;
else
if (l.mValue == "||")
else if (l.mValue == "||")
result->mType = Ast::Type::Or;
break;
@@ -509,11 +524,11 @@ namespace Calc
}
Lexem mLexem;
public:
public:
Ast::PItem parseExpression(std::istream& input)
{
Ast::PItem operationNode(nullptr), leftNode(nullptr), rightNode(nullptr),
currentOperation(nullptr);
Ast::PItem operationNode(nullptr), leftNode(nullptr), rightNode(nullptr), currentOperation(nullptr);
// While we have lexem
while (mLexem = getLexem(input))
@@ -545,8 +560,7 @@ namespace Calc
throw std::runtime_error("Open bracket or constant / number / string / variable expected.");
}
}
else
if (!operationNode)
else if (!operationNode)
{
// Well, there is left node already
// See operation here
@@ -573,10 +587,12 @@ namespace Calc
// Parse rest of expression
rightNode = parseExpression(input);
// If right part of expression is operation - make left side child of right part - to allow calculation in right order
// If right part of expression is operation - make left side child of right part - to allow calculation
// in right order
if (operationNode)
{
if (rightNode->isOperation() && rightNode->getOperatorLevel() <= operationNode->getOperatorLevel() && !rightNode->hasBrackets())
if (rightNode->isOperation() &&
rightNode->getOperatorLevel() <= operationNode->getOperatorLevel() && !rightNode->hasBrackets())
{
// Get left child of right expression - make it our right child
operationNode->children().push_back(leftNode);
@@ -598,11 +614,8 @@ namespace Calc
return currentOperation ? currentOperation : leftNode;
}
public:
Ast::PItem parse(std::istream& input)
{
return nullptr;
}
public:
Ast::PItem parse(std::istream& input) { return nullptr; }
void testLexemParser(const std::string& test)
{
@@ -613,14 +626,14 @@ namespace Calc
std::cout << "Lexem type: " << (int)l.mType << ", value: " << l.mValue << std::endl;
}
}
};
};
class Worker
{
public:
class Worker
{
public:
Variant eval(Ast::PItem ast);
};
}
};
} // namespace Calc
#endif
+23 -28
View File
@@ -17,19 +17,19 @@ BOOL WINAPI CrashReporter::Callback(LPVOID arg)
return TRUE;
}
typedef int(__stdcall *CrInstallProc)(__in PCR_INSTALL_INFOW pInfo);
typedef int(__stdcall* CrInstallProc)(__in PCR_INSTALL_INFOW pInfo);
static CrInstallProc CrInstall = nullptr;
typedef int(__stdcall *CrUninstallProc)();
typedef int(__stdcall* CrUninstallProc)();
static CrUninstallProc CrUninstall = nullptr;
typedef int(__stdcall *CrInstallIntoCurrentThreadProc)(DWORD dwFlags);
typedef int(__stdcall* CrInstallIntoCurrentThreadProc)(DWORD dwFlags);
static CrInstallIntoCurrentThreadProc CrInstallIntoCurrentThread = nullptr;
typedef int(__stdcall *CrUninstallFromCurrentThreadProc)();
typedef int(__stdcall* CrUninstallFromCurrentThreadProc)();
static CrUninstallFromCurrentThreadProc CrUninstallFromCurrentThread = nullptr;
typedef int(__stdcall *CrGetLastErrorMsgProc)(LPWSTR buffer, UINT size);
typedef int(__stdcall* CrGetLastErrorMsgProc)(LPWSTR buffer, UINT size);
static CrGetLastErrorMsgProc CrGetLastErrorMsg = nullptr;
static HMODULE CrLibraryHandle = NULL;
@@ -49,8 +49,10 @@ void CrashReporter::init(const std::string& appname, const std::string& version,
CrInstall = (CrInstallProc)::GetProcAddress(CrLibraryHandle, "crInstallW");
CrUninstall = (CrUninstallProc)::GetProcAddress(CrLibraryHandle, "crUninstall");
CrInstallIntoCurrentThread = (CrInstallIntoCurrentThreadProc)::GetProcAddress(CrLibraryHandle, "crInstallToCurrentThread2");
CrUninstallFromCurrentThread = (CrUninstallFromCurrentThreadProc)::GetProcAddress(CrLibraryHandle, "crUninstallFromCurrentThread");
CrInstallIntoCurrentThread =
(CrInstallIntoCurrentThreadProc)::GetProcAddress(CrLibraryHandle, "crInstallToCurrentThread2");
CrUninstallFromCurrentThread =
(CrUninstallFromCurrentThreadProc)::GetProcAddress(CrLibraryHandle, "crUninstallFromCurrentThread");
CrGetLastErrorMsg = (CrGetLastErrorMsgProc)::GetProcAddress(CrLibraryHandle, "crGetLastErrorMsgW");
#else
CrInstall = &crInstallW;
@@ -70,8 +72,7 @@ void CrashReporter::init(const std::string& appname, const std::string& version,
{
std::wstring appname, version, url;
} unicode;
unicode.appname = StringHelper::makeTstring(appname),
unicode.version = StringHelper::makeTstring(version),
unicode.appname = StringHelper::makeTstring(appname), unicode.version = StringHelper::makeTstring(version),
unicode.url = StringHelper::makeTstring(url);
if (unicode.appname.empty())
@@ -86,9 +87,9 @@ void CrashReporter::init(const std::string& appname, const std::string& version,
info.pszAppName = unicode.appname.c_str();
info.pszAppVersion = unicode.version.c_str();
info.pszEmailSubject = TEXT("Crash report");
//info.pszEmailTo = L"amegyeri@minerva-soft.com";
//info.pszUrl = L"http://ftp.minerva-soft.com/crashlog/crashrpt.php";
//info.pszUrl = L"http://sip.crypttalk.com/crashlog/crashrpt.php";
// info.pszEmailTo = L"amegyeri@minerva-soft.com";
// info.pszUrl = L"http://ftp.minerva-soft.com/crashlog/crashrpt.php";
// info.pszUrl = L"http://sip.crypttalk.com/crashlog/crashrpt.php";
info.pszUrl = unicode.url.c_str();
info.pfnCrashCallback = Callback;
info.uPriorities[CR_HTTP] = 1;
@@ -103,7 +104,8 @@ void CrashReporter::init(const std::string& appname, const std::string& version,
wchar_t errorMsg[512] = L"";
CrGetLastErrorMsg(errorMsg, 512);
OutputDebugStringW(errorMsg);
//LogCritical("Core", << "Failed to install CrashReporter with code " << nResult << " and message " << errorMsg);
// LogCritical("Core", << "Failed to install CrashReporter with code " << nResult << " and message " <<
// errorMsg);
}
#endif
}
@@ -120,7 +122,8 @@ void CrashReporter::free()
CrUninstallFromCurrentThread = nullptr;
CrGetLastErrorMsg = nullptr;
#if defined(CRASHRPT_DYNAMIC)
::FreeLibrary(CrLibraryHandle); CrLibraryHandle = NULL;
::FreeLibrary(CrLibraryHandle);
CrLibraryHandle = NULL;
#endif
}
#endif
@@ -129,8 +132,8 @@ void CrashReporter::free()
bool CrashReporter::isLoaded()
{
#if defined(TARGET_WIN)
return !(!CrInstall || !CrUninstall || !CrGetLastErrorMsg ||
!CrInstallIntoCurrentThread || !CrUninstallFromCurrentThread);
return !(!CrInstall || !CrUninstall || !CrGetLastErrorMsg || !CrInstallIntoCurrentThread ||
!CrUninstallFromCurrentThread);
#else
return false;
#endif
@@ -174,20 +177,12 @@ CrashReporterGuard::~CrashReporterGuard()
#else
CrashReporterThreadPoint::CrashReporterThreadPoint()
{
}
CrashReporterThreadPoint::CrashReporterThreadPoint() {}
CrashReporterThreadPoint::~CrashReporterThreadPoint()
{
}
CrashReporterThreadPoint::~CrashReporterThreadPoint() {}
CrashReporterGuard::CrashReporterGuard()
{
}
CrashReporterGuard::CrashReporterGuard() {}
CrashReporterGuard::~CrashReporterGuard()
{
}
CrashReporterGuard::~CrashReporterGuard() {}
#endif
+5 -4
View File
@@ -4,8 +4,8 @@
#include <string>
#if defined(TARGET_WIN)
# include <WinSock2.h>
# include <Windows.h>
#include <WinSock2.h>
#include <Windows.h>
#endif
// Helper class to translate SEH exceptions to C++ - sometimes it is needed
@@ -15,6 +15,7 @@ class SE_Exception
{
private:
unsigned int nSE;
public:
SE_Exception() {}
SE_Exception(unsigned int n) : nSE(n) {}
@@ -26,10 +27,10 @@ extern void SEHToCpp(unsigned int, EXCEPTION_POINTERS*);
// Although better way is to have _set_se_translator set - in our case we do not call it.
// The cause is usage of CrashRpt libraries - it gives better control on exception reporting.
# define SET_SEH_TO_CPP
#define SET_SEH_TO_CPP
//_set_se_translator(&SEHToCpp)
#else
# define SET_SEH_TO_CPP
#define SET_SEH_TO_CPP
#endif
class CrashReporter
+2 -5
View File
@@ -2,12 +2,9 @@
#include "HL_String.h"
// --------- CsvFile ----------------
CsvReader::CsvReader(std::istream& stream)
:mInputStream(stream)
{}
CsvReader::CsvReader(std::istream& stream) : mInputStream(stream) {}
CsvReader::~CsvReader()
{}
CsvReader::~CsvReader() {}
std::istream& CsvReader::stream() const
{
+8 -20
View File
@@ -38,11 +38,10 @@ enum
ERR_OPENSLES = 23 // OpenSL ES failed. Subcode has actual error code.
};
class Exception: public std::exception
class Exception : public std::exception
{
public:
Exception(int code, int subcode = 0)
:mCode(code), mSubcode(subcode)
Exception(int code, int subcode = 0) : mCode(code), mSubcode(subcode)
{
std::snprintf(mMessage, sizeof(mMessage), "%d-%d", code, subcode);
}
@@ -50,32 +49,21 @@ public:
Exception(int code, const char* message)
{
if (message)
strncpy(mMessage, message, (sizeof mMessage) - 1 );
strncpy(mMessage, message, (sizeof mMessage) - 1);
}
Exception(const Exception& src)
:mCode(src.mCode), mSubcode(src.mSubcode)
Exception(const Exception& src) : mCode(src.mCode), mSubcode(src.mSubcode)
{
memcpy(mMessage, src.mMessage, sizeof mMessage);
}
~Exception()
{ }
~Exception() {}
int code() const
{
return mCode;
}
int code() const { return mCode; }
int subcode() const
{
return mSubcode;
}
int subcode() const { return mSubcode; }
const char* what() const noexcept
{
return mMessage;
}
const char* what() const noexcept { return mMessage; }
protected:
int mCode = 0, mSubcode = 0;
+8 -6
View File
@@ -2,9 +2,9 @@
#include <fstream>
#if defined(TARGET_LINUX) || defined(TARGET_OSX) || defined(TARGET_ANDROID)
# include <unistd.h>
# include <sys/statvfs.h>
# include <memory.h>
#include <unistd.h>
#include <sys/statvfs.h>
#include <memory.h>
#endif
bool FileHelper::exists(const std::string& s)
@@ -102,7 +102,8 @@ size_t FileHelper::getFreespace(const std::string& path)
size_t r = static_cast<size_t>(-1);
#if defined(TARGET_LINUX)
struct statvfs stats; memset(&stats, 0, sizeof stats);
struct statvfs stats;
memset(&stats, 0, sizeof stats);
int retcode = statvfs(path.c_str(), &stats);
if (retcode == 0)
@@ -111,7 +112,7 @@ size_t FileHelper::getFreespace(const std::string& path)
return r;
}
std::string FileHelper::expandUserHome(const std::string &path)
std::string FileHelper::expandUserHome(const std::string& path)
{
if (path.empty() || path[0] != '~')
return path; // No expansion needed
@@ -124,7 +125,8 @@ std::string FileHelper::expandUserHome(const std::string &path)
{
home_dir = std::getenv("HOMEDRIVE");
const char* homepath = std::getenv("HOMEPATH");
if (home_dir && homepath) {
if (home_dir && homepath)
{
std::string fullpath(home_dir);
fullpath += homepath;
return fullpath + path.substr(1);
+52 -17
View File
@@ -102,8 +102,7 @@ bool Packet::parseV3(const ByteBuffer& packet)
if (!sourceAddr4.isEmpty())
mSourceAddress = sourceAddr4;
else
if (!sourceAddr6.isEmpty())
else if (!sourceAddr6.isEmpty())
mSourceAddress = sourceAddr6;
if (!mSourceAddress.isEmpty())
@@ -111,8 +110,7 @@ bool Packet::parseV3(const ByteBuffer& packet)
if (!destAddr4.isEmpty())
mDestinationAddress = destAddr4;
else
if (!destAddr6.isEmpty())
else if (!destAddr6.isEmpty())
mDestinationAddress = destAddr6;
if (!mDestinationAddress.isEmpty())
@@ -121,7 +119,7 @@ bool Packet::parseV3(const ByteBuffer& packet)
return true;
}
bool Packet::parseV2(const ByteBuffer &packet)
bool Packet::parseV2(const ByteBuffer& packet)
{
if (packet.size() < 31)
return false;
@@ -148,16 +146,53 @@ bool Packet::parseV2(const ByteBuffer &packet)
return true;
}
#define WRITE_CHUNK_UCHAR(T, V) {w.writeUShort((uint16_t)mVendorId); w.writeUShort((uint16_t)T); w.writeUShort(1); w.writeUChar((uint8_t)V);}
#define WRITE_CHUNK_USHORT(T, V) {w.writeUShort((uint16_t)mVendorId); w.writeUShort((uint16_t)T); w.writeUShort(2); w.writeUShort((uint16_t)V);}
#define WRITE_CHUNK_UINT(T, V) {w.writeUShort((uint16_t)mVendorId); w.writeUShort((uint16_t)T); w.writeUShort(4); w.writeUInt((uint32_t)V);}
#define WRITE_CHUNK_IP4(T, V) {w.writeUShort((uint16_t)mVendorId); w.writeUShort((uint16_t)T); w.writeUShort(4); w.writeIp(V);}
#define WRITE_CHUNK_IP6(T, V) {w.writeUShort((uint16_t)mVendorId); w.writeUShort((uint16_t)T); w.writeUShort(8); w.writeIp(V);}
#define WRITE_CHUNK_BUFFER(T, V) {w.writeUShort((uint16_t)mVendorId); w.writeUShort((uint16_t)T); w.writeUShort(8); w.writeBuffer(V.data(), V.size());}
#define WRITE_CHUNK_UCHAR(T, V) \
{ \
w.writeUShort((uint16_t)mVendorId); \
w.writeUShort((uint16_t)T); \
w.writeUShort(1); \
w.writeUChar((uint8_t)V); \
}
#define WRITE_CHUNK_USHORT(T, V) \
{ \
w.writeUShort((uint16_t)mVendorId); \
w.writeUShort((uint16_t)T); \
w.writeUShort(2); \
w.writeUShort((uint16_t)V); \
}
#define WRITE_CHUNK_UINT(T, V) \
{ \
w.writeUShort((uint16_t)mVendorId); \
w.writeUShort((uint16_t)T); \
w.writeUShort(4); \
w.writeUInt((uint32_t)V); \
}
#define WRITE_CHUNK_IP4(T, V) \
{ \
w.writeUShort((uint16_t)mVendorId); \
w.writeUShort((uint16_t)T); \
w.writeUShort(4); \
w.writeIp(V); \
}
#define WRITE_CHUNK_IP6(T, V) \
{ \
w.writeUShort((uint16_t)mVendorId); \
w.writeUShort((uint16_t)T); \
w.writeUShort(8); \
w.writeIp(V); \
}
#define WRITE_CHUNK_BUFFER(T, V) \
{ \
w.writeUShort((uint16_t)mVendorId); \
w.writeUShort((uint16_t)T); \
w.writeUShort(8); \
w.writeBuffer(V.data(), V.size()); \
}
ByteBuffer Packet::buildV3()
{
ByteBuffer r; r.resize(mBody.size() + 512);
ByteBuffer r;
r.resize(mBody.size() + 512);
BufferWriter w(r);
// Signature
@@ -174,8 +209,7 @@ ByteBuffer Packet::buildV3()
{
if (mSourceAddress.isV4())
WRITE_CHUNK_IP4(ChunkType::IP4SourceAddress, mSourceAddress)
else
if (mSourceAddress.isV6())
else if (mSourceAddress.isV6())
WRITE_CHUNK_IP6(ChunkType::IP6SourceAddress, mSourceAddress);
WRITE_CHUNK_USHORT(ChunkType::SourcePort, mSourceAddress.port());
@@ -186,8 +220,7 @@ ByteBuffer Packet::buildV3()
{
if (mDestinationAddress.isV4())
WRITE_CHUNK_IP4(ChunkType::IP4DestinationAddress, mDestinationAddress)
else
if (mDestinationAddress.isV6())
else if (mDestinationAddress.isV6())
WRITE_CHUNK_IP6(ChunkType::IP6DestinationAddress, mDestinationAddress);
WRITE_CHUNK_USHORT(ChunkType::DestinationPort, mDestinationAddress.port());
@@ -216,7 +249,9 @@ ByteBuffer Packet::buildV3()
r.resize(w.offset());
w.rewind(); w.skip(4); w.writeUShort((uint16_t)r.size());
w.rewind();
w.skip(4);
w.writeUShort((uint16_t)r.size());
return r;
}
+15 -19
View File
@@ -6,8 +6,8 @@
namespace HEP
{
enum class ChunkType
{
enum class ChunkType
{
None = 0,
IPProtocolFamily,
IPProtocolID,
@@ -26,10 +26,10 @@ namespace HEP
PacketPayload,
CompressedPayload,
InternalC
};
};
enum class VendorId
{
enum class VendorId
{
None,
FreeSwitch,
Kamailio,
@@ -37,10 +37,10 @@ namespace HEP
Asterisk,
Homer,
SipXecs
};
};
enum class ProtocolId
{
enum class ProtocolId
{
Reserved = 0,
SIP,
XMPP,
@@ -54,21 +54,17 @@ namespace HEP
IAX,
H322,
H321
};
};
struct Packet
{
struct Packet
{
bool parseV3(const ByteBuffer& packet);
bool parseV2(const ByteBuffer& packet);
ByteBuffer buildV3();
uint8_t
mIpProtocolFamily,
mIpProtocolId;
uint8_t mIpProtocolFamily, mIpProtocolId;
InternetAddress
mSourceAddress,
mDestinationAddress;
InternetAddress mSourceAddress, mDestinationAddress;
timeval mTimestamp;
ProtocolId mProtocolType;
@@ -78,8 +74,8 @@ namespace HEP
ByteBuffer mBody;
VendorId mVendorId;
uint32_t mBodyOffset = 0;
};
};
}
} // namespace HEP
#endif
File diff suppressed because it is too large Load Diff
-1
View File
@@ -36,4 +36,3 @@ public:
#endif // HL_IUUP_H
-1
View File
@@ -2,4 +2,3 @@
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+4 -4
View File
@@ -11,13 +11,13 @@
using ice::GLogger;
using ice::LogLock;
using ice::LL_MEDIA;
using ice::LL_DEBUG;
using ice::LL_INFO;
using ice::LL_CRITICAL;
using ice::LL_DEBUG;
using ice::LL_ERROR;
using ice::LL_INFO;
using ice::LL_MEDIA;
using ice::LL_NONE;
using ice::LL_SPECIAL;
using ice::LL_ERROR;
using ice::LogLevelHelper;
#endif
+9 -14
View File
@@ -53,8 +53,7 @@ NetworkFrame::Payload NetworkFrame::GetUdpPayloadForEthernet(const Packet& data)
result.mData += sizeof(VlanHeader);
result.mLength -= sizeof(VlanHeader);
proto = ntohs(vlan->mData);
}
while (proto == 0x8100);
} while (proto == 0x8100);
}
// Skip MPLS headers
@@ -63,11 +62,11 @@ NetworkFrame::Payload NetworkFrame::GetUdpPayloadForEthernet(const Packet& data)
case ETHERTYPE_MPLS_UC:
case ETHERTYPE_MPLS_MC:
// Parse MPLS here until marker "bottom of mpls stack"
for(bool bottomOfStack = false; !bottomOfStack;
for (bool bottomOfStack = false; !bottomOfStack;
bottomOfStack = ((ntohl(*(uint32_t*)(result.mData - 4)) & MPLS_STACK_MASK) >> MPLS_STACK_SHIFT) != 0)
{
result.mData += 4;
result.mLength -=4;
result.mLength -= 4;
}
break;
@@ -187,20 +186,16 @@ NetworkFrame::Payload NetworkFrame::GetUdpPayloadForIp4(const Packet& data)
struct Ip6Header
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
uint8_t traffic_class_hi:4,
version:4;
uint8_t flow_label_hi:4,
traffic_class_lo:4;
uint8_t traffic_class_hi : 4, version : 4;
uint8_t flow_label_hi : 4, traffic_class_lo : 4;
uint16_t flow_label_lo;
#elif __BYTE_ORDER == __BIG_ENDIAN
uint8_t version:4,
traffic_class_hi:4;
uint8_t traffic_class_lo:4,
flow_label_hi:4;
uint8_t version : 4, traffic_class_hi : 4;
uint8_t traffic_class_lo : 4, flow_label_hi : 4;
uint16_t flow_label_lo;
#else
# error "Please fix endianness defines"
#error "Please fix endianness defines"
#endif
uint16_t payload_len;
@@ -220,7 +215,7 @@ NetworkFrame::Payload NetworkFrame::GetUdpPayloadForIp6(const Packet& data)
*/
result.mData += sizeof(Ip6Header);
result.mLength -= sizeof(Ip6Header);
//std::cout << sizeof(Ip6Header) << std::endl;
// std::cout << sizeof(Ip6Header) << std::endl;
const UdpHeader* udp = reinterpret_cast<const UdpHeader*>(result.mData);
result.mData += sizeof(UdpHeader);
+8 -23
View File
@@ -12,18 +12,11 @@ public:
const uint8_t* mData;
size_t mLength;
Packet(const uint8_t* data, size_t length)
:mData(data), mLength(length)
{}
Packet(const uint8_t* data, size_t length) : mData(data), mLength(length) {}
Packet()
:mData(nullptr), mLength(0)
{}
Packet() : mData(nullptr), mLength(0) {}
bool is_empty() const
{
return mData == nullptr || mLength == 0;
}
bool is_empty() const { return mData == nullptr || mLength == 0; }
};
struct Payload
@@ -51,7 +44,7 @@ public:
#if defined(TARGET_WIN)
struct /*__attribute__((packed))*/ LinuxSllHeader
#else
#else
struct __attribute__((packed)) LinuxSllHeader
#endif
{
@@ -82,18 +75,11 @@ public:
uint8_t mTtl; /* time to live */
uint8_t mProtocol; /* protocol */
uint16_t mChecksum; /* checksum */
in_addr mSource,
mDestination; /* source and dest address */
in_addr mSource, mDestination; /* source and dest address */
int headerLength() const
{
return (mVhl & 0x0f) * 4;
}
int headerLength() const { return (mVhl & 0x0f) * 4; }
int version() const
{
return mVhl >> 4;
}
int version() const { return mVhl >> 4; }
const in_addr& source4() const { return mSource; }
const in_addr& dest4() const { return mDestination; }
@@ -127,11 +113,10 @@ public:
#define TH_URG 0x20
#define TH_ECE 0x40
#define TH_CWR 0x80
#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
#define TH_FLAGS (TH_FIN | TH_SYN | TH_RST | TH_ACK | TH_URG | TH_ECE | TH_CWR)
uint16_t mWindow; /* window */
uint16_t mChecksum; /* checksum */
uint16_t mUrgentPointer; /* urgent pointer */
};
};
#endif
+23 -18
View File
@@ -4,7 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#if defined(TARGET_LINUX) || defined(TARGET_ANDROID)
# include <asm/ioctls.h>
#include <asm/ioctls.h>
#endif
#include "../engine_config.h"
@@ -12,19 +12,17 @@
#include "HL_Log.h"
#if defined(TARGET_OSX) || defined(TARGET_LINUX)
# include <fcntl.h>
#include <fcntl.h>
#endif
#if !defined(TARGET_WIN)
# include <unistd.h>
#include <unistd.h>
#endif
#include <assert.h>
#define LOG_SUBSYSTEM "network"
DatagramSocket::DatagramSocket()
:mFamily(AF_INET), mHandle(INVALID_SOCKET), mLocalPort(0)
{}
DatagramSocket::DatagramSocket() : mFamily(AF_INET), mHandle(INVALID_SOCKET), mLocalPort(0) {}
DatagramSocket::~DatagramSocket()
{
@@ -41,8 +39,10 @@ void DatagramSocket::open(int family)
mHandle = ::socket(mFamily, SOCK_DGRAM, IPPROTO_UDP);
if (mHandle != INVALID_SOCKET)
{
sockaddr_in addr4; sockaddr_in6 addr6;
memset(&addr4, 0, sizeof(addr4)); memset(&addr6, 0, sizeof(addr6));
sockaddr_in addr4;
sockaddr_in6 addr6;
memset(&addr4, 0, sizeof(addr4));
memset(&addr6, 0, sizeof(addr6));
socklen_t l = mFamily == AF_INET ? sizeof(addr4) : sizeof(addr6);
int retcode = getsockname(mHandle, (mFamily == AF_INET ? (sockaddr*)&addr4 : (sockaddr*)&addr6), &l);
if (!retcode)
@@ -57,15 +57,16 @@ int DatagramSocket::localport()
return mLocalPort;
}
void DatagramSocket::sendDatagram(InternetAddress &dest, const void *packetData, unsigned int packetSize)
void DatagramSocket::sendDatagram(InternetAddress& dest, const void* packetData, unsigned int packetSize)
{
if (mHandle == INVALID_SOCKET)
return;
/*int sent = */::sendto(mHandle, (const char*)packetData, packetSize, 0, dest.genericsockaddr(), dest.sockaddrLen());
/*int sent = */ ::sendto(mHandle, (const char*)packetData, packetSize, 0, dest.genericsockaddr(),
dest.sockaddrLen());
}
unsigned DatagramSocket::recvDatagram(InternetAddress &src, void *packetBuffer, unsigned packetCapacity)
unsigned DatagramSocket::recvDatagram(InternetAddress& src, void* packetBuffer, unsigned packetCapacity)
{
if (mHandle == INVALID_SOCKET)
return 0;
@@ -76,8 +77,14 @@ unsigned DatagramSocket::recvDatagram(InternetAddress &src, void *packetBuffer,
sockaddr_in6 addr_6 = {AF_INET6, 0, 0, {0}, 0};
switch (mFamily)
{
case AF_INET: addr = (sockaddr*)&addr_4; addrLen = sizeof(addr_4); break;
case AF_INET6: addr = (sockaddr*)&addr_6; addrLen = sizeof(addr_6); break;
case AF_INET:
addr = (sockaddr*)&addr_4;
addrLen = sizeof(addr_4);
break;
case AF_INET6:
addr = (sockaddr*)&addr_6;
addrLen = sizeof(addr_6);
break;
default:
assert(0);
}
@@ -131,7 +138,7 @@ bool DatagramSocket::setBlocking(bool blocking)
int flags = fcntl(mHandle, F_GETFL, 0);
if (flags < 0)
return false;
flags = blocking ? (flags&~O_NONBLOCK) : (flags|O_NONBLOCK);
flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
return (fcntl(mHandle, F_SETFL, flags) == 0) ? true : false;
#endif
#if defined(TARGET_ANDROID)
@@ -152,9 +159,7 @@ DatagramAgreggator::DatagramAgreggator()
mMaxHandle = 0;
}
DatagramAgreggator::~DatagramAgreggator()
{
}
DatagramAgreggator::~DatagramAgreggator() {}
void DatagramAgreggator::addSocket(PDatagramSocket socket)
{
@@ -196,6 +201,6 @@ bool DatagramAgreggator::waitForData(std::chrono::milliseconds timeout)
tv.tv_sec = timeout.count() / 1000;
tv.tv_usec = (timeout.count() % 1000) * 1000;
int rescode = ::select(mMaxHandle+1, &mReadSet, nullptr, nullptr, &tv);
int rescode = ::select(mMaxHandle + 1, &mReadSet, nullptr, nullptr, &tv);
return rescode > 0;
}
+1 -1
View File
@@ -15,13 +15,13 @@ class NetworkSocket
{
public:
virtual int localport() = 0;
};
class DatagramSocket
{
friend class SocketHeap;
friend class DatagramAgreggator;
public:
DatagramSocket();
virtual ~DatagramSocket();
File diff suppressed because it is too large Load Diff
+9 -9
View File
@@ -10,7 +10,7 @@
#include <windows.h>
#if defined(USE_MINIDUMP)
# include <DbgHelp.h>
#include <DbgHelp.h>
#endif
int winVersion()
@@ -39,17 +39,17 @@ int winVersion()
return Win_Seven;
else
return Win_Vista;
}
}
// ----------------- CrashMiniDump -----------------
#if defined(USE_MINIDUMP)
static LONG WINAPI MyExceptionHandler(EXCEPTION_POINTERS* ExceptionInfo)
{
// Open the file
HANDLE hFile = CreateFile( L"MiniDump.dmp", GENERIC_READ | GENERIC_WRITE,
0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
HANDLE hFile =
CreateFile(L"MiniDump.dmp", GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if( ( hFile != NULL ) && ( hFile != INVALID_HANDLE_VALUE ) )
if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))
{
// Create the minidump
MINIDUMP_EXCEPTION_INFORMATION mdei;
@@ -60,11 +60,11 @@ static LONG WINAPI MyExceptionHandler(EXCEPTION_POINTERS* ExceptionInfo)
MINIDUMP_TYPE mdt = MiniDumpWithFullMemory;
BOOL rv = MiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(),
hFile, mdt, (ExceptionInfo != 0) ? &mdei : 0, 0, 0 );
BOOL rv = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, mdt,
(ExceptionInfo != 0) ? &mdei : 0, 0, 0);
// Close the file
CloseHandle( hFile );
CloseHandle(hFile);
}
else
{
@@ -140,7 +140,7 @@ int _kbhit()
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
fcntl(STDIN_FILENO, F_SETFL, oldf);
if(ch != EOF)
if (ch != EOF)
{
ungetc(ch, stdin);
return 1;
+2 -2
View File
@@ -41,7 +41,7 @@ int iosVersion();
#include <sys/select.h>
#include <termios.h>
#if defined(TARGET_LINUX)
//# include <stropts.h>
// # include <stropts.h>
#endif
extern int _kbhit();
@@ -49,6 +49,6 @@ extern int _kbhit();
#endif
#if defined(TARGET_WIN)
# include <conio.h>
#include <conio.h>
#endif
#endif
+2 -4
View File
@@ -5,11 +5,9 @@
#include "HL_Pointer.h"
UsageCounter::UsageCounter()
{}
UsageCounter::UsageCounter() {}
UsageCounter::~UsageCounter()
{}
UsageCounter::~UsageCounter() {}
int UsageCounter::obtain(int usageId)
{
+97 -70
View File
@@ -19,36 +19,36 @@
#include <vector>
#ifndef HL_RTP_POOL
# define HL_RTP_POOL 1
#define HL_RTP_POOL 1
#endif
namespace hl
{
#if HL_RTP_POOL
/// @class FixedBlockPool
/// A process-wide, fixed-block pool with a lock-free thread-local fast path: uniform 256-byte
/// blocks carved from 64 KB chunks, an intrusive thread-local free list, and a per-block header
/// tag so deallocate() is O(1) and lock-free for any block (and can tell pooled blocks from the
/// global-allocator fallback used for oversized requests) regardless of the freeing thread.
///
/// CROSS-THREAD RECLAIM (2026-07-26) — fixes an unbounded capacity ratchet. A uniform block size
/// makes a block allocated on one thread safe to free on another, but "safe" is not "reclaimed".
/// With a purely thread-local free list the block joins the FREEING thread's list, so a
/// producer/consumer split strands it: vq-core allocates RTPPacket / jitter-buffer nodes on the
/// capture threads and frees them on the interval/reap side, so the capture threads' lists were
/// perpetually empty and refill() carved a fresh chunk every BlocksPerChunk allocations, forever.
/// Observed on vqmonitor (the only box with >1 capture thread): capacityBlocks() 256 -> 11.8M
/// = 2.7 GiB over 4 days at ~25 MiB/h, while activeBlocks() drained to 0 every idle interval.
///
/// The fix is a process-wide depot of free-block batches. A thread whose free list grows past
/// ThreadCacheHighWater hands a batch down to the depot; a thread that runs dry takes a batch
/// from the depot before carving a new chunk; a thread flushes its remainder to the depot on
/// exit. The depot is touched once per BlocksPerChunk operations and the hysteresis between
/// "empty" and the high-water keeps it off the per-packet path, so the fast path stays lock-free.
/// capacityBlocks() now plateaus at the true concurrent high-water instead of ratcheting.
class FixedBlockPool
{
public:
/// @class FixedBlockPool
/// A process-wide, fixed-block pool with a lock-free thread-local fast path: uniform 256-byte
/// blocks carved from 64 KB chunks, an intrusive thread-local free list, and a per-block header
/// tag so deallocate() is O(1) and lock-free for any block (and can tell pooled blocks from the
/// global-allocator fallback used for oversized requests) regardless of the freeing thread.
///
/// CROSS-THREAD RECLAIM (2026-07-26) — fixes an unbounded capacity ratchet. A uniform block size
/// makes a block allocated on one thread safe to free on another, but "safe" is not "reclaimed".
/// With a purely thread-local free list the block joins the FREEING thread's list, so a
/// producer/consumer split strands it: vq-core allocates RTPPacket / jitter-buffer nodes on the
/// capture threads and frees them on the interval/reap side, so the capture threads' lists were
/// perpetually empty and refill() carved a fresh chunk every BlocksPerChunk allocations, forever.
/// Observed on vqmonitor (the only box with >1 capture thread): capacityBlocks() 256 -> 11.8M
/// = 2.7 GiB over 4 days at ~25 MiB/h, while activeBlocks() drained to 0 every idle interval.
///
/// The fix is a process-wide depot of free-block batches. A thread whose free list grows past
/// ThreadCacheHighWater hands a batch down to the depot; a thread that runs dry takes a batch
/// from the depot before carving a new chunk; a thread flushes its remainder to the depot on
/// exit. The depot is touched once per BlocksPerChunk operations and the hysteresis between
/// "empty" and the high-water keeps it off the per-packet path, so the fast path stays lock-free.
/// capacityBlocks() now plateaus at the true concurrent high-water instead of ratcheting.
class FixedBlockPool
{
public:
/// Usable bytes handed back to the caller from a pooled block. Comfortably covers the
/// shared_ptr nodes we pool (control block + RTPPacket / RtpBuffer::Packet, ~90-130 bytes).
static constexpr std::size_t PayloadSize = 240;
@@ -124,15 +124,9 @@ namespace hl
/// activeBlocks() is a genuine leak of referenced objects rather than a
/// traffic peak that merely carved extra chunks. Covers every pooled
/// shared_ptr node (allocate_shared<RTPPacket> + jitter-buffer packets).
static std::int64_t activeBlocks() noexcept
{
return s_activeBlocks.load(std::memory_order_relaxed);
}
static std::int64_t activeBlocks() noexcept { return s_activeBlocks.load(std::memory_order_relaxed); }
/// Live oversized allocations that overflowed to ::operator new.
static std::int64_t activeGlobalAllocations() noexcept
{
return s_activeGlobal.load(std::memory_order_relaxed);
}
static std::int64_t activeGlobalAllocations() noexcept { return s_activeGlobal.load(std::memory_order_relaxed); }
/// Total blocks ever carved (chunks x BlocksPerChunk) = high-water capacity.
/// With cross-thread reclaim this PLATEAUS once the pool has covered the
/// concurrent high-water; sustained linear growth means reclaim is not working.
@@ -143,18 +137,12 @@ namespace hl
/// Free blocks parked in the process-wide depot, i.e. reclaimed from a freeing
/// thread and available to any allocating thread. Healthy steady state is a
/// non-zero, bounded value: it is the surplus that used to be stranded.
static std::int64_t depotBlocks() noexcept
{
return s_depotBlocks.load(std::memory_order_relaxed);
}
static std::int64_t depotBlocks() noexcept { return s_depotBlocks.load(std::memory_order_relaxed); }
/// Approximate live pooled payload bytes (excludes per-block header).
static std::int64_t activeBytes() noexcept
{
return activeBlocks() * static_cast<std::int64_t>(PayloadSize);
}
static std::int64_t activeBytes() noexcept { return activeBlocks() * static_cast<std::int64_t>(PayloadSize); }
/// @}
private:
private:
inline static std::atomic<std::int64_t> s_activeBlocks{0};
inline static std::atomic<std::int64_t> s_activeGlobal{0};
inline static std::atomic<std::int64_t> s_chunks{0};
@@ -174,10 +162,7 @@ namespace hl
static_assert(PayloadSize >= 2 * sizeof(void*) + sizeof(std::size_t),
"pooled block payload must hold the free-list, depot and length slots");
static uint64_t& tagOf(void* block) noexcept
{
return *reinterpret_cast<uint64_t*>(block);
}
static uint64_t& tagOf(void* block) noexcept { return *reinterpret_cast<uint64_t*>(block); }
static void*& nextOf(void* block) noexcept
{
@@ -317,36 +302,70 @@ namespace hl
static ChunkRegistry* instance = new ChunkRegistry();
return *instance;
}
};
};
#endif // HL_RTP_POOL
/// Mode-independent accessors for the pool diagnostics, so callers need not know
/// whether HL_RTP_POOL is compiled in. When pooling is disabled they return -1
/// ("not applicable") since allocate_shared then behaves like make_shared.
/// Mode-independent accessors for the pool diagnostics, so callers need not know
/// whether HL_RTP_POOL is compiled in. When pooling is disabled they return -1
/// ("not applicable") since allocate_shared then behaves like make_shared.
#if HL_RTP_POOL
inline std::int64_t poolActiveBlocks() noexcept { return FixedBlockPool::activeBlocks(); }
inline std::int64_t poolCapacityBlocks() noexcept { return FixedBlockPool::capacityBlocks(); }
inline std::int64_t poolDepotBlocks() noexcept { return FixedBlockPool::depotBlocks(); }
inline std::int64_t poolActiveGlobal() noexcept { return FixedBlockPool::activeGlobalAllocations(); }
inline std::int64_t poolActiveBytes() noexcept { return FixedBlockPool::activeBytes(); }
inline std::int64_t poolActiveBlocks() noexcept
{
return FixedBlockPool::activeBlocks();
}
inline std::int64_t poolCapacityBlocks() noexcept
{
return FixedBlockPool::capacityBlocks();
}
inline std::int64_t poolDepotBlocks() noexcept
{
return FixedBlockPool::depotBlocks();
}
inline std::int64_t poolActiveGlobal() noexcept
{
return FixedBlockPool::activeGlobalAllocations();
}
inline std::int64_t poolActiveBytes() noexcept
{
return FixedBlockPool::activeBytes();
}
#else
inline std::int64_t poolActiveBlocks() noexcept { return -1; }
inline std::int64_t poolCapacityBlocks() noexcept { return -1; }
inline std::int64_t poolDepotBlocks() noexcept { return -1; }
inline std::int64_t poolActiveGlobal() noexcept { return -1; }
inline std::int64_t poolActiveBytes() noexcept { return -1; }
inline std::int64_t poolActiveBlocks() noexcept
{
return -1;
}
inline std::int64_t poolCapacityBlocks() noexcept
{
return -1;
}
inline std::int64_t poolDepotBlocks() noexcept
{
return -1;
}
inline std::int64_t poolActiveGlobal() noexcept
{
return -1;
}
inline std::int64_t poolActiveBytes() noexcept
{
return -1;
}
#endif
/// @class PoolAllocator
/// A stateless, std-conforming Allocator suitable for std::allocate_shared. When HL_RTP_POOL is
/// enabled it serves single-node allocations from FixedBlockPool; otherwise (and for any request
/// that does not fit a pooled block) it delegates to the global allocator, matching make_shared.
template <class T> struct PoolAllocator
{
/// @class PoolAllocator
/// A stateless, std-conforming Allocator suitable for std::allocate_shared. When HL_RTP_POOL is
/// enabled it serves single-node allocations from FixedBlockPool; otherwise (and for any request
/// that does not fit a pooled block) it delegates to the global allocator, matching make_shared.
template<class T>
struct PoolAllocator
{
using value_type = T;
PoolAllocator() noexcept = default;
template <class U> PoolAllocator(const PoolAllocator<U>&) noexcept {}
template<class U>
PoolAllocator(const PoolAllocator<U>&) noexcept
{
}
T* allocate(std::size_t n)
{
@@ -366,7 +385,15 @@ namespace hl
#endif
}
template <class U> bool operator==(const PoolAllocator<U>&) const noexcept { return true; }
template <class U> bool operator!=(const PoolAllocator<U>&) const noexcept { return false; }
};
template<class U>
bool operator==(const PoolAllocator<U>&) const noexcept
{
return true;
}
template<class U>
bool operator!=(const PoolAllocator<U>&) const noexcept
{
return false;
}
};
} // namespace hl
+59 -57
View File
@@ -4,8 +4,8 @@
#include <algorithm>
#ifdef TARGET_WIN
# define popen _popen
# define pclose _pclose
#define popen _popen
#define pclose _pclose
#endif
#if defined(TARGET_WIN)
@@ -22,38 +22,38 @@ std::string OsProcess::execCommand(const std::string& cmd)
std::string output;
HANDLE hPipeRead, hPipeWrite;
SECURITY_ATTRIBUTES saAttr = { sizeof(SECURITY_ATTRIBUTES) };
saAttr.bInheritHandle = TRUE; //Pipe handles are inherited by child process.
SECURITY_ATTRIBUTES saAttr = {sizeof(SECURITY_ATTRIBUTES)};
saAttr.bInheritHandle = TRUE; // Pipe handles are inherited by child process.
saAttr.lpSecurityDescriptor = NULL;
// Create a pipe to get results from child's stdout.
if ( !CreatePipe(&hPipeRead, &hPipeWrite, &saAttr, 0) )
if (!CreatePipe(&hPipeRead, &hPipeWrite, &saAttr, 0))
return output;
STARTUPINFOA si = { sizeof(STARTUPINFOA) };
STARTUPINFOA si = {sizeof(STARTUPINFOA)};
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.hStdOutput = hPipeWrite;
si.hStdError = hPipeWrite;
si.wShowWindow = SW_HIDE; // Prevents cmd window from flashing. Requires STARTF_USESHOWWINDOW in dwFlags.
PROCESS_INFORMATION pi = { 0 };
PROCESS_INFORMATION pi = {0};
char* cmdline = (char*)_alloca(cmd.size()+1);
char* cmdline = (char*)_alloca(cmd.size() + 1);
strcpy(cmdline, strx::replace(cmd, "/", "\\").c_str());
BOOL fSuccess = CreateProcessA( nullptr, cmdline, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
if (! fSuccess)
BOOL fSuccess = CreateProcessA(nullptr, cmdline, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
if (!fSuccess)
{
CloseHandle( hPipeWrite );
CloseHandle( hPipeRead );
CloseHandle(hPipeWrite);
CloseHandle(hPipeRead);
return output;
}
bool bProcessEnded = false;
for (; !bProcessEnded ;)
for (; !bProcessEnded;)
{
// Give some timeslice (50ms), so we won't waste 100% cpu.
bProcessEnded = WaitForSingleObject( pi.hProcess, 50) == WAIT_OBJECT_0;
bProcessEnded = WaitForSingleObject(pi.hProcess, 50) == WAIT_OBJECT_0;
// Even if process exited - we continue reading, if there is some data available over pipe.
for (;;)
@@ -75,35 +75,35 @@ std::string OsProcess::execCommand(const std::string& cmd)
buf[dwRead] = 0;
output += buf;
}
} //for
} // for
CloseHandle( hPipeWrite );
CloseHandle( hPipeRead );
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
CloseHandle(hPipeWrite);
CloseHandle(hPipeRead);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return output;
}
std::shared_ptr<std::thread> OsProcess::asyncExecCommand(const std::string& cmdline,
std::function<void(const std::string& line)> callback,
std::function<void(const std::string& reason)> finished_callback,
bool& finish_flag)
std::shared_ptr<std::thread>
OsProcess::asyncExecCommand(const std::string& cmdline, std::function<void(const std::string& line)> callback,
std::function<void(const std::string& reason)> finished_callback, bool& finish_flag)
{
// std::cout << cmdline << std::endl;
std::string output;
HANDLE hPipeRead, hPipeWrite;
SECURITY_ATTRIBUTES saAttr = { sizeof(SECURITY_ATTRIBUTES), nullptr, FALSE };
saAttr.bInheritHandle = TRUE; //Pipe handles are inherited by child process.
SECURITY_ATTRIBUTES saAttr = {sizeof(SECURITY_ATTRIBUTES), nullptr, FALSE};
saAttr.bInheritHandle = TRUE; // Pipe handles are inherited by child process.
saAttr.lpSecurityDescriptor = nullptr;
// Create a pipe to get results from child's stdout.
if ( !CreatePipe(&hPipeRead, &hPipeWrite, &saAttr, 0) )
if (!CreatePipe(&hPipeRead, &hPipeWrite, &saAttr, 0))
return std::shared_ptr<std::thread>();
STARTUPINFOA si; memset(&si, 0, sizeof si);
STARTUPINFOA si;
memset(&si, 0, sizeof si);
si.cb = sizeof(STARTUPINFOA);
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.hStdOutput = hPipeWrite;
@@ -113,27 +113,28 @@ std::shared_ptr<std::thread> OsProcess::asyncExecCommand(const std::string& cmdl
PROCESS_INFORMATION pi;
memset(&pi, 0, sizeof pi);
char* cmdbuffer = (char*)_alloca(cmdline.size()+1);
char* cmdbuffer = (char*)_alloca(cmdline.size() + 1);
strcpy(cmdbuffer, strx::replace(cmdline, "/", "\\").c_str());
BOOL fSuccess = CreateProcessA( nullptr, cmdbuffer, nullptr, nullptr, TRUE,
CREATE_NEW_CONSOLE, nullptr, nullptr, &si, &pi);
if (! fSuccess)
BOOL fSuccess =
CreateProcessA(nullptr, cmdbuffer, nullptr, nullptr, TRUE, CREATE_NEW_CONSOLE, nullptr, nullptr, &si, &pi);
if (!fSuccess)
{
CloseHandle( hPipeWrite );
CloseHandle( hPipeRead );
CloseHandle(hPipeWrite);
CloseHandle(hPipeRead);
return std::shared_ptr<std::thread>();
}
std::shared_ptr<std::thread> r = std::make_shared<std::thread>(
[&finish_flag, pi, callback, finished_callback, hPipeRead, hPipeWrite]()
{
char buf[4096]; memset(buf, 0, sizeof buf);
for (; !finish_flag ;)
char buf[4096];
memset(buf, 0, sizeof buf);
for (; !finish_flag;)
{
// Give some timeslice (50ms), so we won't waste 100% cpu.
bool timeouted = WaitForSingleObject( pi.hProcess, 50) == WAIT_OBJECT_0;
bool timeouted = WaitForSingleObject(pi.hProcess, 50) == WAIT_OBJECT_0;
// Even if process exited - we continue reading, if there is some data available over pipe.
for (;;)
@@ -148,7 +149,9 @@ std::shared_ptr<std::thread> OsProcess::asyncExecCommand(const std::string& cmdl
break;
int filled = strlen(buf);
if (!::ReadFile(hPipeRead, buf + filled, std::min(sizeof(buf) - 1 - filled, (size_t)dwAvail), &dwRead, nullptr) || !dwRead)
if (!::ReadFile(hPipeRead, buf + filled, std::min(sizeof(buf) - 1 - filled, (size_t)dwAvail),
&dwRead, nullptr) ||
!dwRead)
// error, the child process might ended
break;
@@ -158,33 +161,33 @@ std::shared_ptr<std::thread> OsProcess::asyncExecCommand(const std::string& cmdl
const char* cr;
while ((cr = strchr(buf, '\n')) != nullptr)
{
std::string line(buf, cr - buf -1);
std::string line(buf, cr - buf - 1);
if (callback)
callback(strx::trim(line));
memmove(buf, cr + 1, strlen(cr+1) + 1);
memmove(buf, cr + 1, strlen(cr + 1) + 1);
}
}
} //for
} // for
if (buf[0])
callback(strx::trim(std::string(buf)));
char ctrlc = 3;
//if (finish_flag)
// if (finish_flag)
// ::WriteFile(hPipeWrite, &ctrlc, 1, nullptr, nullptr);
// GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, pi.dwProcessId);
CloseHandle( hPipeWrite );
CloseHandle( hPipeRead );
CloseHandle(hPipeWrite);
CloseHandle(hPipeRead);
if (finish_flag)
{
//GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
// GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
// Close underlying process
//TerminateProcess(pi.hProcess, 3);
// TerminateProcess(pi.hProcess, 3);
}
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
if (finished_callback)
finished_callback(std::string());
});
@@ -229,12 +232,12 @@ int OsProcess::execSystem(const std::string& cmd)
#include "helper/HL_String.h"
#include "helper/HL_Sync.h"
std::shared_ptr<std::thread> OsProcess::asyncExecCommand(const std::string& cmdline,
std::function<void(const std::string& line)> line_callback,
std::function<void(const std::string& reason)> finished_callback,
bool& finish_flag)
std::shared_ptr<std::thread>
OsProcess::asyncExecCommand(const std::string& cmdline, std::function<void(const std::string& line)> line_callback,
std::function<void(const std::string& reason)> finished_callback, bool& finish_flag)
{
std::shared_ptr<std::thread> t = std::make_shared<std::thread>([cmdline, line_callback, finished_callback, &finish_flag]()
std::shared_ptr<std::thread> t = std::make_shared<std::thread>(
[cmdline, line_callback, finished_callback, &finish_flag]()
{
ThreadHelper::setName("OsProcess::asyncExecCommand");
std::string cp = cmdline;
@@ -257,7 +260,7 @@ std::shared_ptr<std::thread> OsProcess::asyncExecCommand(const std::string& cmdl
while (!feof(pipe) && !finish_flag)
{
// Wait for more data
struct pollfd pfd{ .fd = fno, .events = POLLIN };
struct pollfd pfd{.fd = fno, .events = POLLIN};
while (poll(&pfd, 1, 0) == 0 && !finish_flag)
;
@@ -275,8 +278,7 @@ std::shared_ptr<std::thread> OsProcess::asyncExecCommand(const std::string& cmdl
buffer[r] = 0;
lines += std::string(buffer);
}
}
while (r == sizeof(buffer) - 1);
} while (r == sizeof(buffer) - 1);
if (lines.find('\n') != std::string::npos && line_callback)
{
@@ -287,7 +289,7 @@ std::shared_ptr<std::thread> OsProcess::asyncExecCommand(const std::string& cmdl
if (d != std::string::npos)
{
if (line_callback)
line_callback(strx::trim(lines.substr(p, d-p)));
line_callback(strx::trim(lines.substr(p, d - p)));
p = d + 1;
}
}
@@ -322,7 +324,7 @@ pid_t OsProcess::findPid(const std::string& cmdline)
std::string output = execCommand(oss.str());
return std::atoi(output.c_str());
}
catch(...)
catch (...)
{
return 0;
}
+3 -5
View File
@@ -11,15 +11,13 @@ class OsProcess
public:
static std::string execCommand(const std::string& cmdline);
static int execSystem(const std::string& cmdline);
static std::shared_ptr<std::thread> asyncExecCommand(const std::string& cmdline,
std::function<void(const std::string& line)> line_callback,
std::function<void(const std::string& reason)> finished_callback,
bool& finish_flag);
static std::shared_ptr<std::thread>
asyncExecCommand(const std::string& cmdline, std::function<void(const std::string& line)> line_callback,
std::function<void(const std::string& reason)> finished_callback, bool& finish_flag);
#if defined(TARGET_OSX) || defined(TARGET_LINUX)
static pid_t findPid(const std::string& cmdline);
static void killByPid(pid_t pid);
#endif
};
#endif
+52 -41
View File
@@ -4,12 +4,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#if defined(TARGET_WIN)
# include <WinSock2.h>
# include <Windows.h>
#include <WinSock2.h>
#include <Windows.h>
#endif
#if defined(TARGET_LINUX) || defined(TARGET_ANDROID) || defined(TARGET_OSX)
# include <arpa/inet.h>
#include <arpa/inet.h>
#endif
#include "HL_Rtp.h"
@@ -33,12 +33,12 @@ static const char RTPDUMP_SHEBANG[] = "#!rtpplay1.0";
// RTP fixed header (little-endian bit-field layout)
struct RtpHeader
{
unsigned char cc:4; /* CSRC count */
unsigned char x:1; /* header extension flag */
unsigned char p:1; /* padding flag */
unsigned char version:2; /* protocol version */
unsigned char pt:7; /* payload type */
unsigned char m:1; /* marker bit */
unsigned char cc : 4; /* CSRC count */
unsigned char x : 1; /* header extension flag */
unsigned char p : 1; /* padding flag */
unsigned char version : 2; /* protocol version */
unsigned char pt : 7; /* payload type */
unsigned char m : 1; /* marker bit */
unsigned short seq; /* sequence number */
unsigned int ts; /* timestamp */
unsigned int ssrc; /* synchronization source */
@@ -46,9 +46,9 @@ struct RtpHeader
struct RtcpHeader
{
unsigned char rc:5; /* reception report count */
unsigned char p:1; /* padding flag */
unsigned char version:2; /* protocol version */
unsigned char rc : 5; /* reception report count */
unsigned char p : 1; /* padding flag */
unsigned char version : 2; /* protocol version */
unsigned char pt; /* payload type */
uint16_t len; /* length */
uint32_t ssrc; /* synchronization source */
@@ -59,10 +59,8 @@ struct RtcpHeader
static std::string ipToString(uint32_t ip)
{
// ip in host byte order → dotted-decimal
return std::to_string((ip >> 24) & 0xFF) + "." +
std::to_string((ip >> 16) & 0xFF) + "." +
std::to_string((ip >> 8) & 0xFF) + "." +
std::to_string( ip & 0xFF);
return std::to_string((ip >> 24) & 0xFF) + "." + std::to_string((ip >> 16) & 0xFF) + "." +
std::to_string((ip >> 8) & 0xFF) + "." + std::to_string(ip & 0xFF);
}
static uint32_t stringToIp(const std::string& s)
@@ -130,7 +128,7 @@ int RtpHelper::findPtype(const void* buffer, size_t length)
return -1;
}
int RtpHelper::findPacketNo(const void *buffer, size_t length)
int RtpHelper::findPacketNo(const void* buffer, size_t length)
{
if (isRtp(buffer, length))
return ntohs(reinterpret_cast<const RtpHeader*>(buffer)->seq);
@@ -152,7 +150,8 @@ int RtpHelper::findPayloadLength(const void* buffer, size_t length)
return -1;
// Header extension
if (h->x) {
if (h->x)
{
if (offset + 4 > length)
return -1;
uint16_t extWords = (static_cast<uint16_t>(p[offset + 2]) << 8) | p[offset + 3];
@@ -164,7 +163,8 @@ int RtpHelper::findPayloadLength(const void* buffer, size_t length)
size_t payloadLen = length - offset;
// Padding
if (h->p && payloadLen > 0) {
if (h->p && payloadLen > 0)
{
uint8_t padBytes = p[length - 1];
if (padBytes > payloadLen)
return -1;
@@ -186,7 +186,8 @@ std::shared_ptr<jrtplib::RTPPacket> RtpDump::parseRtpData(const uint8_t* data, s
if (!data || len < 12 || !RtpHelper::isRtp(data, len))
return nullptr;
try {
try
{
// Both are heap-allocated; RTPRawPacket takes ownership and deletes them
jrtplib::RTPIPAddress senderAddress = {jrtplib::RTPIPv4Address(uint32_t(0), uint16_t(0))};
uint8_t* dataCopy = new uint8_t[len];
@@ -199,16 +200,15 @@ std::shared_ptr<jrtplib::RTPPacket> RtpDump::parseRtpData(const uint8_t* data, s
return nullptr;
return packet;
} catch (const std::exception& e) {
}
catch (const std::exception& e)
{
ICELogInfo(<< "Failed to parse RTP packet: " << e.what());
return nullptr;
}
}
RtpDump::RtpDump(const char* filename)
: mFilename(filename ? filename : "")
{
}
RtpDump::RtpDump(const char* filename) : mFilename(filename ? filename : "") {}
RtpDump::~RtpDump() = default;
@@ -237,14 +237,19 @@ void RtpDump::load()
// Parse source address from the text line
size_t spacePos = textLine.find(' ');
if (spacePos != std::string::npos) {
if (spacePos != std::string::npos)
{
std::string addrPart = textLine.substr(spacePos + 1);
size_t slashPos = addrPart.find('/');
if (slashPos != std::string::npos) {
if (slashPos != std::string::npos)
{
mSourceIp = stringToIp(addrPart.substr(0, slashPos));
try {
try
{
mSourcePort = static_cast<uint16_t>(std::stoi(addrPart.substr(slashPos + 1)));
} catch (...) {
}
catch (...)
{
mSourcePort = 0;
}
}
@@ -275,21 +280,25 @@ void RtpDump::load()
// --- 3. Packet records ---
size_t packetCount = 0;
while (input.good() && input.peek() != EOF) {
while (input.good() && input.peek() != EOF)
{
// Packet header: length(2) + plen(2) + offset(4) = 8 bytes
uint16_t recLength, plen;
uint32_t offsetMs;
input.read(reinterpret_cast<char*>(&recLength), 2);
if (input.gcount() != 2) break;
if (input.gcount() != 2)
break;
recLength = ntohs(recLength);
input.read(reinterpret_cast<char*>(&plen), 2);
if (input.gcount() != 2) break;
if (input.gcount() != 2)
break;
plen = ntohs(plen);
input.read(reinterpret_cast<char*>(&offsetMs), 4);
if (input.gcount() != 4) break;
if (input.gcount() != 4)
break;
offsetMs = ntohl(offsetMs);
// All-zeros record signals end of file in some implementations
@@ -367,7 +376,8 @@ void RtpDump::add(const void* buffer, size_t len)
uint32_t offsetMs = 0;
auto now = std::chrono::steady_clock::now();
if (!mRecording) {
if (!mRecording)
{
mRecording = true;
mRecordStart = now;
@@ -378,7 +388,9 @@ void RtpDump::add(const void* buffer, size_t len)
auto usec = std::chrono::duration_cast<std::chrono::microseconds>(epoch - sec);
mStartSec = static_cast<uint32_t>(sec.count());
mStartUsec = static_cast<uint32_t>(usec.count());
} else {
}
else
{
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - mRecordStart);
offsetMs = static_cast<uint32_t>(elapsed.count());
}
@@ -396,8 +408,7 @@ void RtpDump::add(const void* buffer, size_t len, uint32_t offsetMs)
throw std::runtime_error("Packet too large: " + std::to_string(len));
RtpData entry;
entry.mRawData.assign(static_cast<const uint8_t*>(buffer),
static_cast<const uint8_t*>(buffer) + len);
entry.mRawData.assign(static_cast<const uint8_t*>(buffer), static_cast<const uint8_t*>(buffer) + len);
entry.mOffsetMs = offsetMs;
entry.mPacket = parseRtpData(entry.mRawData.data(), entry.mRawData.size());
@@ -414,9 +425,8 @@ void RtpDump::flush()
throw std::runtime_error("Failed to open file for writing: " + mFilename);
// --- 1. Text header ---
std::string textLine = std::string(RTPDUMP_SHEBANG) + " " +
ipToString(mSourceIp) + "/" +
std::to_string(mSourcePort) + "\n";
std::string textLine =
std::string(RTPDUMP_SHEBANG) + " " + ipToString(mSourceIp) + "/" + std::to_string(mSourcePort) + "\n";
output.write(textLine.data(), static_cast<std::streamsize>(textLine.size()));
// --- 2. Binary file header (16 bytes) ---
@@ -441,7 +451,8 @@ void RtpDump::flush()
// --- 3. Packet records ---
size_t written = 0;
for (const auto& pkt : mPacketList) {
for (const auto& pkt : mPacketList)
{
if (pkt.mRawData.empty())
continue;
+3 -6
View File
@@ -22,12 +22,9 @@ struct RtpPair
T mRtp;
T mRtcp;
RtpPair()
{}
RtpPair() {}
RtpPair(const T& rtp, const T& rtcp)
:mRtp(rtp), mRtcp(rtcp)
{}
RtpPair(const T& rtp, const T& rtcp) : mRtp(rtp), mRtcp(rtcp) {}
bool multiplexed() const { return mRtp == mRtcp; }
};
@@ -37,7 +34,7 @@ class RtpHelper
public:
static bool isRtp(const void* buffer, size_t length);
static int findPtype(const void* buffer, size_t length);
static int findPacketNo(const void *buffer, size_t length);
static int findPacketNo(const void* buffer, size_t length);
static bool isRtpOrRtcp(const void* buffer, size_t length);
static bool isRtcp(const void* buffer, size_t length);
static unsigned findSsrc(const void* buffer, size_t length);
+4 -3
View File
@@ -4,12 +4,13 @@
#include <atomic>
#include <mutex>
template <class T>
template<class T>
class SafeSingleton
{
protected:
static std::atomic<T*> SharedInstance;
static std::mutex mMutex;
public:
static T& instance()
{
@@ -50,9 +51,9 @@ public:
}
};
template <class T>
template<class T>
std::atomic<T*> SafeSingleton<T>::SharedInstance;
template <class T>
template<class T>
std::mutex SafeSingleton<T>::mMutex;
#endif
+17 -18
View File
@@ -12,7 +12,7 @@
#include <assert.h>
#include <chrono>
#if !defined(TARGET_WIN)
# include <unistd.h> // Responsible for close() call on Linux
#include <unistd.h> // Responsible for close() call on Linux
#endif
#include "HL_SocketHeap.h"
@@ -31,8 +31,7 @@
using namespace std::chrono_literals;
// ----------------------------- SocketSink -------------------------
SocketSink::~SocketSink()
{}
SocketSink::~SocketSink() {}
// ----------------------------- SocketHeap -------------------------
@@ -74,7 +73,7 @@ void SocketHeap::setRange(unsigned short start, unsigned short finish)
mFinish = finish;
}
void SocketHeap::range(unsigned short &start, unsigned short &finish)
void SocketHeap::range(unsigned short& start, unsigned short& finish)
{
Lock l(mGuard);
@@ -82,10 +81,10 @@ void SocketHeap::range(unsigned short &start, unsigned short &finish)
finish = mFinish;
}
RtpPair<PDatagramSocket> SocketHeap::allocSocketPair(int family, SocketSink *sink, Multiplex m)
RtpPair<PDatagramSocket> SocketHeap::allocSocketPair(int family, SocketSink* sink, Multiplex m)
{
PDatagramSocket rtp, rtcp;
for (int attempt=0; (!rtp || !rtcp) && attempt < (mFinish - mStart)/2; attempt++)
for (int attempt = 0; (!rtp || !rtcp) && attempt < (mFinish - mStart) / 2; attempt++)
{
// Allocate RTP
try
@@ -96,7 +95,7 @@ RtpPair<PDatagramSocket> SocketHeap::allocSocketPair(int family, SocketSink *sin
else
rtcp = allocSocket(family, sink, rtp->localport() + 1);
}
catch(...)
catch (...)
{
// Release a partially allocated pair before retrying - otherwise
// the RTP socket from this attempt leaks into the socket map.
@@ -121,14 +120,13 @@ RtpPair<PDatagramSocket> SocketHeap::allocSocketPair(int family, SocketSink *sin
freeSocket(rtcp);
throw Exception(ERR_NET_FAILED);
}
ICELogInfo(<< "Allocated socket pair " << (family == AF_INET ? "AF_INET" : "AF_INET6") << " "
<< rtp->socket() << ":" << rtcp->socket()
<< " at ports " << rtp->localport() << ":"<< rtcp->localport());
ICELogInfo(<< "Allocated socket pair " << (family == AF_INET ? "AF_INET" : "AF_INET6") << " " << rtp->socket()
<< ":" << rtcp->socket() << " at ports " << rtp->localport() << ":" << rtcp->localport());
return RtpPair<PDatagramSocket>(rtp, rtcp);
}
void SocketHeap::freeSocketPair(const RtpPair<PDatagramSocket> &p)
void SocketHeap::freeSocketPair(const RtpPair<PDatagramSocket>& p)
{
freeSocket(p.mRtp);
freeSocket(p.mRtcp);
@@ -257,10 +255,11 @@ void SocketHeap::thread()
}
// Update socket set
for (auto& socketIter: mSocketMap)
for (auto& socketIter : mSocketMap)
agreggator.addSocket(socketIter.second.mSocket);
/* for (SocketMap::iterator socketIter = mSocketMap.begin(); socketIter != mSocketMap.end(); ++socketIter)
/* for (SocketMap::iterator socketIter = mSocketMap.begin(); socketIter != mSocketMap.end();
++socketIter)
{
// Add handle to set
agreggator.addSocket(socketIter->second.mSocket);
@@ -278,11 +277,11 @@ void SocketHeap::thread()
// Remove deleted sockets to avoid call non-existant sinks
processDeleted();
for (unsigned i=0; i<agreggator.count(); i++)
for (unsigned i = 0; i < agreggator.count(); i++)
{
if (agreggator.hasDataAtIndex(i))
{
//ICELogInfo(<<"Got incoming UDP packet at index " << (const int)i);
// ICELogInfo(<<"Got incoming UDP packet at index " << (const int)i);
PDatagramSocket sock = agreggator.socketAt(i);
// Find corresponding data sink
@@ -293,14 +292,14 @@ void SocketHeap::thread()
InternetAddress src;
unsigned received = sock->recvDatagram(src, mTempPacket, sizeof mTempPacket);
if ( received > 0 && received <= MAX_VALID_UDPPACKET_SIZE)
if (received > 0 && received <= MAX_VALID_UDPPACKET_SIZE)
socketItemIter->second.mSink->onReceivedData(sock, src, mTempPacket, received);
}
// There is a call to ProcessDeleted() as OnReceivedData() could delete sockets
processDeleted();
}
} //of for
} // of for
}
}
else
@@ -308,7 +307,7 @@ void SocketHeap::thread()
}
mShutdown = false;
//#endif
// #endif
}
+8 -15
View File
@@ -22,7 +22,8 @@ class SocketSink
{
public:
virtual ~SocketSink();
virtual void onReceivedData(PDatagramSocket socket, InternetAddress& src, const void* receivedPtr, unsigned receivedSize) = 0;
virtual void onReceivedData(PDatagramSocket socket, InternetAddress& src, const void* receivedPtr,
unsigned receivedSize) = 0;
};
// Class allocates new UDP sockets and tracks incoming packets on them. It runs in separate thread
@@ -49,7 +50,8 @@ public:
// Returns used port number range
void range(unsigned short& start, unsigned short& finish);
// Attempts to allocate and return socket + allocated port number. REQUIRES pointer to data sink - it will be used to process incoming datagrams
// Attempts to allocate and return socket + allocated port number. REQUIRES pointer to data sink - it will be used
// to process incoming datagrams
PDatagramSocket allocSocket(int family, SocketSink* sink, int port = 0);
RtpPair<PDatagramSocket> allocSocketPair(int family, SocketSink* sink, Multiplex m);
@@ -69,18 +71,11 @@ protected:
// Data sink pointer
SocketSink* mSink;
SocketItem()
:mSink(nullptr)
{ }
SocketItem() : mSink(nullptr) {}
SocketItem(unsigned short portnumber, SocketSink* sink)
:mSink(sink)
{
mSocket->mLocalPort = portnumber;
}
SocketItem(unsigned short portnumber, SocketSink* sink) : mSink(sink) { mSocket->mLocalPort = portnumber; }
~SocketItem()
{ }
~SocketItem() {}
};
typedef std::map<SOCKET, SocketItem> SocketMap;
@@ -90,8 +85,7 @@ protected:
Mutex mGuard;
SocketMap mSocketMap;
PortVector mPortVector;
unsigned short mStart,
mFinish;
unsigned short mStart, mFinish;
SocketVector mDeleteVector;
Mutex mDeleteGuard;
@@ -107,7 +101,6 @@ protected:
// Processes mDeleteVector -> updates mSocketMap, removes socket items and closes sockets specified in mDeleteVector
void processDeleted();
};
#endif
+6 -21
View File
@@ -13,10 +13,7 @@ struct Average
return mSum / mCount;
}
T value() const
{
return average();
}
T value() const { return average(); }
void process(T value)
{
@@ -43,10 +40,7 @@ struct TestResult
mAverage.process(value);
}
bool is_initialized() const
{
return mAverage.mCount > 0;
}
bool is_initialized() const { return mAverage.mCount > 0; }
T current() const
{
@@ -56,26 +50,17 @@ struct TestResult
return 0;
}
T value() const
{
return current();
}
T value() const { return current(); }
T average() const
{
return mAverage.average();
}
T average() const { return mAverage.average(); }
TestResult<T>& operator = (T value)
TestResult<T>& operator=(T value)
{
process(value);
return *this;
}
operator T()
{
return mCurrent;
}
operator T() { return mCurrent; }
};
-1
View File
@@ -20,5 +20,4 @@ enum class StreamState
};
#endif
+47 -47
View File
@@ -11,9 +11,9 @@
#include <inttypes.h>
#ifdef TARGET_WIN
# include <WinSock2.h>
# include <Windows.h>
# include <cctype>
#include <WinSock2.h>
#include <Windows.h>
#include <cctype>
#endif
std::string strx::extractFilename(const std::string& path)
@@ -45,7 +45,7 @@ std::string strx::appendPath(const std::string& s1, const std::string& s2)
return result + s2;
}
std::string strx::makeUtf8(const std::tstring &arg)
std::string strx::makeUtf8(const std::tstring& arg)
{
#if defined(TARGET_WIN)
int required = WideCharToMultiByte(CP_UTF8, 0, arg.c_str(), -1, NULL, 0, NULL, NULL);
@@ -60,7 +60,7 @@ std::string strx::makeUtf8(const std::tstring &arg)
#endif
}
std::string strx::toUtf8(const std::tstring &arg)
std::string strx::toUtf8(const std::tstring& arg)
{
return makeUtf8(arg);
}
@@ -80,7 +80,7 @@ std::tstring strx::makeTstring(const std::string& arg)
#endif
}
int strx::toInt(const char *s, int defaultValue, bool* isOk)
int strx::toInt(const char* s, int defaultValue, bool* isOk)
{
int result;
if (sscanf(s, "%d", &result) != 1)
@@ -89,14 +89,13 @@ int strx::toInt(const char *s, int defaultValue, bool* isOk)
*isOk = false;
result = defaultValue;
}
else
if (isOk)
else if (isOk)
*isOk = true;
return result;
}
uint64_t strx::toUint64(const char* s, uint64_t def, bool *isOk)
uint64_t strx::toUint64(const char* s, uint64_t def, bool* isOk)
{
uint64_t result = def;
if (sscanf(s, "%" SCNu64, &result) != 1)
@@ -105,8 +104,7 @@ uint64_t strx::toUint64(const char* s, uint64_t def, bool *isOk)
*isOk = false;
result = def;
}
else
if (isOk)
else if (isOk)
*isOk = true;
return result;
@@ -119,27 +117,28 @@ std::string strx::toHex(unsigned int value)
return buffer;
}
std::string strx::toHex(const void *ptr)
std::string strx::toHex(const void* ptr)
{
std::ostringstream oss;
oss << std::fixed << std::setw(8) << std::setfill('0') << std::hex << ptr;
return oss.str();
}
//must be lowercase for MD5
// must be lowercase for MD5
static const char hexmap[] = "0123456789abcdef";
std::string strx::toHex(const uint8_t* input, size_t inputLength)
{
std::string result; result.resize(inputLength * 2);
std::string result;
result.resize(inputLength * 2);
const char* p = (const char*)input;
char* r = &result[0];
for (size_t i=0; i < inputLength; ++i)
for (size_t i = 0; i < inputLength; ++i)
{
unsigned char temp = *p++;
int hi = (temp & 0xf0)>>4;
int hi = (temp & 0xf0) >> 4;
int low = (temp & 0xf);
*r++ = hexmap[hi];
@@ -149,13 +148,13 @@ std::string strx::toHex(const uint8_t* input, size_t inputLength)
return result;
}
std::string strx::prefixLines(const std::string &source, const std::string &prefix)
std::string strx::prefixLines(const std::string& source, const std::string& prefix)
{
// Read source line by line
std::istringstream iss(source);
std::ostringstream oss;
std::string line;
while (std::getline(iss,line))
while (std::getline(iss, line))
{
oss << prefix << line << std::endl;
}
@@ -194,7 +193,7 @@ void strx::split(const std::string& src, std::vector<std::string>& dst, const st
}
else
{
std::string t = src.substr(p, f-p);
std::string t = src.substr(p, f - p);
if (!t.empty())
dst.push_back(t);
p = f + 1;
@@ -234,11 +233,11 @@ std::pair<std::string, std::string> strx::parseAssignment(const std::string& s,
if (p != std::string::npos)
{
result.first = strx::trim(s.substr(0, p));
result.second = strx::trim(s.substr(p+1));
result.second = strx::trim(s.substr(p + 1));
if (trimQuotes && result.second.size() >= 2)
{
if ((result.second[0] == '"' && result.second[result.second.size()-1] == '"') ||
(result.second[0] == '\'' && result.second[result.second.size()-1] == '\''))
if ((result.second[0] == '"' && result.second[result.second.size() - 1] == '"') ||
(result.second[0] == '\'' && result.second[result.second.size() - 1] == '\''))
result.second = result.second.substr(1, result.second.size() - 2);
}
}
@@ -255,7 +254,7 @@ std::string strx::intToString(int value)
return buffer;
}
float strx::toFloat(const std::string &s, float v, bool* isOk)
float strx::toFloat(const std::string& s, float v, bool* isOk)
{
float result = 0.0;
int code = sscanf(s.c_str(), "%f", &result);
@@ -274,11 +273,13 @@ float strx::toFloat(const std::string &s, float v, bool* isOk)
return result;
}
std::string strx::trim(const std::string &s)
std::string strx::trim(const std::string& s)
{
auto wsfront = std::find_if_not(s.begin(), s.end(), [](int c) { return std::isspace(c) || c == '\r' || c == '\n'; });
auto wsback = std::find_if_not(s.rbegin(), s.rend(), [](int c) { return std::isspace(c) || c == '\r' || c == '\n'; }).base();
return (wsback <= wsfront ? std::string() : std::string(wsfront,wsback));
auto wsfront =
std::find_if_not(s.begin(), s.end(), [](int c) { return std::isspace(c) || c == '\r' || c == '\n'; });
auto wsback =
std::find_if_not(s.rbegin(), s.rend(), [](int c) { return std::isspace(c) || c == '\r' || c == '\n'; }).base();
return (wsback <= wsfront ? std::string() : std::string(wsfront, wsback));
}
std::string strx::timeToString(time_t t)
@@ -291,16 +292,16 @@ std::string strx::timeToString(time_t t)
#else
lt = *localtime(&t);
#endif
strftime(buffer, sizeof(buffer)-1, "%Y-%m-%d %H:%M:%S", &lt);
strftime(buffer, sizeof(buffer) - 1, "%Y-%m-%d %H:%M:%S", &lt);
return buffer;
}
std::string strx::millisecondsToString(uint64_t t)
{
return timeToString(t/1000);
return timeToString(t / 1000);
}
int strx::fromHex2Int(const std::string &s)
int strx::fromHex2Int(const std::string& s)
{
int result = 0;
int retcode = sscanf(s.c_str(), "%x", &result);
@@ -328,10 +329,11 @@ static int hex2code(char s)
std::string strx::fromHex2String(const std::string& s)
{
std::string result; result.resize(s.size() / 2);
std::string result;
result.resize(s.size() / 2);
const char* t = s.c_str();
for (size_t i = 0; i < result.size(); i++)
result[i] = static_cast<char>((hex2code(t[i*2]) << 4) | hex2code(t[i*2+1]));
result[i] = static_cast<char>((hex2code(t[i * 2]) << 4) | hex2code(t[i * 2 + 1]));
return result;
}
@@ -350,7 +352,7 @@ std::string strx::replace(const std::string& s, const std::string& tmpl, const s
{
std::string result(s);
std::string::size_type p = 0;
while ( (p = result.find(tmpl, p)) != std::string::npos)
while ((p = result.find(tmpl, p)) != std::string::npos)
{
result.replace(p, tmpl.size(), n);
p += n.size();
@@ -367,11 +369,11 @@ std::string strx::decodeUri(const std::string& s)
char ch;
int i, ii = 0;
for (i=0; i<(int)s.length(); i++)
for (i = 0; i < (int)s.length(); i++)
{
if (s[i] == '%' && i + 2 < (int)s.length())
{
if (sscanf(s.substr(i+1,2).c_str(), "%x", &ii) == 1)
if (sscanf(s.substr(i + 1, 2).c_str(), "%x", &ii) == 1)
{
ch = static_cast<char>(ii);
ret += ch;
@@ -403,13 +405,13 @@ bool strx::endsWith(const std::string& s, const std::string& suffix)
int strx::stringToDuration(const std::string& s)
{
if (endsWith(s, "ms"))
return std::stoi(s.substr(0, s.size()-2));
return std::stoi(s.substr(0, s.size() - 2));
if (endsWith(s, "s"))
return std::stoi(s.substr(0, s.size()-1)) * 1000;
return std::stoi(s.substr(0, s.size() - 1)) * 1000;
if (endsWith(s, "m"))
return std::stoi(s.substr(0, s.size()-1)) * 60000;
return std::stoi(s.substr(0, s.size() - 1)) * 60000;
if (endsWith(s, "h"))
return std::stoi(s.substr(0, s.size()-1)) * 3600 * 1000;
return std::stoi(s.substr(0, s.size() - 1)) * 3600 * 1000;
else
return std::stoi(s) * 1000;
}
@@ -438,7 +440,7 @@ std::string strx::removeQuotes(const std::string& s)
r = r.substr(1);
if (r.back() == '"')
r = r.substr(0, r.size()-1);
r = r.substr(0, r.size() - 1);
return r;
}
@@ -446,20 +448,18 @@ std::string strx::removeQuotes(const std::string& s)
#if defined(TARGET_WIN)
// MSVC++ lacks memmem support
const void *memmem(const void *haystack, size_t haystack_len,
const void * const needle, const size_t needle_len)
const void* memmem(const void* haystack, size_t haystack_len, const void* const needle, const size_t needle_len)
{
if (!haystack || !haystack_len || !needle || !needle_len)
return nullptr;
for (const char *h = (const char*)haystack;
haystack_len >= needle_len;
++h, --haystack_len) {
if (!memcmp(h, needle, needle_len)) {
for (const char* h = (const char*)haystack; haystack_len >= needle_len; ++h, --haystack_len)
{
if (!memcmp(h, needle, needle_len))
{
return h;
}
}
return nullptr;
}
#endif
+3 -4
View File
@@ -28,7 +28,7 @@ public:
static std::tstring makeTstring(const std::string& arg);
static int toInt(const char* s, int defaultValue, bool* isOk = nullptr);
static uint64_t toUint64(const char* s, uint64_t def, bool *isOk = nullptr);
static uint64_t toUint64(const char* s, uint64_t def, bool* isOk = nullptr);
static std::string toHex(unsigned int value);
static std::string toHex(const void* ptr);
static std::string toHex(const uint8_t* input, size_t inputLength);
@@ -45,7 +45,7 @@ public:
static void split(const std::string& src, std::vector<std::string>& dst, const std::string& delims);
static std::vector<std::string> split(const std::string& src, const std::string& delims = "\n");
template <typename T>
template<typename T>
static std::string join(const std::vector<T>& v, const std::string& delimiter)
{
std::ostringstream s;
@@ -88,8 +88,7 @@ public:
#if defined(TARGET_WIN)
// MSVC++ lacks memmem support
extern const void *memmem(const void *haystack, size_t haystack_len,
const void * const needle, const size_t needle_len);
extern const void* memmem(const void* haystack, size_t haystack_len, const void* const needle, const size_t needle_len);
#endif
#endif
+42 -34
View File
@@ -10,11 +10,11 @@
#include <iostream>
#ifdef TARGET_OSX
# include <libkern/OSAtomic.h>
#include <libkern/OSAtomic.h>
#endif
#ifdef TARGET_WIN
# include <Windows.h>
#include <Windows.h>
#endif
void SyncHelper::delay(unsigned int microseconds)
@@ -35,7 +35,7 @@ void SyncHelper::delay(unsigned int microseconds)
// ------------------- ThreadHelper -------------------
void ThreadHelper::setName(const std::string &name)
void ThreadHelper::setName(const std::string& name)
{
#if defined(TARGET_LINUX)
// The name will be truncated to 8 or 16 characters
@@ -53,7 +53,7 @@ uint64_t ThreadHelper::getCurrentId()
return static_cast<uint64_t>(GetCurrentThreadId());
#endif
#if defined(TARGET_LINUX)||defined(TARGET_OSX)
#if defined(TARGET_LINUX) || defined(TARGET_OSX)
// RPi builds want this!
return (uint64_t)(pthread_self());
#endif
@@ -76,7 +76,7 @@ static time_t TimestampBase = time(nullptr);
std::chrono::milliseconds chronox::getTimestamp()
{
time_point<steady_clock> t = steady_clock::now();
uint64_t ms = duration_cast< milliseconds >(t.time_since_epoch()).count();
uint64_t ms = duration_cast<milliseconds>(t.time_since_epoch()).count();
return std::chrono::milliseconds(ms - TimestampStartPoint + TimestampBase * 1000);
}
@@ -84,7 +84,7 @@ std::chrono::milliseconds chronox::getUptime()
{
time_point<steady_clock> t = steady_clock::now();
uint64_t ms = duration_cast< milliseconds >(t.time_since_epoch()).count();
uint64_t ms = duration_cast<milliseconds>(t.time_since_epoch()).count();
return std::chrono::milliseconds(ms - TimestampStartPoint);
}
@@ -140,15 +140,9 @@ std::chrono::milliseconds chronox::ExecutionTime::getSpentTime() const
}
// --------------- BufferQueue -----------------
BufferQueue::BufferQueue()
{
BufferQueue::BufferQueue() {}
}
BufferQueue::~BufferQueue()
{
}
BufferQueue::~BufferQueue() {}
void BufferQueue::push(const void* data, int bytes)
{
@@ -164,8 +158,7 @@ void BufferQueue::push(const void* data, int bytes)
BufferQueue::PBlock BufferQueue::pull(int milliseconds)
{
std::unique_lock<std::mutex> l(mMutex);
mSignal.wait_for(l, std::chrono::milliseconds(milliseconds),
[this]() { return !mBlockList.empty(); });
mSignal.wait_for(l, std::chrono::milliseconds(milliseconds), [this]() { return !mBlockList.empty(); });
PBlock r;
if (!mBlockList.empty())
@@ -178,9 +171,7 @@ BufferQueue::PBlock BufferQueue::pull(int milliseconds)
}
// ----------------- Semaphore ---------------------
Semaphore::Semaphore(unsigned int count)
: m_count(count)
{}
Semaphore::Semaphore(unsigned int count) : m_count(count) {}
void Semaphore::notify()
{
@@ -196,7 +187,8 @@ void Semaphore::wait()
m_count--;
}
bool Semaphore::waitFor(std::chrono::milliseconds timeout) {
bool Semaphore::waitFor(std::chrono::milliseconds timeout)
{
std::unique_lock<std::mutex> lock(m_mtx);
if (!m_cv.wait_for(lock, timeout, [this]() { return m_count > 0; }))
@@ -246,15 +238,18 @@ uint64_t TimerQueue::add(std::chrono::milliseconds milliseconds, std::function<v
// 1 if the timer was cancelled.
// 0 if you were too late to cancel (or the timer ID was never valid to
// start with)
size_t TimerQueue::cancel(uint64_t id) {
size_t TimerQueue::cancel(uint64_t id)
{
// Instead of removing the item from the container (thus breaking the
// heap integrity), we set the item as having no handler, and put
// that handler on a new item at the top for immediate execution
// The timer thread will then ignore the original item, since it has no
// handler.
std::unique_lock<std::mutex> lk(m_mtx);
for (auto&& item : m_items.getContainer()) {
if (item.id == id && item.handler) {
for (auto&& item : m_items.getContainer())
{
if (item.id == id && item.handler)
{
WorkItem newItem;
// Zero time, so it stays at the top for immediate execution
newItem.end = Clock::time_point();
@@ -285,8 +280,10 @@ size_t TimerQueue::cancelAll()
// Setting all "end" to 0 (for immediate execution) is ok,
// since it maintains the heap integrity
std::unique_lock<std::mutex> lk(m_mtx);
for (auto&& item : m_items.getContainer()) {
if (item.id) {
for (auto&& item : m_items.getContainer())
{
if (item.id)
{
item.end = Clock::time_point();
item.id = 0;
}
@@ -307,9 +304,12 @@ void TimerQueue::run()
if (end.first)
{
// Timers found, so wait until it expires (or something else changes)
auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(end.second - std::chrono::steady_clock::now());
auto milliseconds =
std::chrono::duration_cast<std::chrono::milliseconds>(end.second - std::chrono::steady_clock::now());
m_checkWork.waitFor(milliseconds);
} else {
}
else
{
// No timers exist, so wait forever until something changes
m_checkWork.wait();
}
@@ -327,11 +327,15 @@ void TimerQueue::run()
std::pair<bool, TimerQueue::Clock::time_point> TimerQueue::calcWaitTime()
{
std::lock_guard<std::mutex> lk(m_mtx);
while (m_items.size()) {
if (m_items.top().handler) {
while (m_items.size())
{
if (m_items.top().handler)
{
// Item present, so return the new wait time
return std::make_pair(true, m_items.top().end);
} else {
}
else
{
// Discard empty handlers (they were cancelled)
m_items.pop();
}
@@ -342,9 +346,11 @@ std::pair<bool, TimerQueue::Clock::time_point> TimerQueue::calcWaitTime()
return std::make_pair(false, Clock::time_point());
}
void TimerQueue::checkWork() {
void TimerQueue::checkWork()
{
std::unique_lock<std::mutex> lk(m_mtx);
while (m_items.size() && m_items.top().end <= Clock::now()) {
while (m_items.size() && m_items.top().end <= Clock::now())
{
WorkItem item(std::move(m_items.top()));
m_items.pop();
@@ -355,10 +361,12 @@ void TimerQueue::checkWork() {
}
}
bool TimerQueue::WorkItem::operator > (const TimerQueue::WorkItem& other) const {
bool TimerQueue::WorkItem::operator>(const TimerQueue::WorkItem& other) const
{
return end > other.end;
}
std::vector<TimerQueue::WorkItem>& TimerQueue::Queue::getContainer() {
std::vector<TimerQueue::WorkItem>& TimerQueue::Queue::getContainer()
{
return this->c;
}
+6 -6
View File
@@ -15,8 +15,8 @@
#include <assert.h>
#if defined(TARGET_WIN)
# include <WinSock2.h>
# include <Windows.h>
#include <WinSock2.h>
#include <Windows.h>
#endif
typedef std::recursive_mutex Mutex;
@@ -76,6 +76,7 @@ public:
public:
ExecutionTime();
std::chrono::milliseconds getSpentTime() const;
protected:
std::chrono::milliseconds mStart;
};
@@ -106,7 +107,7 @@ protected:
// Allows execution of handlers at a specified time in the future
// Guarantees:
// - All handlers are executed ONCE, even if canceled (aborted parameter will
//be set to true)
// be set to true)
// - If TimerQueue is destroyed, it will cancel all handlers.
// - Handlers are ALWAYS executed in the Timer Queue worker thread.
// - Handlers execution order is NOT guaranteed
@@ -153,13 +154,12 @@ private:
Clock::time_point end;
uint64_t id; // id==0 means it was cancelled
std::function<void(bool)> handler;
bool operator > (const WorkItem& other) const;
bool operator>(const WorkItem& other) const;
};
std::mutex m_mtx;
// Inheriting from priority_queue, so we can access the internal container
class Queue : public std::priority_queue<WorkItem, std::vector<WorkItem>,
std::greater<WorkItem>>
class Queue : public std::priority_queue<WorkItem, std::vector<WorkItem>, std::greater<WorkItem>>
{
public:
std::vector<WorkItem>& getContainer();
+3 -3
View File
@@ -6,7 +6,7 @@ thread_pool::thread_pool(size_t num_of_threads, const std::string& name)
if (!num_of_threads)
num_of_threads = std::thread::hardware_concurrency();
for(size_t idx = 0; idx < num_of_threads; idx++)
for (size_t idx = 0; idx < num_of_threads; idx++)
this->workers.emplace_back(std::thread(&thread_pool::run_worker, this));
}
@@ -45,7 +45,7 @@ thread_pool::~thread_pool()
stop = true;
}
this->condition.notify_all();
for(std::thread &worker: workers)
for (std::thread& worker : workers)
worker.join();
}
@@ -58,7 +58,7 @@ void thread_pool::run_worker()
{
std::unique_lock<std::mutex> lock(this->queue_mutex);
this->condition.wait(lock, [this]{return !this->tasks.empty() || this->stop;});
this->condition.wait(lock, [this] { return !this->tasks.empty() || this->stop; });
if (!tasks.empty())
{
t = tasks.front();
+2 -2
View File
@@ -28,10 +28,10 @@ public:
private:
// need to keep track of threads so we can join them
std::vector< std::thread > workers;
std::vector<std::thread> workers;
// the task queue
std::queue< task > tasks;
std::queue<task> tasks;
// synchronization
std::mutex queue_mutex;
+4 -5
View File
@@ -12,7 +12,7 @@ double now_ms(void)
#else
struct timespec res;
clock_gettime(CLOCK_MONOTONIC, &res);
return 1000.0 * res.tv_sec + (double) res.tv_nsec / 1e6;
return 1000.0 * res.tv_sec + (double)res.tv_nsec / 1e6;
#endif
}
@@ -31,17 +31,17 @@ int compare_timespec(const timespec& lhs, const timespec& rhs)
return 0;
}
bool operator < (const timespec& lhs, const timespec& rhs)
bool operator<(const timespec& lhs, const timespec& rhs)
{
return compare_timespec(lhs, rhs) < 0;
}
bool operator == (const timespec& lhs, const timespec& rhs)
bool operator==(const timespec& lhs, const timespec& rhs)
{
return compare_timespec(lhs, rhs) == 0;
}
bool operator > (const timespec& lhs, const timespec& rhs)
bool operator>(const timespec& lhs, const timespec& rhs)
{
return compare_timespec(lhs, rhs) > 0;
}
@@ -50,4 +50,3 @@ bool is_zero(const timespec& ts)
{
return !ts.tv_sec && !ts.tv_nsec;
}
+3 -3
View File
@@ -9,9 +9,9 @@ extern double now_ms();
// Compare the timespec.
// Returns -1 if lhs < rhs, 1 if lhs > rhs, 0 if equal
extern int compare_timespec(const timespec& lhs, const timespec& rhs);
extern bool operator < (const timespec& lhs, const timespec& rhs);
extern bool operator == (const timespec& lhs, const timespec& rhs);
extern bool operator > (const timespec& lhs, const timespec& rhs);
extern bool operator<(const timespec& lhs, const timespec& rhs);
extern bool operator==(const timespec& lhs, const timespec& rhs);
extern bool operator>(const timespec& lhs, const timespec& rhs);
extern bool is_zero(const timespec& ts);
#endif
+62 -36
View File
@@ -7,11 +7,11 @@
#define __HL_TYPES_H
#ifdef WIN32
# define tstring wstring
# define to_tstring to_wstring
#define tstring wstring
#define to_tstring to_wstring
#else
# define tstring string
# define to_tstring to_string
#define tstring string
#define to_tstring to_string
#endif
#ifdef WIN32
@@ -32,49 +32,61 @@ enum SdpDirection
#include <stdexcept>
#include <map>
template<
class K, class V,
class HashK = std::hash<K>, class EqK = std::equal_to<K>,
class HashV = std::hash<V>, class EqV = std::equal_to<V>
>
class BiMap {
template<class K, class V, class HashK = std::hash<K>, class EqK = std::equal_to<K>, class HashV = std::hash<V>,
class EqV = std::equal_to<V>>
class BiMap
{
public:
using key_type = K;
using mapped_type = V;
BiMap(const std::map<K,V>& initializers) {
for (const auto& item: initializers) {
BiMap(const std::map<K, V>& initializers)
{
for (const auto& item : initializers)
{
insert(item.first, item.second);
}
}
// Insert a new (key, value) pair. Returns false if either key or value already exists.
bool insert(const K& k, const V& v) {
if (contains_key(k) || contains_value(v)) return false;
bool insert(const K& k, const V& v)
{
if (contains_key(k) || contains_value(v))
return false;
auto ok = forward_.emplace(k, v);
try {
try
{
auto ov = reverse_.emplace(v, k);
if (!ov.second) { // shouldn't happen given the guard above
if (!ov.second)
{ // shouldn't happen given the guard above
forward_.erase(k);
return false;
}
} catch (...) {
}
catch (...)
{
forward_.erase(k);
throw;
}
return ok.second;
}
bool insert(K&& k, V&& v) {
if (contains_key(k) || contains_value(v)) return false;
bool insert(K&& k, V&& v)
{
if (contains_key(k) || contains_value(v))
return false;
auto ok = forward_.emplace(std::move(k), std::move(v));
try {
try
{
auto ov = reverse_.emplace(ok.first->second, ok.first->first); // use stored refs
if (!ov.second) {
if (!ov.second)
{
forward_.erase(ok.first);
return false;
}
} catch (...) {
}
catch (...)
{
forward_.erase(ok.first);
throw;
}
@@ -82,10 +94,13 @@ public:
}
// Replace value for existing key (and update reverse map). Returns false if value is already bound elsewhere.
bool replace_by_key(const K& k, const V& new_v) {
bool replace_by_key(const K& k, const V& new_v)
{
auto it = forward_.find(k);
if (it == forward_.end()) return false;
if (contains_value(new_v)) return false;
if (it == forward_.end())
return false;
if (contains_value(new_v))
return false;
// remove old reverse, insert new reverse, then update forward
reverse_.erase(it->second);
reverse_.emplace(new_v, k);
@@ -94,10 +109,13 @@ public:
}
// Replace key for existing value (and update forward map). Returns false if key is already bound elsewhere.
bool replace_by_value(const V& v, const K& new_k) {
bool replace_by_value(const V& v, const K& new_k)
{
auto it = reverse_.find(v);
if (it == reverse_.end()) return false;
if (contains_key(new_k)) return false;
if (it == reverse_.end())
return false;
if (contains_key(new_k))
return false;
forward_.erase(it->second);
forward_.emplace(new_k, v);
it->second = new_k;
@@ -105,17 +123,21 @@ public:
}
// Erase by key/value. Return number erased (0 or 1).
size_t erase_key(const K& k) {
size_t erase_key(const K& k)
{
auto it = forward_.find(k);
if (it == forward_.end()) return 0;
if (it == forward_.end())
return 0;
reverse_.erase(it->second);
forward_.erase(it);
return 1;
}
size_t erase_value(const V& v) {
size_t erase_value(const V& v)
{
auto it = reverse_.find(v);
if (it == reverse_.end()) return 0;
if (it == reverse_.end())
return 0;
forward_.erase(it->second);
reverse_.erase(it);
return 1;
@@ -125,11 +147,13 @@ public:
bool contains_key(const K& k) const { return forward_.find(k) != forward_.end(); }
bool contains_value(const V& v) const { return reverse_.find(v) != reverse_.end(); }
const V* find_by_key(const K& k) const {
const V* find_by_key(const K& k) const
{
auto it = forward_.find(k);
return (it == forward_.end()) ? nullptr : &it->second;
}
const K* find_by_value(const V& v) const {
const K* find_by_value(const V& v) const
{
auto it = reverse_.find(v);
return (it == reverse_.end()) ? nullptr : &it->second;
}
@@ -138,7 +162,8 @@ public:
const V& at_key(const K& k) const { return forward_.at(k); }
const K& at_value(const V& v) const { return reverse_.at(v); }
void clear() noexcept {
void clear() noexcept
{
forward_.clear();
reverse_.clear();
}
@@ -147,7 +172,8 @@ public:
size_t size() const noexcept { return forward_.size(); }
// Reserve buckets for performance (optional)
void reserve(size_t n) {
void reserve(size_t n)
{
forward_.reserve(n);
reverse_.reserve(n);
}
+10 -13
View File
@@ -7,8 +7,7 @@
#define ADR_WINDOW_CLASS_NAME L"HIDDEN_USB_CHANGE_DELEGATE_WINDOWCLASS_%u"
#define ADR_WINDOW_NAME L"HIDDEN_USB_CHANGE_DELEGATE_WINDOW_%u"
UsbChangeListener::UsbChangeListener()
:mNotifyHandle(NULL), mHiddenWindow(NULL), mDelegate(NULL)
UsbChangeListener::UsbChangeListener() : mNotifyHandle(NULL), mHiddenWindow(NULL), mDelegate(NULL)
{
wsprintfW(mWindowClassName, ADR_WINDOW_CLASS_NAME, (unsigned int)rand());
}
@@ -32,7 +31,7 @@ void UsbChangeListener::start()
{
// Exposing Window to Mixer
WNDCLASSEXW wcx;
memset( &wcx, 0, sizeof(WNDCLASSEXW) );
memset(&wcx, 0, sizeof(WNDCLASSEXW));
wcx.cbSize = sizeof(WNDCLASSEXW);
wcx.lpszClassName = mWindowClassName;
wcx.lpfnWndProc = (WNDPROC)ADRWindowProc;
@@ -40,11 +39,8 @@ void UsbChangeListener::start()
wchar_t windowname[128];
wsprintfW(windowname, ADR_WINDOW_NAME, rand());
mHiddenWindow = CreateWindowW( mWindowClassName,
windowname,
WS_POPUP | WS_DISABLED,
0, 0, 0, 0,
NULL, NULL, NULL, NULL );
mHiddenWindow =
CreateWindowW(mWindowClassName, windowname, WS_POPUP | WS_DISABLED, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
if (!mHiddenWindow)
throw Exception(ERR_CREATEWINDOW, GetLastError());
if (!SetWindowLongPtr(mHiddenWindow, GWLP_USERDATA, (LONG_PTR)this))
@@ -57,13 +53,14 @@ void UsbChangeListener::start()
mNotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
// Register notification
if (!RegisterDeviceNotification(mHiddenWindow, &mNotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES))
if (!RegisterDeviceNotification(mHiddenWindow, &mNotificationFilter,
DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES))
throw Exception(ERR_REGISTERNOTIFICATION, GetLastError());
}
LRESULT CALLBACK UsbChangeListener::ADRWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
LRESULT CALLBACK UsbChangeListener::ADRWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if ( uMsg == WM_DEVICECHANGE )
if (uMsg == WM_DEVICECHANGE)
{
if (wParam == DBT_DEVICEARRIVAL || wParam == DBT_DEVICEREMOVECOMPLETE)
{
@@ -84,7 +81,7 @@ LRESULT CALLBACK UsbChangeListener::ADRWindowProc( HWND hwnd, UINT uMsg, WPARAM
}
}
}
return ::DefWindowProc( hwnd, uMsg, wParam, lParam);
return ::DefWindowProc(hwnd, uMsg, wParam, lParam);
}
@@ -97,7 +94,7 @@ void UsbChangeListener::stop()
mNotifyHandle = NULL;
}
//Destroy the window
// Destroy the window
if (mHiddenWindow != NULL)
{
::DestroyWindow(mHiddenWindow);
+6 -6
View File
@@ -7,9 +7,9 @@
#include <windows.h>
#include <Dbt.h>
class UsbChangeListener
{
public:
class UsbChangeListener
{
public:
class Delegate
{
public:
@@ -26,7 +26,7 @@
void start();
void stop();
protected:
protected:
HDEVNOTIFY mNotifyHandle; /// Handle to track notifications about USB insert/removal.
HWND mHiddenWindow; /// Hidden window to receive notifications
DEV_BROADCAST_DEVICEINTERFACE mNotificationFilter; /// Notifications filter
@@ -38,8 +38,8 @@
/// @param uMsg Message ID
/// @param wParam First param
/// @param lParam Second param
static LRESULT CALLBACK ADRWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
};
static LRESULT CALLBACK ADRWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
};
#endif
+3 -3
View File
@@ -28,7 +28,7 @@ Uuid Uuid::generateOne()
static thread_local std::mt19937 generator = []
{
std::random_device rd;
auto seed_data = std::array<int, std::mt19937::state_size> {};
auto seed_data = std::array<int, std::mt19937::state_size>{};
std::generate(std::begin(seed_data), std::end(seed_data), std::ref(rd));
std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
return std::mt19937(seq);
@@ -40,7 +40,7 @@ Uuid Uuid::generateOne()
return result;
}
Uuid Uuid::parse(const std::string &s)
Uuid Uuid::parse(const std::string& s)
{
Uuid result;
auto id = uuids::uuid::from_string(s);
@@ -57,7 +57,7 @@ std::string Uuid::toString() const
return uuids::to_string(id);
}
bool Uuid::operator < (const Uuid& right) const
bool Uuid::operator<(const Uuid& right) const
{
return memcmp(mUuid, right.mUuid, sizeof(mUuid)) < 0;
return false;
+1 -1
View File
@@ -11,7 +11,7 @@ public:
static Uuid generateOne();
static Uuid parse(const std::string& s);
std::string toString() const;
bool operator < (const Uuid& right) const;
bool operator<(const Uuid& right) const;
protected:
uint8_t mUuid[16];
+78 -71
View File
@@ -8,7 +8,7 @@
#include <assert.h>
#if defined(TARGET_ANDROID)
# define __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif
#include <inttypes.h>
@@ -25,35 +25,21 @@ Variant::Variant()
mPointer = nullptr;
}
Variant::~Variant()
{
}
Variant::~Variant() {}
Variant::Variant(bool value)
:mType(VTYPE_BOOL), mBool(value)
{}
Variant::Variant(bool value) : mType(VTYPE_BOOL), mBool(value) {}
Variant::Variant(int value)
:mType(VTYPE_INT), mInt(value)
{}
Variant::Variant(int value) : mType(VTYPE_INT), mInt(value) {}
Variant::Variant(int64_t value)
:mType(VTYPE_INT64), mInt64(value)
{}
Variant::Variant(int64_t value) : mType(VTYPE_INT64), mInt64(value) {}
Variant::Variant(float value)
:mType(VTYPE_FLOAT), mFloat(value)
{}
Variant::Variant(float value) : mType(VTYPE_FLOAT), mFloat(value) {}
Variant::Variant(double value)
:mType(VTYPE_FLOAT), mFloat((float)value)
{}
Variant::Variant(double value) : mType(VTYPE_FLOAT), mFloat((float)value) {}
Variant::Variant(const std::string& value)
:mType(VTYPE_STRING), mString(value)
{}
Variant::Variant(const std::string& value) : mType(VTYPE_STRING), mString(value) {}
Variant& Variant::operator = (bool value)
Variant& Variant::operator=(bool value)
{
mType = VTYPE_BOOL;
mBool = value;
@@ -61,7 +47,7 @@ Variant& Variant::operator = (bool value)
return *this;
}
Variant& Variant::operator = (int value)
Variant& Variant::operator=(int value)
{
mType = VTYPE_INT;
mInt = value;
@@ -69,7 +55,7 @@ Variant& Variant::operator = (int value)
return *this;
}
Variant& Variant::operator = (int64_t value)
Variant& Variant::operator=(int64_t value)
{
mType = VTYPE_INT64;
mInt64 = value;
@@ -77,7 +63,7 @@ Variant& Variant::operator = (int64_t value)
return *this;
}
Variant& Variant::operator = (float value)
Variant& Variant::operator=(float value)
{
mType = VTYPE_FLOAT;
mFloat = value;
@@ -85,7 +71,7 @@ Variant& Variant::operator = (float value)
return *this;
}
Variant& Variant::operator = (const std::string& value)
Variant& Variant::operator=(const std::string& value)
{
mType = VTYPE_STRING;
mString = value;
@@ -93,7 +79,7 @@ Variant& Variant::operator = (const std::string& value)
return *this;
}
Variant& Variant::operator = (const char* value)
Variant& Variant::operator=(const char* value)
{
mType = VTYPE_STRING;
mString = value;
@@ -101,7 +87,7 @@ Variant& Variant::operator = (const char* value)
return *this;
}
Variant& Variant::operator = (void* value)
Variant& Variant::operator=(void* value)
{
mType = VTYPE_POINTER;
mPointer = value;
@@ -109,7 +95,7 @@ Variant& Variant::operator = (void* value)
return *this;
}
Variant& Variant::operator = (PVariantMap map)
Variant& Variant::operator=(PVariantMap map)
{
mType = VTYPE_VMAP;
mVMap = map;
@@ -117,94 +103,119 @@ Variant& Variant::operator = (PVariantMap map)
return *this;
}
Variant Variant::operator + (const Variant& rhs)
Variant Variant::operator+(const Variant& rhs)
{
switch (type())
{
case VTYPE_BOOL:
case VTYPE_INT: return asInt() + rhs.asInt();
case VTYPE_INT64: return asInt64() + rhs.asInt64();
case VTYPE_FLOAT: return asFloat() + rhs.asFloat();
case VTYPE_STRING: return asStdString() + rhs.asStdString();
case VTYPE_INT:
return asInt() + rhs.asInt();
case VTYPE_INT64:
return asInt64() + rhs.asInt64();
case VTYPE_FLOAT:
return asFloat() + rhs.asFloat();
case VTYPE_STRING:
return asStdString() + rhs.asStdString();
default:
return false;
}
}
Variant Variant::operator - (const Variant& rhs)
Variant Variant::operator-(const Variant& rhs)
{
switch (type())
{
case VTYPE_BOOL:
case VTYPE_STRING:
case VTYPE_INT: return asInt() - rhs.asInt();
case VTYPE_INT64: return asInt64() - rhs.asInt64();
case VTYPE_FLOAT: return asFloat() - rhs.asFloat();
case VTYPE_INT:
return asInt() - rhs.asInt();
case VTYPE_INT64:
return asInt64() - rhs.asInt64();
case VTYPE_FLOAT:
return asFloat() - rhs.asFloat();
default:
return false;
}
}
Variant Variant::operator * (const Variant& rhs)
Variant Variant::operator*(const Variant& rhs)
{
switch (type())
{
case VTYPE_BOOL:
case VTYPE_STRING:
case VTYPE_INT: return asInt() * rhs.asInt();
case VTYPE_INT64: return asInt64() * rhs.asInt64();
case VTYPE_FLOAT: return asFloat() * rhs.asFloat();
case VTYPE_INT:
return asInt() * rhs.asInt();
case VTYPE_INT64:
return asInt64() * rhs.asInt64();
case VTYPE_FLOAT:
return asFloat() * rhs.asFloat();
default:
return false;
}
}
Variant Variant::operator / (const Variant& rhs)
Variant Variant::operator/(const Variant& rhs)
{
switch (type())
{
case VTYPE_BOOL:
case VTYPE_STRING:
case VTYPE_INT: return asInt() / rhs.asInt();
case VTYPE_INT64: return asInt64() / rhs.asInt64();
case VTYPE_FLOAT: return asFloat() / rhs.asFloat();
case VTYPE_INT:
return asInt() / rhs.asInt();
case VTYPE_INT64:
return asInt64() / rhs.asInt64();
case VTYPE_FLOAT:
return asFloat() / rhs.asFloat();
default:
return false;
}
}
bool Variant::operator < (const Variant& rhs) const
bool Variant::operator<(const Variant& rhs) const
{
switch (type())
{
case VTYPE_STRING: return asStdString() < rhs.asStdString();
case VTYPE_STRING:
return asStdString() < rhs.asStdString();
case VTYPE_BOOL:
case VTYPE_INT: return asInt() < rhs.asInt();
case VTYPE_INT64: return asInt64() < rhs.asInt64();
case VTYPE_FLOAT: return asFloat() < rhs.asFloat();
case VTYPE_INT:
return asInt() < rhs.asInt();
case VTYPE_INT64:
return asInt64() < rhs.asInt64();
case VTYPE_FLOAT:
return asFloat() < rhs.asFloat();
default:
return false;
}
}
bool Variant::operator > (const Variant& rhs) const
bool Variant::operator>(const Variant& rhs) const
{
return !(*this == rhs) && !(*this < rhs);
}
bool Variant::operator == (const Variant& rhs) const
bool Variant::operator==(const Variant& rhs) const
{
switch (type())
{
case VTYPE_STRING: return asStdString() == rhs.asStdString();
case VTYPE_BOOL: return asBool() == rhs.asBool();
case VTYPE_INT: return asInt() == rhs.asInt();
case VTYPE_INT64: return asInt64() == rhs.asInt64();
case VTYPE_FLOAT: return asFloat() == rhs.asFloat();
case VTYPE_POINTER: return asPointer() == rhs.asPointer();
case VTYPE_VMAP: assert(0); break;
case VTYPE_STRING:
return asStdString() == rhs.asStdString();
case VTYPE_BOOL:
return asBool() == rhs.asBool();
case VTYPE_INT:
return asInt() == rhs.asInt();
case VTYPE_INT64:
return asInt64() == rhs.asInt64();
case VTYPE_FLOAT:
return asFloat() == rhs.asFloat();
case VTYPE_POINTER:
return asPointer() == rhs.asPointer();
case VTYPE_VMAP:
assert(0);
break;
default:
return false;
}
@@ -212,17 +223,17 @@ bool Variant::operator == (const Variant& rhs) const
return false;
}
bool Variant::operator != (const Variant& rhs) const
bool Variant::operator!=(const Variant& rhs) const
{
return !(*this == rhs);
}
bool Variant::operator <= (const Variant& rhs) const
bool Variant::operator<=(const Variant& rhs) const
{
return (*this < rhs) || (*this == rhs);
}
bool Variant::operator >= (const Variant& rhs) const
bool Variant::operator>=(const Variant& rhs) const
{
return (*this > rhs) || (*this == rhs);
}
@@ -345,13 +356,9 @@ VariantType Variant::type() const
return mType;
}
VariantMap::VariantMap()
{
}
VariantMap::VariantMap() {}
VariantMap::~VariantMap()
{
}
VariantMap::~VariantMap() {}
bool VariantMap::empty() const
{
@@ -368,7 +375,7 @@ bool VariantMap::exists(int itemId) const
return mData.find(itemId) != mData.end();
}
Variant& VariantMap::operator [](int itemId)
Variant& VariantMap::operator[](int itemId)
{
return mData[itemId];
}

Some files were not shown because too many files have changed in this diff Show More