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:
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);
}
void mumble::MumbleCommunicator::sendAudioFrame(int16_t *samples, int length) {
mum->sendAudioData(samples, length);
}
mumble::MumbleCommunicator::~MumbleCommunicator() {
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 sendAudioFrame(int16_t *samples, int length);
public:
boost::asio::io_service &ioService;

View File

@ -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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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;
//}

View File

@ -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<void(int16_t *, int)> 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();

View File

@ -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();