cleanup
This commit is contained in:
parent
3b38825b34
commit
77e14b5941
@ -349,7 +349,7 @@ void Mixer::read(int16_t* outBuffer, size_t frameCount, ExtraMixFunction extraMi
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (extraMixFunction)
|
if (extraMixFunction)
|
||||||
extraMixFunction(outBuffer, bufferSize, channels);
|
extraMixFunction(outBuffer, frameCount, channels);
|
||||||
|
|
||||||
{
|
{
|
||||||
MutexLocker locker(m_effectsMutex);
|
MutexLocker locker(m_effectsMutex);
|
||||||
|
1
source/extern/CMakeLists.txt
vendored
1
source/extern/CMakeLists.txt
vendored
@ -3,6 +3,7 @@ SET (OPUS_INSTALL_CMAKE_CONFIG_MODULE OFF)
|
|||||||
SET (OPUS_X86_MAY_HAVE_AVX OFF)
|
SET (OPUS_X86_MAY_HAVE_AVX OFF)
|
||||||
SET (OPUS_X86_MAY_HAVE_SSE4_1 OFF)
|
SET (OPUS_X86_MAY_HAVE_SSE4_1 OFF)
|
||||||
SET (OPUS_STACK_PROTECTOR OFF)
|
SET (OPUS_STACK_PROTECTOR OFF)
|
||||||
|
SET (OPUS_ENABLE_FLOAT_API ON)
|
||||||
ADD_SUBDIRECTORY (opus)
|
ADD_SUBDIRECTORY (opus)
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES (
|
INCLUDE_DIRECTORIES (
|
||||||
|
@ -145,6 +145,7 @@ Voice::Voice(ApplicationControllerPtr appController) : m_encoder(nullptr, opus_e
|
|||||||
|
|
||||||
Voice::~Voice() {
|
Voice::~Voice() {
|
||||||
save();
|
save();
|
||||||
|
closeDevice();
|
||||||
|
|
||||||
s_singleton = nullptr;
|
s_singleton = nullptr;
|
||||||
}
|
}
|
||||||
@ -162,8 +163,8 @@ void Voice::loadJson(Json const& config) {
|
|||||||
m_threshold = config.getFloat("threshold", m_threshold);
|
m_threshold = config.getFloat("threshold", m_threshold);
|
||||||
m_inputVolume = config.getFloat("inputVolume", m_inputVolume);
|
m_inputVolume = config.getFloat("inputVolume", m_inputVolume);
|
||||||
m_outputVolume = config.getFloat("outputVolume", m_outputVolume);
|
m_outputVolume = config.getFloat("outputVolume", m_outputVolume);
|
||||||
m_inputMode = VoiceInputModeNames.getLeft(config.getString("inputMode", "pushToTalk"));
|
m_inputMode = VoiceInputModeNames.getLeft(config.getString("inputMode", "PushToTalk"));
|
||||||
m_channelMode = VoiceChannelModeNames.getLeft(config.getString("channelMode", "mono"));
|
m_channelMode = VoiceChannelModeNames.getLeft(config.getString("channelMode", "Mono"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -239,7 +240,7 @@ void Voice::readAudioData(uint8_t* stream, int len) {
|
|||||||
m_capturedChunksFrames += samples / m_deviceChannels;
|
m_capturedChunksFrames += samples / m_deviceChannels;
|
||||||
auto data = (opus_int16*)malloc(len);
|
auto data = (opus_int16*)malloc(len);
|
||||||
memcpy(data, stream, len);
|
memcpy(data, stream, len);
|
||||||
m_capturedChunks.emplace(data, samples);
|
m_capturedChunks.emplace(data, samples); // takes ownership
|
||||||
}
|
}
|
||||||
else { // Clear out any residual data so they don't manifest at the start of the next encode, whenever that is
|
else { // Clear out any residual data so they don't manifest at the start of the next encode, whenever that is
|
||||||
while (!m_capturedChunks.empty())
|
while (!m_capturedChunks.empty())
|
||||||
@ -248,46 +249,47 @@ void Voice::readAudioData(uint8_t* stream, int len) {
|
|||||||
m_capturedChunksFrames = 0;
|
m_capturedChunksFrames = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<opus_int16> takenSamples;
|
|
||||||
while (m_capturedChunksFrames >= VOICE_FRAME_SIZE) {
|
while (m_capturedChunksFrames >= VOICE_FRAME_SIZE) {
|
||||||
takenSamples.clear();
|
|
||||||
size_t samplesToTake = VOICE_FRAME_SIZE * (size_t)m_deviceChannels;
|
size_t samplesToTake = VOICE_FRAME_SIZE * (size_t)m_deviceChannels;
|
||||||
|
std::vector<opus_int16> takenSamples;
|
||||||
takenSamples.reserve(samplesToTake);
|
takenSamples.reserve(samplesToTake);
|
||||||
|
|
||||||
while (!m_capturedChunks.empty()) {
|
while (!m_capturedChunks.empty()) {
|
||||||
auto& front = m_capturedChunks.front();
|
auto& front = m_capturedChunks.front();
|
||||||
if (front.exhausted())
|
if (front.exhausted())
|
||||||
m_capturedChunks.pop();
|
m_capturedChunks.pop();
|
||||||
else if ((samplesToTake -= front.takeSamples(takenSamples, samplesToTake)) == 0)
|
else {
|
||||||
|
samplesToTake -= front.takeSamples(takenSamples, samplesToTake);
|
||||||
|
if (samplesToTake == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
m_capturedChunksFrames -= VOICE_FRAME_SIZE;
|
m_capturedChunksFrames -= VOICE_FRAME_SIZE;
|
||||||
|
|
||||||
ByteArray encodedData(VOICE_MAX_PACKET_SIZE, 0);
|
|
||||||
float vol = m_inputVolume;
|
float vol = m_inputVolume;
|
||||||
if (m_inputVolume != 1.0f) {
|
if (m_inputVolume != 1.0f) {
|
||||||
for (size_t i = 0; i != takenSamples.size(); ++i)
|
for (size_t i = 0; i != takenSamples.size(); ++i)
|
||||||
takenSamples[i] *= m_inputVolume;
|
takenSamples[i] *= m_inputVolume;
|
||||||
}
|
}
|
||||||
|
ByteArray encodedData(VOICE_MAX_FRAME_SIZE, 0);
|
||||||
|
opus_int32 encodedSize = opus_encode(m_encoder.get(), takenSamples.data(), VOICE_FRAME_SIZE, (unsigned char*)encodedData.ptr(), encodedData.size());
|
||||||
if (opus_int32 size = opus_encode(m_encoder.get(), takenSamples.data(), VOICE_FRAME_SIZE, (unsigned char*)encodedData.ptr(), VOICE_MAX_PACKET_SIZE)) {
|
if (encodedSize == 1)
|
||||||
if (size == 1)
|
|
||||||
continue;
|
continue;
|
||||||
|
else if (encodedSize < 0)
|
||||||
encodedData.resize(size);
|
Logger::error("Voice: Opus encode error {}", opus_strerror(encodedSize));
|
||||||
|
else {
|
||||||
|
encodedData.resize(encodedSize);
|
||||||
MutexLocker lock(m_captureMutex);
|
MutexLocker lock(m_captureMutex);
|
||||||
m_encodedChunks.emplace_back(move(encodedData)); // reset takes ownership of data buffer
|
m_encodedChunks.emplace_back(move(encodedData)); // reset takes ownership of data buffer
|
||||||
m_encodedChunksLength += size;
|
m_encodedChunksLength += encodedSize;
|
||||||
Logger::info("Voice: encoded Opus chunk {} bytes big", size);
|
Logger::info("Voice: encoded Opus chunk {} bytes big", encodedSize);
|
||||||
}
|
|
||||||
else if (size < 0) {
|
|
||||||
Logger::error("Voice: Opus encode error {}", opus_strerror(size));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Voice::mix(int16_t* buffer, size_t samples, unsigned channels) {
|
void Voice::mix(int16_t* buffer, size_t frameCount, unsigned channels) {
|
||||||
|
size_t samples = frameCount * channels;
|
||||||
static std::vector<int16_t> finalMixBuffer{};
|
static std::vector<int16_t> finalMixBuffer{};
|
||||||
static std::vector<int32_t> voiceMixBuffer{};
|
static std::vector<int32_t> voiceMixBuffer{};
|
||||||
finalMixBuffer.resize(samples);
|
finalMixBuffer.resize(samples);
|
||||||
@ -326,7 +328,7 @@ void Voice::mix(int16_t* buffer, size_t samples, unsigned channels) {
|
|||||||
|
|
||||||
float vol = m_outputVolume;
|
float vol = m_outputVolume;
|
||||||
for (size_t i = 0; i != samples; ++i)
|
for (size_t i = 0; i != samples; ++i)
|
||||||
finBuf[i] = (int16_t)std::clamp<int>(mixBuf[i] * vol, INT16_MIN, INT16_MAX);
|
finBuf[i] = (int16_t)clamp<int>(mixBuf[i] * vol, INT16_MIN, INT16_MAX);
|
||||||
|
|
||||||
SDL_MixAudioFormat((Uint8*)buffer, (Uint8*)finBuf, AUDIO_S16, samples * sizeof(int16_t), SDL_MIX_MAXVOLUME);
|
SDL_MixAudioFormat((Uint8*)buffer, (Uint8*)finBuf, AUDIO_S16, samples * sizeof(int16_t), SDL_MIX_MAXVOLUME);
|
||||||
}
|
}
|
||||||
@ -344,7 +346,7 @@ void Voice::update(PositionalAttenuationFunction positionalAttenuationFunction)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Time::monotonicMilliseconds() > m_nextSaveTime) {
|
if (m_nextSaveTime && Time::monotonicMilliseconds() > m_nextSaveTime) {
|
||||||
m_nextSaveTime = 0;
|
m_nextSaveTime = 0;
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
@ -365,7 +367,7 @@ int Voice::send(DataStreamBuffer& out, size_t budget) {
|
|||||||
out.write<uint16_t>(VOICE_VERSION);
|
out.write<uint16_t>(VOICE_VERSION);
|
||||||
MutexLocker captureLock(m_captureMutex);
|
MutexLocker captureLock(m_captureMutex);
|
||||||
|
|
||||||
if (!m_encoder || m_capturedChunks.empty())
|
if (m_capturedChunks.empty())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
std::vector<ByteArray> encodedChunks = move(m_encodedChunks);
|
std::vector<ByteArray> encodedChunks = move(m_encodedChunks);
|
||||||
@ -420,6 +422,8 @@ bool Voice::receive(SpeakerPtr speaker, std::string_view view) {
|
|||||||
throw VoiceException(strf("Decoder error: {}", opus_strerror(samples)), false);
|
throw VoiceException(strf("Decoder error: {}", opus_strerror(samples)), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger::info("Voice: decoded Opus chunk {} bytes big", opusLength);
|
||||||
|
|
||||||
static auto getCVT = [](int channels) -> SDL_AudioCVT {
|
static auto getCVT = [](int channels) -> SDL_AudioCVT {
|
||||||
SDL_AudioCVT cvt;
|
SDL_AudioCVT cvt;
|
||||||
SDL_BuildAudioCVT(&cvt, AUDIO_S16SYS, channels, VOICE_SAMPLE_RATE, AUDIO_S16, 2, 44100);
|
SDL_BuildAudioCVT(&cvt, AUDIO_S16SYS, channels, VOICE_SAMPLE_RATE, AUDIO_S16, 2, 44100);
|
||||||
@ -478,8 +482,6 @@ void Voice::resetEncoder() {
|
|||||||
void Voice::openDevice() {
|
void Voice::openDevice() {
|
||||||
closeDevice();
|
closeDevice();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
m_applicationController->openAudioInputDevice(
|
m_applicationController->openAudioInputDevice(
|
||||||
m_deviceName ? m_deviceName->utf8Ptr() : nullptr,
|
m_deviceName ? m_deviceName->utf8Ptr() : nullptr,
|
||||||
VOICE_SAMPLE_RATE,
|
VOICE_SAMPLE_RATE,
|
||||||
|
@ -42,7 +42,7 @@ struct VoiceAudioChunk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline size_t takeSamples(std::vector<int16_t>& out, size_t count) {
|
inline size_t takeSamples(std::vector<int16_t>& out, size_t count) {
|
||||||
size_t toRead = std::min<size_t>(count, remaining);
|
size_t toRead = min<size_t>(count, remaining);
|
||||||
int16_t* start = data.get() + offset;
|
int16_t* start = data.get() + offset;
|
||||||
out.insert(out.end(), start, start + toRead);
|
out.insert(out.end(), start, start + toRead);
|
||||||
offset += toRead;
|
offset += toRead;
|
||||||
@ -133,9 +133,7 @@ public:
|
|||||||
// Must be called every frame with input state, expires after 1s.
|
// Must be called every frame with input state, expires after 1s.
|
||||||
void setInput(bool input = true);
|
void setInput(bool input = true);
|
||||||
|
|
||||||
inline int encoderChannels() const {
|
inline int encoderChannels() const { return (int)m_channelMode; }
|
||||||
return m_channelMode == VoiceChannelMode::Mono ? 1 : 2;
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
static Voice* s_singleton;
|
static Voice* s_singleton;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user