From a17113448aef2537f0eb811141981228ea90faeb Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Thu, 20 Jul 2017 16:24:17 +0200 Subject: [PATCH] done --- audio/AudioInputModule.cpp | 122 ++++++++++++------------------------ audio/AudioInputModule.h | 8 --- audio/AudioOutputModule.cpp | 88 ++++++++------------------ audio/AudioOutputModule.h | 52 ++++++++------- main.cpp | 106 ++++++++++++++++++++++++++++--- main.h | 10 +++ 6 files changed, 196 insertions(+), 190 deletions(-) diff --git a/audio/AudioInputModule.cpp b/audio/AudioInputModule.cpp index af07ca2..f06e1d9 100644 --- a/audio/AudioInputModule.cpp +++ b/audio/AudioInputModule.cpp @@ -9,7 +9,6 @@ #include "../libtgvoip/logging.h" #include #include -#include using namespace tgvoip; using namespace tgvoip::audio; @@ -19,8 +18,6 @@ AudioInputModule::AudioInputModule(std::string deviceID, VoIPController *control wrapper = (VoIP *)(controller->implData); wrapper->in = this; wrapper->inputState = AUDIO_STATE_CREATED; - init_mutex(inputMutex); - configuringInput = false; } AudioInputModule::~AudioInputModule() @@ -28,21 +25,11 @@ AudioInputModule::~AudioInputModule() wrapper->inputState = AUDIO_STATE_NONE; wrapper->in = NULL; - if (senderThread) { + if (senderThread) + { LOGD("before join senderThread"); join_thread(senderThread); } - - while (holdFiles.size()) { - fclose(holdFiles.front()); - holdFiles.pop(); - } - while (inputFiles.size()) { - fclose(inputFiles.front()); - inputFiles.pop(); - } - - free_mutex(inputMutex); } void AudioInputModule::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels) @@ -61,59 +48,16 @@ void AudioInputModule::Configure(uint32_t sampleRate, uint32_t bitsPerSample, ui wrapper->inputState = AUDIO_STATE_CONFIGURED; } -bool AudioInputModule::play(const char *file) { - FILE *tmp = fopen(file, "rb"); - - if (tmp == NULL) { - throw Php::Exception("Could not open file!"); - return false; - } - - configuringInput = true; - lock_mutex(inputMutex); - inputFiles.push(tmp); - configuringInput = false; - unlock_mutex(inputMutex); - - return true; -} - -bool AudioInputModule::playOnHold(Php::Parameters ¶ms) { - configuringInput = true; - FILE *tmp = NULL; - - lock_mutex(inputMutex); - while (holdFiles.size()) { - fclose(holdFiles.front()); - holdFiles.pop(); - } - for (int i = 0; i < params[0].size(); i++) { - tmp = fopen(params[0][i], "rb"); - if (tmp == NULL) { - throw Php::Exception("Could not open file!"); - configuringInput = false; - unlock_mutex(inputMutex); - return false; - } - holdFiles.push(tmp); - } - configuringInput = false; - unlock_mutex(inputMutex); - return true; -} - - void AudioInputModule::Start() { if (wrapper->inputState == AUDIO_STATE_RUNNING) return; wrapper->inputState = AUDIO_STATE_RUNNING; - + LOGE("STARTING SENDER THREAD"); start_thread(senderThread, StartSenderThread, this); set_thread_priority(senderThread, get_thread_max_priority()); set_thread_name(senderThread, "voip-sender"); - } void AudioInputModule::Stop() @@ -123,50 +67,64 @@ void AudioInputModule::Stop() wrapper->inputState = AUDIO_STATE_CONFIGURED; } - -void* AudioInputModule::StartSenderThread(void* input){ - ((AudioInputModule*)input)->RunSenderThread(); +void *AudioInputModule::StartSenderThread(void *input) +{ + ((AudioInputModule *)input)->RunSenderThread(); return NULL; } -void AudioInputModule::RunSenderThread() { - unsigned char *data = (unsigned char *) malloc(inputCSamplesSize); +void AudioInputModule::RunSenderThread() +{ + unsigned char *data = (unsigned char *)malloc(inputCSamplesSize); size_t read; double time = VoIPController::GetCurrentTime(); double sleeptime; - while (wrapper->inputState == AUDIO_STATE_RUNNING) { - lock_mutex(inputMutex); - while (!configuringInput && wrapper->inputState == AUDIO_STATE_RUNNING) { - if ((sleeptime = (inputWritePeriodSec - (VoIPController::GetCurrentTime() - time))*1000000.0) < 0) { + while (wrapper->inputState == AUDIO_STATE_RUNNING) + { + lock_mutex(wrapper->inputMutex); + while (!wrapper->configuringInput && wrapper->inputState == AUDIO_STATE_RUNNING) + { + if ((sleeptime = (inputWritePeriodSec - (VoIPController::GetCurrentTime() - time)) * 1000000.0) < 0) + { LOGE("Sender: I'm late!"); - } else { + } + else + { usleep(sleeptime); } time = VoIPController::GetCurrentTime(); - if (!inputFiles.empty()) { - if ((read = fread(data, sizeof(unsigned char), inputSamplesSize, inputFiles.front())) != inputCSamplesSize) { - fclose(inputFiles.front()); - inputFiles.pop(); + if (!wrapper->inputFiles.empty()) + { + if ((read = fread(data, sizeof(unsigned char), inputSamplesSize, wrapper->inputFiles.front())) != inputCSamplesSize) + { + fclose(wrapper->inputFiles.front()); + wrapper->inputFiles.pop(); memset(data + (read % inputCSamplesSize), 0, inputCSamplesSize - (read % inputCSamplesSize)); } wrapper->playing = true; - } else { + } + else + { wrapper->playing = false; - if (holdFiles.empty()) { + if (wrapper->holdFiles.empty()) + { memset(data, 0, inputCSamplesSize); - } else { - if ((read = fread(data, sizeof(unsigned char), inputSamplesSize, holdFiles.front())) != inputCSamplesSize) { - fseek(holdFiles.front(), 0, SEEK_SET); - holdFiles.push(holdFiles.front()); - holdFiles.pop(); + } + else + { + if ((read = fread(data, sizeof(unsigned char), inputSamplesSize, wrapper->holdFiles.front())) != inputCSamplesSize) + { + fseek(wrapper->holdFiles.front(), 0, SEEK_SET); + wrapper->holdFiles.push(wrapper->holdFiles.front()); + wrapper->holdFiles.pop(); memset(data + (read % inputCSamplesSize), 0, inputCSamplesSize - (read % inputCSamplesSize)); } } } - InvokeCallback(data, inputCSamplesSize); + InvokeCallback(data, inputCSamplesSize); } - unlock_mutex(inputMutex); + unlock_mutex(wrapper->inputMutex); } free(data); } diff --git a/audio/AudioInputModule.h b/audio/AudioInputModule.h index c123a00..1a7a274 100644 --- a/audio/AudioInputModule.h +++ b/audio/AudioInputModule.h @@ -29,9 +29,6 @@ public: bool writeSamples(unsigned char *data); static void EnumerateDevices(std::vector& devs); - bool play(const char *file); - bool playOnHold(Php::Parameters ¶ms); - static void* StartSenderThread(void* input); void RunSenderThread(); @@ -47,11 +44,6 @@ public: size_t inputCSamplesSize; - std::queue inputFiles; - std::queue holdFiles; - - tgvoip_mutex_t inputMutex; - bool configuringInput; private: diff --git a/audio/AudioOutputModule.cpp b/audio/AudioOutputModule.cpp index 9f4a1aa..9d28f24 100644 --- a/audio/AudioOutputModule.cpp +++ b/audio/AudioOutputModule.cpp @@ -18,59 +18,16 @@ AudioOutputModule::AudioOutputModule(std::string deviceID, VoIPController *contr wrapper = (VoIP *)(controller->implData); wrapper->out = this; wrapper->outputState = AUDIO_STATE_CREATED; - outputFile=NULL; - configuringOutput = false; - //init_mutex(outputMutex); - } AudioOutputModule::~AudioOutputModule() { wrapper->outputState = AUDIO_STATE_NONE; wrapper->out = NULL; - if (receiverThread) { + if (receiverThread) + { LOGD("before join receiverThread"); join_thread(receiverThread); } - - this->unsetOutputFile(); - free_mutex(outputMutex); - -} - -bool AudioOutputModule::unsetOutputFile() { - if (outputFile == NULL) { - return false; - } - - configuringOutput = true; - lock_mutex(outputMutex); - fflush(outputFile); - fclose(outputFile); - outputFile = NULL; - configuringOutput = false; - unlock_mutex(outputMutex); - - return true; - -} -bool AudioOutputModule::setOutputFile(const char *file) { - configuringOutput = true; - - lock_mutex(outputMutex); - if (outputFile != NULL) { - fclose(outputFile); - outputFile=NULL; - } - outputFile = fopen(file, "wb"); - if (outputFile == NULL) { - throw Php::Exception("Could not open file!"); - configuringOutput = false; - unlock_mutex(outputMutex); - return false; - } - configuringOutput = false; - unlock_mutex(outputMutex); - return true; } void AudioOutputModule::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels) @@ -87,8 +44,6 @@ void AudioOutputModule::Configure(uint32_t sampleRate, uint32_t bitsPerSample, u outputCSamplesSize = outputSampleNumber * outputChannels * outputBitsPerSample / 8 * sizeof(unsigned char); wrapper->outputState = AUDIO_STATE_CONFIGURED; - - } void AudioOutputModule::Start() @@ -96,12 +51,11 @@ void AudioOutputModule::Start() if (wrapper->outputState == AUDIO_STATE_RUNNING) return; wrapper->outputState = AUDIO_STATE_RUNNING; - + LOGE("STARTING RECEIVER THREAD"); start_thread(receiverThread, StartReceiverThread, this); set_thread_priority(receiverThread, get_thread_max_priority()); set_thread_name(receiverThread, "voip-receiver"); - } void AudioOutputModule::Stop() @@ -121,36 +75,44 @@ float AudioOutputModule::GetLevel() return outputLevel; } - -void* AudioOutputModule::StartReceiverThread(void* output){ - ((AudioOutputModule*)output)->RunReceiverThread(); +void *AudioOutputModule::StartReceiverThread(void *output) +{ + ((AudioOutputModule *)output)->RunReceiverThread(); return NULL; } -void AudioOutputModule::RunReceiverThread() { - unsigned char *data = (unsigned char *) malloc(outputCSamplesSize); +void AudioOutputModule::RunReceiverThread() +{ + unsigned char *data = (unsigned char *)malloc(outputCSamplesSize); double time = VoIPController::GetCurrentTime(); double sleeptime; - while (wrapper->outputState == AUDIO_STATE_RUNNING) { - lock_mutex(outputMutex); - - while (!configuringOutput && wrapper->outputState == AUDIO_STATE_RUNNING) { - if ((sleeptime = (outputWritePeriodSec - (VoIPController::GetCurrentTime() - time))*1000000.0) < 0) { + while (wrapper->outputState == AUDIO_STATE_RUNNING) + { + lock_mutex(wrapper->outputMutex); + + while (!wrapper->configuringOutput && wrapper->outputState == AUDIO_STATE_RUNNING) + { + if ((sleeptime = (outputWritePeriodSec - (VoIPController::GetCurrentTime() - time)) * 1000000.0) < 0) + { LOGE("Receiver: I'm late!"); - } else { + } + else + { usleep(sleeptime); } time = VoIPController::GetCurrentTime(); InvokeCallback(data, outputCSamplesSize); - if (outputFile != NULL) { - if (fwrite(data, sizeof(unsigned char), outputSamplesSize, outputFile) != outputCSamplesSize) { + if (wrapper->outputFile != NULL) + { + if (fwrite(data, sizeof(unsigned char), outputSamplesSize, wrapper->outputFile) != outputCSamplesSize) + { LOGE("COULD NOT WRITE DATA TO FILE"); } } } - unlock_mutex(outputMutex); + unlock_mutex(wrapper->outputMutex); } free(data); } diff --git a/audio/AudioOutputModule.h b/audio/AudioOutputModule.h index 619f49c..233b999 100644 --- a/audio/AudioOutputModule.h +++ b/audio/AudioOutputModule.h @@ -12,49 +12,47 @@ #include "../main.h" #include "../libtgvoip/threading.h" -namespace tgvoip{ namespace audio{ -class AudioOutputModule : public AudioOutput{ +namespace tgvoip +{ +namespace audio +{ +class AudioOutputModule : public AudioOutput +{ -public: - - AudioOutputModule(std::string deviceID, VoIPController* controller); + public: + AudioOutputModule(std::string deviceID, VoIPController *controller); virtual ~AudioOutputModule(); virtual void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels); virtual void Start(); virtual void Stop(); virtual bool IsPlaying() override; virtual float GetLevel() override; - unsigned char * readSamples(); - static void EnumerateDevices(std::vector& devs); + unsigned char *readSamples(); + static void EnumerateDevices(std::vector &devs); - static void* StartReceiverThread(void* output); + static void *StartReceiverThread(void *output); void RunReceiverThread(); bool unsetOutputFile(); bool setOutputFile(const char *file); - int outputBitsPerSample; - int outputSampleRate; - int outputChannels; - int outputSamplePeriod; - int outputWritePeriod; - double outputSamplePeriodSec; - double outputWritePeriodSec; - int outputSampleNumber; - int outputSamplesSize; - size_t outputCSamplesSize; - float outputLevel = 0.0; + int outputBitsPerSample; + int outputSampleRate; + int outputChannels; + int outputSamplePeriod; + int outputWritePeriod; + double outputSamplePeriodSec; + double outputWritePeriodSec; + int outputSampleNumber; + int outputSamplesSize; + size_t outputCSamplesSize; + float outputLevel = 0.0; -private: + private: tgvoip_thread_t receiverThread; VoIP *wrapper; - - FILE *outputFile; - tgvoip_mutex_t outputMutex; - - bool configuringOutput; - }; -}} +} +} #endif //LIBTGVOIP_AUDIOOUTPUTPHP_H diff --git a/main.cpp b/main.cpp index 2d9e6a7..f7d77cf 100644 --- a/main.cpp +++ b/main.cpp @@ -50,6 +50,12 @@ void VoIP::initVoIPController() { out=NULL; inst = new VoIPController(); + outputFile=NULL; + configuringOutput = false; + init_mutex(outputMutex); + init_mutex(inputMutex); + configuringInput = false; + inst->implData = (void *) this; inst->SetStateCallback([](VoIPController *controller, int state) { ((VoIP *)controller->implData)->state = state; @@ -64,6 +70,24 @@ void VoIP::deinitVoIPController() { if (callState != CALL_STATE_ENDED) { callState = CALL_STATE_ENDED; delete inst; + + lock_mutex(inputMutex); + unlock_mutex(inputMutex); + free_mutex(inputMutex); + lock_mutex(outputMutex); + unlock_mutex(outputMutex); + free_mutex(outputMutex); + + while (holdFiles.size()) { + fclose(holdFiles.front()); + holdFiles.pop(); + } + while (inputFiles.size()) { + fclose(inputFiles.front()); + inputFiles.pop(); + } + unsetOutputFile(); + } } @@ -244,20 +268,82 @@ void VoIP::parseConfig() { } } -Php::Value VoIP::setOutputFile(Php::Parameters ¶ms) { - return out->setOutputFile(params[0]); -} + Php::Value VoIP::unsetOutputFile() { - return out->unsetOutputFile(); -} -Php::Value VoIP::play(Php::Parameters ¶ms) { - if (in->play(params[0])) { - return this; + if (outputFile == NULL) { + return false; } - return false; + + configuringOutput = true; + lock_mutex(outputMutex); + fflush(outputFile); + fclose(outputFile); + outputFile = NULL; + configuringOutput = false; + unlock_mutex(outputMutex); + + return true; + +} +Php::Value VoIP::setOutputFile(Php::Parameters ¶ms) { + configuringOutput = true; + + lock_mutex(outputMutex); + if (outputFile != NULL) { + fclose(outputFile); + outputFile=NULL; + } + outputFile = fopen(params[0], "wb"); + if (outputFile == NULL) { + throw Php::Exception("Could not open file!"); + configuringOutput = false; + unlock_mutex(outputMutex); + return false; + } + configuringOutput = false; + unlock_mutex(outputMutex); + return true; +} + + +Php::Value VoIP::play(Php::Parameters ¶ms) { + FILE *tmp = fopen(params[0], "rb"); + + if (tmp == NULL) { + throw Php::Exception("Could not open file!"); + return false; + } + + configuringInput = true; + lock_mutex(inputMutex); + inputFiles.push(tmp); + configuringInput = false; + unlock_mutex(inputMutex); + + return this; } Php::Value VoIP::playOnHold(Php::Parameters ¶ms) { - return in->playOnHold(params); + configuringInput = true; + FILE *tmp = NULL; + + lock_mutex(inputMutex); + while (holdFiles.size()) { + fclose(holdFiles.front()); + holdFiles.pop(); + } + for (int i = 0; i < params[0].size(); i++) { + tmp = fopen(params[0][i], "rb"); + if (tmp == NULL) { + throw Php::Exception("Could not open file!"); + configuringInput = false; + unlock_mutex(inputMutex); + return false; + } + holdFiles.push(tmp); + } + configuringInput = false; + unlock_mutex(inputMutex); + return true; } void VoIP::setMicMute(Php::Parameters ¶ms) diff --git a/main.h b/main.h index c4b8a3e..f064157 100644 --- a/main.h +++ b/main.h @@ -104,6 +104,16 @@ public: void parseConfig(); void parseProxyConfig(); + std::queue inputFiles; + std::queue holdFiles; + tgvoip_mutex_t inputMutex; + + bool configuringInput; + FILE *outputFile; + tgvoip_mutex_t outputMutex; + + bool configuringOutput; + private: int callState = CALL_STATE_NONE; VoIPController *inst;