| 693 | } |
| 694 | |
| 695 | void Voice::thread() { |
| 696 | while (true) { |
| 697 | MutexLocker locker(m_threadMutex); |
| 698 | |
| 699 | m_threadCond.wait(m_threadMutex); |
| 700 | if (m_stopThread) |
| 701 | return; |
| 702 | |
| 703 | { |
| 704 | MutexLocker locker(m_captureMutex); |
| 705 | ByteArray encoded(VOICE_MAX_PACKET_SIZE, 0); |
| 706 | size_t frameSamples = VOICE_FRAME_SIZE * (size_t)m_deviceChannels; |
| 707 | while (m_capturedChunksFrames >= VOICE_FRAME_SIZE) { |
| 708 | std::vector<opus_int16> samples; |
| 709 | samples.reserve(frameSamples); |
| 710 | size_t samplesLeft = frameSamples; |
| 711 | while (samplesLeft && !m_capturedChunks.empty()) { |
| 712 | auto& front = m_capturedChunks.front(); |
| 713 | if (front.exhausted()) |
| 714 | m_capturedChunks.pop(); |
| 715 | else |
| 716 | samplesLeft -= front.takeSamples(samples, samplesLeft); |
| 717 | } |
| 718 | m_capturedChunksFrames -= VOICE_FRAME_SIZE; |
| 719 | |
| 720 | if (m_inputAmplitude != 1.0f) { |
| 721 | for (size_t i = 0; i != samples.size(); ++i) |
| 722 | samples[i] *= m_inputAmplitude; |
| 723 | } |
| 724 | |
| 725 | if (int encodedSize = opus_encode(m_encoder.get(), samples.data(), VOICE_FRAME_SIZE, (unsigned char*)encoded.ptr(), encoded.size())) { |
| 726 | if (encodedSize == 1) |
| 727 | continue; |
| 728 | |
| 729 | encoded.resize(encodedSize); |
| 730 | |
| 731 | { |
| 732 | MutexLocker locker(m_encodeMutex); |
| 733 | m_encodedChunks.emplace_back(std::move(encoded)); |
| 734 | m_encodedChunksLength += encodedSize; |
| 735 | |
| 736 | encoded = ByteArray(VOICE_MAX_PACKET_SIZE, 0); |
| 737 | } |
| 738 | |
| 739 | //Logger::info("Voice: encoded Opus chunk {} samples -> {} bytes", frameSamples, encodedSize); |
| 740 | } |
| 741 | else if (encodedSize < 0) |
| 742 | Logger::error("Voice: Opus encode error {}", opus_strerror(encodedSize)); |
| 743 | } |
| 744 | } |
| 745 | |
| 746 | continue; |
| 747 | |
| 748 | locker.unlock(); |
| 749 | Thread::yield(); |
| 750 | } |
| 751 | return; |
| 752 | } |
nothing calls this directly
no test coverage detected