From 0189d0f8ace2a2ef5f287834509a14fd4672e2f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20S=C5=82omkowski?= Date: Mon, 2 Nov 2015 23:41:49 +0100 Subject: [PATCH] Add working two-way channel. --- ISamplesBuffer.hpp | 2 +- MumbleCommunicator.cpp | 10 +++---- MumbleCommunicator.hpp | 1 + PjsuaCommunicator.cpp | 64 ++++++++++++++++++++++++------------------ PjsuaCommunicator.hpp | 9 ++++-- main.cpp | 19 +++++++++---- 6 files changed, 63 insertions(+), 42 deletions(-) diff --git a/ISamplesBuffer.hpp b/ISamplesBuffer.hpp index 6c0b2e4..b5f4750 100644 --- a/ISamplesBuffer.hpp +++ b/ISamplesBuffer.hpp @@ -7,7 +7,7 @@ class ISamplesBuffer { public: virtual void pushSamples(int16_t *samples, unsigned int length) = 0; - virtual unsigned int pullSamples(int16_t *samples, unsigned int length, bool waitWhenEmpty) = 0; +// virtual unsigned int pullSamples(int16_t *samples, unsigned int length, bool waitWhenEmpty) = 0; }; diff --git a/MumbleCommunicator.cpp b/MumbleCommunicator.cpp index 916fb0b..f4a93f8 100644 --- a/MumbleCommunicator.cpp +++ b/MumbleCommunicator.cpp @@ -38,12 +38,10 @@ mumble::MumbleCommunicator::MumbleCommunicator( mum->connect(host, port, user, password); } +void mumble::MumbleCommunicator::sendAudioFrame(int16_t *samples, int length) { + mum->sendAudioData(samples, length); +} + mumble::MumbleCommunicator::~MumbleCommunicator() { mum->disconnect(); } -// -//void mumble::MumbleCommunicator::senderThreadFunction() { -// while (!quit) { -// -// } -//} diff --git a/MumbleCommunicator.hpp b/MumbleCommunicator.hpp index 90182f9..4f39143 100644 --- a/MumbleCommunicator.hpp +++ b/MumbleCommunicator.hpp @@ -35,6 +35,7 @@ namespace mumble { //void receiveAudioFrameCallback(uint8_t *audio_data, uint32_t audio_data_size); + void sendAudioFrame(int16_t *samples, int length); public: boost::asio::io_service &ioService; diff --git a/PjsuaCommunicator.cpp b/PjsuaCommunicator.cpp index db1614d..7b81c7b 100644 --- a/PjsuaCommunicator.cpp +++ b/PjsuaCommunicator.cpp @@ -61,12 +61,17 @@ static void onCallState(pjsua_call_id call_id, ci.state_text.ptr)); } -sip::PjsuaCommunicator::PjsuaCommunicator( +sip::PjsuaCommunicator::PjsuaCommunicator() + : logger(log4cpp::Category::getInstance("SipCommunicator")), + callbackLogger(log4cpp::Category::getInstance("SipCommunicatorCallback")) { + +} + +void sip::PjsuaCommunicator::connect( std::string host, std::string user, std::string password, - unsigned int port) : logger(log4cpp::Category::getInstance("SipCommunicator")), - callbackLogger(log4cpp::Category::getInstance("SipCommunicatorCallback")) { + unsigned int port) { pj_status_t status; @@ -205,14 +210,17 @@ pj_status_t sip::PjsuaCommunicator::mediaPortGetFrame(pjmedia_frame *frame) { } void sip::PjsuaCommunicator::mediaPortPutFrame(pj_int16_t *samples, pj_size_t count) { - std::unique_lock lock(outBuffAccessMutex); - - callbackLogger.debug("Pushing %d samples to out-buff.", count); - pjmedia_circ_buf_write(outputBuff, samples, count); - - lock.unlock(); - - outBuffCondVar.notify_all(); +// std::unique_lock lock(outBuffAccessMutex); +// +// callbackLogger.debug("Pushing %d samples to out-buff.", count); +// pjmedia_circ_buf_write(outputBuff, samples, count); +// +// lock.unlock(); +// +// outBuffCondVar.notify_all(); + if (count > 0) { + onIncomingSamples(samples, count); + } } void sip::PjsuaCommunicator::registerAccount(string host, string user, string password) { @@ -244,20 +252,20 @@ void sip::PjsuaCommunicator::pushSamples(int16_t *samples, unsigned int length) pjmedia_circ_buf_write(inputBuff, samples, length); } -unsigned int sip::PjsuaCommunicator::pullSamples(int16_t *samples, unsigned int length, bool waitWhenEmpty) { - std::unique_lock lock(outBuffAccessMutex); - - unsigned int availableSamples; - - while ((availableSamples = pjmedia_circ_buf_get_len(inputBuff)) < length) { - callbackLogger.debug("Not enough samples in buffer: %d, requested %d. Waiting.", availableSamples, length); - outBuffCondVar.wait(lock); - } - - const int samplesToRead = std::min(length, availableSamples); - - callbackLogger.debug("Pulling %d samples from out-buff.", samplesToRead); - pjmedia_circ_buf_read(inputBuff, samples, samplesToRead); - - return samplesToRead; -} +//unsigned int sip::PjsuaCommunicator::pullSamples(int16_t *samples, unsigned int length, bool waitWhenEmpty) { +// std::unique_lock lock(outBuffAccessMutex); +// +// unsigned int availableSamples; +// +// while ((availableSamples = pjmedia_circ_buf_get_len(inputBuff)) < length) { +// callbackLogger.debug("Not enough samples in buffer: %d, requested %d. Waiting.", availableSamples, length); +// outBuffCondVar.wait(lock); +// } +// +// const int samplesToRead = std::min(length, availableSamples); +// +// callbackLogger.debug("Pulling %d samples from out-buff.", samplesToRead); +// pjmedia_circ_buf_read(inputBuff, samples, samplesToRead); +// +// return samplesToRead; +//} diff --git a/PjsuaCommunicator.hpp b/PjsuaCommunicator.hpp index db1f381..58b0451 100644 --- a/PjsuaCommunicator.hpp +++ b/PjsuaCommunicator.hpp @@ -46,7 +46,9 @@ namespace sip { class PjsuaCommunicator : public ISamplesBuffer { public: - PjsuaCommunicator( + PjsuaCommunicator(); + + void connect( std::string host, std::string user, std::string password, @@ -56,7 +58,9 @@ namespace sip { virtual void pushSamples(int16_t *samples, unsigned int length); - virtual unsigned int pullSamples(int16_t *samples, unsigned int length, bool waitWhenEmpty); + std::function onIncomingSamples; + +// virtual unsigned int pullSamples(int16_t *samples, unsigned int length, bool waitWhenEmpty); private: log4cpp::Category &logger; @@ -73,6 +77,7 @@ namespace sip { std::mutex outBuffAccessMutex; std::condition_variable outBuffCondVar; + // todo make it completely stateless pjmedia_port *createMediaPort(); diff --git a/main.cpp b/main.cpp index fd8d713..82ee603 100644 --- a/main.cpp +++ b/main.cpp @@ -24,11 +24,7 @@ int main(int argc, char *argv[]) { boost::asio::io_service ioService; - sip::PjsuaCommunicator pjsuaCommunicator( - conf.getString("sip.host"), - conf.getString("sip.user"), - conf.getString("sip.password"), - conf.getInt("sip.port")); + sip::PjsuaCommunicator pjsuaCommunicator; mumble::MumbleCommunicator mumbleCommunicator( ioService, @@ -38,6 +34,19 @@ int main(int argc, char *argv[]) { conf.getString("mumble.host"), conf.getInt("mumble.port")); + using namespace std::placeholders; + pjsuaCommunicator.onIncomingSamples = std::bind( + &mumble::MumbleCommunicator::sendAudioFrame, + &mumbleCommunicator, + _1, _2); + + pjsuaCommunicator.connect( + conf.getString("sip.host"), + conf.getString("sip.user"), + conf.getString("sip.password"), + conf.getInt("sip.port")); + + logger.info("Application started."); ioService.run();