TeaSpeak-Client/native/serverconnection/src/connection/audio/AudioSender.h

90 lines
2.4 KiB
C++

#pragma once
#include <mutex>
#include <memory>
#include "VoiceClient.h"
namespace tc {
namespace audio {
namespace codec {
class Converter;
}
class AudioResampler;
class AudioOutputSource;
}
namespace connection {
class VoiceConnection;
class VoiceSender : public event::EventEntry {
template<typename _Tp, typename _Up>
friend inline std::shared_ptr<_Tp> std::static_pointer_cast(const std::shared_ptr<_Up>& __r) noexcept;
friend class VoiceConnection;
public:
explicit VoiceSender(VoiceConnection*);
virtual ~VoiceSender();
codec::value get_codec() { return this->_current_codec; }
void set_codec(codec::value value) { this->_current_codec = value; }
void finalize();
void send_data(const void* /* buffer */, size_t /* samples */, size_t /* sample rate */, size_t /* channels */);
void send_stop();
void set_voice_send_enabled(bool /* flag */);
private:
std::weak_ptr<VoiceSender> _ref;
VoiceConnection* handle;
struct AudioCodec {
size_t packet_counter = 0;
std::chrono::system_clock::time_point last_packet;
std::shared_ptr<audio::codec::Converter> converter;
std::shared_ptr<audio::AudioResampler> resampler;
};
std::array<std::unique_ptr<AudioCodec>, codec::MAX + 1> codec{nullptr};
bool initialize_codec(std::string&, codec::value /* codec */, size_t /* channels */, size_t /* source sample rate */, bool /* reset decoder */);
codec::value _current_codec = codec::OPUS_VOICE;
std::mutex _execute_lock;
void* _buffer = nullptr;
size_t _buffer_size = 0;
void clear_buffer() {
if(this->_buffer)
::free(this->_buffer);
this->_buffer = nullptr;
this->_buffer_size = 0;
}
void ensure_buffer(size_t length) {
if(!this->_buffer || this->_buffer_size < length) {
if(this->_buffer)
::free(this->_buffer);
this->_buffer = malloc(length);
this->_buffer_size = length;
}
}
struct AudioFrame {
pipes::buffer buffer;
size_t sample_rate;
size_t channels;
std::chrono::system_clock::time_point timestamp;
};
std::mutex raw_audio_buffer_lock;
std::deque<std::unique_ptr<AudioFrame>> raw_audio_buffers;
bool voice_send_enabled = false;
void encode_raw_frame(const std::unique_ptr<AudioFrame>&);
void event_execute(const std::chrono::system_clock::time_point &point) override;
};
}
}