Add working two-way channel.

This commit is contained in:
Michał Słomkowski 2015-11-02 23:41:49 +01:00
parent 87842318be
commit 0189d0f8ac
6 changed files with 63 additions and 42 deletions

View File

@ -7,7 +7,7 @@ class ISamplesBuffer {
public: public:
virtual void pushSamples(int16_t *samples, unsigned int length) = 0; 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;
}; };

View File

@ -38,12 +38,10 @@ mumble::MumbleCommunicator::MumbleCommunicator(
mum->connect(host, port, user, password); mum->connect(host, port, user, password);
} }
void mumble::MumbleCommunicator::sendAudioFrame(int16_t *samples, int length) {
mum->sendAudioData(samples, length);
}
mumble::MumbleCommunicator::~MumbleCommunicator() { mumble::MumbleCommunicator::~MumbleCommunicator() {
mum->disconnect(); mum->disconnect();
} }
//
//void mumble::MumbleCommunicator::senderThreadFunction() {
// while (!quit) {
//
// }
//}

View File

@ -35,6 +35,7 @@ namespace mumble {
//void receiveAudioFrameCallback(uint8_t *audio_data, uint32_t audio_data_size); //void receiveAudioFrameCallback(uint8_t *audio_data, uint32_t audio_data_size);
void sendAudioFrame(int16_t *samples, int length);
public: public:
boost::asio::io_service &ioService; boost::asio::io_service &ioService;

View File

@ -61,12 +61,17 @@ static void onCallState(pjsua_call_id call_id,
ci.state_text.ptr)); 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 host,
std::string user, std::string user,
std::string password, std::string password,
unsigned int port) : logger(log4cpp::Category::getInstance("SipCommunicator")), unsigned int port) {
callbackLogger(log4cpp::Category::getInstance("SipCommunicatorCallback")) {
pj_status_t status; 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) { void sip::PjsuaCommunicator::mediaPortPutFrame(pj_int16_t *samples, pj_size_t count) {
std::unique_lock<std::mutex> lock(outBuffAccessMutex); // std::unique_lock<std::mutex> lock(outBuffAccessMutex);
//
callbackLogger.debug("Pushing %d samples to out-buff.", count); // callbackLogger.debug("Pushing %d samples to out-buff.", count);
pjmedia_circ_buf_write(outputBuff, samples, count); // pjmedia_circ_buf_write(outputBuff, samples, count);
//
lock.unlock(); // lock.unlock();
//
outBuffCondVar.notify_all(); // outBuffCondVar.notify_all();
if (count > 0) {
onIncomingSamples(samples, count);
}
} }
void sip::PjsuaCommunicator::registerAccount(string host, string user, string password) { 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); pjmedia_circ_buf_write(inputBuff, samples, length);
} }
unsigned int sip::PjsuaCommunicator::pullSamples(int16_t *samples, unsigned int length, bool waitWhenEmpty) { //unsigned int sip::PjsuaCommunicator::pullSamples(int16_t *samples, unsigned int length, bool waitWhenEmpty) {
std::unique_lock<std::mutex> lock(outBuffAccessMutex); // std::unique_lock<std::mutex> lock(outBuffAccessMutex);
//
unsigned int availableSamples; // unsigned int availableSamples;
//
while ((availableSamples = pjmedia_circ_buf_get_len(inputBuff)) < length) { // while ((availableSamples = pjmedia_circ_buf_get_len(inputBuff)) < length) {
callbackLogger.debug("Not enough samples in buffer: %d, requested %d. Waiting.", availableSamples, length); // callbackLogger.debug("Not enough samples in buffer: %d, requested %d. Waiting.", availableSamples, length);
outBuffCondVar.wait(lock); // outBuffCondVar.wait(lock);
} // }
//
const int samplesToRead = std::min(length, availableSamples); // const int samplesToRead = std::min(length, availableSamples);
//
callbackLogger.debug("Pulling %d samples from out-buff.", samplesToRead); // callbackLogger.debug("Pulling %d samples from out-buff.", samplesToRead);
pjmedia_circ_buf_read(inputBuff, samples, samplesToRead); // pjmedia_circ_buf_read(inputBuff, samples, samplesToRead);
//
return samplesToRead; // return samplesToRead;
} //}

View File

@ -46,7 +46,9 @@ namespace sip {
class PjsuaCommunicator : public ISamplesBuffer { class PjsuaCommunicator : public ISamplesBuffer {
public: public:
PjsuaCommunicator( PjsuaCommunicator();
void connect(
std::string host, std::string host,
std::string user, std::string user,
std::string password, std::string password,
@ -56,7 +58,9 @@ namespace sip {
virtual void pushSamples(int16_t *samples, unsigned int length); virtual void pushSamples(int16_t *samples, unsigned int length);
virtual unsigned int pullSamples(int16_t *samples, unsigned int length, bool waitWhenEmpty); std::function<void(int16_t *, int)> onIncomingSamples;
// virtual unsigned int pullSamples(int16_t *samples, unsigned int length, bool waitWhenEmpty);
private: private:
log4cpp::Category &logger; log4cpp::Category &logger;
@ -73,6 +77,7 @@ namespace sip {
std::mutex outBuffAccessMutex; std::mutex outBuffAccessMutex;
std::condition_variable outBuffCondVar; std::condition_variable outBuffCondVar;
// todo make it completely stateless // todo make it completely stateless
pjmedia_port *createMediaPort(); pjmedia_port *createMediaPort();

View File

@ -24,11 +24,7 @@ int main(int argc, char *argv[]) {
boost::asio::io_service ioService; boost::asio::io_service ioService;
sip::PjsuaCommunicator pjsuaCommunicator( sip::PjsuaCommunicator pjsuaCommunicator;
conf.getString("sip.host"),
conf.getString("sip.user"),
conf.getString("sip.password"),
conf.getInt("sip.port"));
mumble::MumbleCommunicator mumbleCommunicator( mumble::MumbleCommunicator mumbleCommunicator(
ioService, ioService,
@ -38,6 +34,19 @@ int main(int argc, char *argv[]) {
conf.getString("mumble.host"), conf.getString("mumble.host"),
conf.getInt("mumble.port")); 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."); logger.info("Application started.");
ioService.run(); ioService.run();