1
0
mirror of https://github.com/danog/php-libtgvoip.git synced 2024-12-02 09:17:55 +01:00
php-libtgvoip/audio/AudioInputModule.cpp

135 lines
3.7 KiB
C++
Raw Normal View History

//
// libtgvoip is free and unencumbered public domain software.
// For more information, see http://unlicense.org or the UNLICENSE file
// you should have received with this source code distribution.
//
2017-07-04 15:50:02 +02:00
#include "AudioInputModule.h"
#include <stdio.h>
2017-06-22 14:48:52 +02:00
#include "../libtgvoip/logging.h"
2017-07-11 21:11:23 +02:00
#include <queue>
2017-07-13 18:03:33 +02:00
#include <unistd.h>
using namespace tgvoip;
using namespace tgvoip::audio;
2017-07-13 18:03:33 +02:00
AudioInputModule::AudioInputModule(std::string deviceID, VoIPController *controller)
2017-07-09 21:12:01 +02:00
{
2017-07-13 18:03:33 +02:00
wrapper = (VoIP *)(controller->implData);
2017-07-10 12:30:13 +02:00
wrapper->in = this;
2017-07-13 18:03:33 +02:00
wrapper->inputState = AUDIO_STATE_CREATED;
}
2017-07-09 21:12:01 +02:00
AudioInputModule::~AudioInputModule()
{
2017-07-13 18:03:33 +02:00
wrapper->inputState = AUDIO_STATE_NONE;
2017-07-10 12:30:13 +02:00
wrapper->in = NULL;
2017-07-13 18:03:33 +02:00
2017-07-20 16:24:17 +02:00
if (senderThread)
{
2017-07-18 19:16:27 +02:00
LOGD("before join senderThread");
join_thread(senderThread);
}
}
2017-06-28 21:02:15 +02:00
2017-07-09 21:12:01 +02:00
void AudioInputModule::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels)
{
2017-07-11 21:11:23 +02:00
inputSampleNumber = 960;
inputSampleRate = sampleRate;
inputBitsPerSample = bitsPerSample;
inputChannels = channels;
inputSamplePeriod = 1.0 / sampleRate * 1000000;
inputWritePeriod = 1.0 / sampleRate * inputSampleNumber * 1000000;
inputSamplePeriodSec = 1.0 / sampleRate;
inputWritePeriodSec = 1.0 / sampleRate * inputSampleNumber;
inputSamplesSize = inputSampleNumber * inputChannels * inputBitsPerSample / 8;
inputCSamplesSize = inputSampleNumber * inputChannels * inputBitsPerSample / 8 * sizeof(unsigned char);
2017-06-28 21:02:15 +02:00
2017-07-13 18:03:33 +02:00
wrapper->inputState = AUDIO_STATE_CONFIGURED;
}
2017-07-09 21:12:01 +02:00
void AudioInputModule::Start()
{
2017-07-13 18:03:33 +02:00
if (wrapper->inputState == AUDIO_STATE_RUNNING)
2017-06-19 15:39:45 +02:00
return;
2017-07-13 18:03:33 +02:00
wrapper->inputState = AUDIO_STATE_RUNNING;
2017-07-20 16:24:17 +02:00
2017-07-11 21:11:23 +02:00
LOGE("STARTING SENDER THREAD");
start_thread(senderThread, StartSenderThread, this);
set_thread_priority(senderThread, get_thread_max_priority());
set_thread_name(senderThread, "voip-sender");
}
2017-07-09 21:12:01 +02:00
void AudioInputModule::Stop()
{
2017-07-13 18:03:33 +02:00
if (wrapper->inputState != AUDIO_STATE_RUNNING)
2017-07-10 00:06:50 +02:00
return;
2017-07-13 18:03:33 +02:00
wrapper->inputState = AUDIO_STATE_CONFIGURED;
}
2017-07-11 21:11:23 +02:00
2017-07-20 16:24:17 +02:00
void *AudioInputModule::StartSenderThread(void *input)
{
((AudioInputModule *)input)->RunSenderThread();
2017-07-11 21:11:23 +02:00
return NULL;
2017-06-19 23:38:03 +02:00
}
2017-07-04 15:50:02 +02:00
2017-07-20 16:24:17 +02:00
void AudioInputModule::RunSenderThread()
{
unsigned char *data = (unsigned char *)malloc(inputCSamplesSize);
2017-07-11 21:11:23 +02:00
size_t read;
double time = VoIPController::GetCurrentTime();
2017-07-13 18:03:33 +02:00
double sleeptime;
2017-07-20 16:24:17 +02:00
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)
{
2017-07-13 18:03:33 +02:00
LOGE("Sender: I'm late!");
2017-07-20 16:24:17 +02:00
}
else
{
2017-07-13 18:03:33 +02:00
usleep(sleeptime);
}
2017-07-11 21:11:23 +02:00
time = VoIPController::GetCurrentTime();
2017-07-13 18:03:33 +02:00
2017-07-20 16:24:17 +02:00
if (!wrapper->inputFiles.empty())
{
if ((read = fread(data, sizeof(unsigned char), inputSamplesSize, wrapper->inputFiles.front())) != inputCSamplesSize)
{
fclose(wrapper->inputFiles.front());
wrapper->inputFiles.pop();
2017-07-11 21:11:23 +02:00
memset(data + (read % inputCSamplesSize), 0, inputCSamplesSize - (read % inputCSamplesSize));
}
2017-07-13 18:54:59 +02:00
wrapper->playing = true;
2017-07-20 16:24:17 +02:00
}
else
{
2017-07-13 18:54:59 +02:00
wrapper->playing = false;
2017-07-20 16:24:17 +02:00
if (wrapper->holdFiles.empty())
{
2017-07-11 21:11:23 +02:00
memset(data, 0, inputCSamplesSize);
2017-07-20 16:24:17 +02:00
}
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();
2017-07-11 21:11:23 +02:00
memset(data + (read % inputCSamplesSize), 0, inputCSamplesSize - (read % inputCSamplesSize));
}
}
}
2017-07-20 16:24:17 +02:00
InvokeCallback(data, inputCSamplesSize);
2017-07-11 21:11:23 +02:00
}
2017-07-20 16:24:17 +02:00
unlock_mutex(wrapper->inputMutex);
2017-07-11 21:11:23 +02:00
}
free(data);
2017-07-13 18:03:33 +02:00
}
2017-07-11 21:11:23 +02:00
2017-07-09 21:12:01 +02:00
void AudioInputModule::EnumerateDevices(std::vector<AudioInputDevice> &devs)
{
2017-07-04 15:50:02 +02:00
}