refactor audio

This commit is contained in:
loki
2019-12-30 11:49:45 +01:00
parent 0289662017
commit 94e1dc903e
3 changed files with 37 additions and 51 deletions
+6 -5
View File
@@ -12,6 +12,7 @@
namespace audio { namespace audio {
using namespace std::literals; using namespace std::literals;
using opus_t = util::safe_ptr<OpusMSEncoder, opus_multistream_encoder_destroy>; using opus_t = util::safe_ptr<OpusMSEncoder, opus_multistream_encoder_destroy>;
using sample_queue_t = std::shared_ptr<safe::queue_t<std::vector<std::int16_t>>>;
struct opus_stream_config_t { struct opus_stream_config_t {
std::int32_t sampleRate; std::int32_t sampleRate;
@@ -49,7 +50,7 @@ static opus_stream_config_t HighSurround51 = {
map_high_surround51 map_high_surround51
}; };
void encodeThread(std::shared_ptr<safe::queue_t<packet_t>> packets, std::shared_ptr<safe::queue_t<platf::audio_t>> samples, config_t config) { void encodeThread(std::shared_ptr<safe::queue_t<packet_t>> packets, sample_queue_t samples, config_t config) {
//FIXME: Pick correct opus_stream_config_t based on config.channels //FIXME: Pick correct opus_stream_config_t based on config.channels
auto stream = &stereo; auto stream = &stereo;
opus_t opus { opus_multistream_encoder_create( opus_t opus { opus_multistream_encoder_create(
@@ -66,7 +67,7 @@ void encodeThread(std::shared_ptr<safe::queue_t<packet_t>> packets, std::shared_
while(auto sample = samples->pop()) { while(auto sample = samples->pop()) {
packet_t packet { 16*1024 }; // 16KB packet_t packet { 16*1024 }; // 16KB
int bytes = opus_multistream_encode(opus.get(), platf::audio_data(sample), frame_size, std::begin(packet), packet.size()); int bytes = opus_multistream_encode(opus.get(), sample->data(), frame_size, std::begin(packet), packet.size());
if(bytes < 0) { if(bytes < 0) {
std::cout << "Error: "sv << opus_strerror(bytes) << std::endl; std::cout << "Error: "sv << opus_strerror(bytes) << std::endl;
exit(7); exit(7);
@@ -78,7 +79,7 @@ void encodeThread(std::shared_ptr<safe::queue_t<packet_t>> packets, std::shared_
} }
void capture(std::shared_ptr<safe::queue_t<packet_t>> packets, config_t config) { void capture(std::shared_ptr<safe::queue_t<packet_t>> packets, config_t config) {
auto samples = std::make_shared<safe::queue_t<platf::audio_t>>(); auto samples = std::make_shared<sample_queue_t::element_type>();
auto mic = platf::microphone(); auto mic = platf::microphone();
if(!mic) { if(!mic) {
@@ -89,11 +90,11 @@ void capture(std::shared_ptr<safe::queue_t<packet_t>> packets, config_t config)
auto stream = &stereo; auto stream = &stereo;
auto frame_size = config.packetDuration * stream->sampleRate / 1000; auto frame_size = config.packetDuration * stream->sampleRate / 1000;
int bytes_per_frame = frame_size * sizeof(std::int16_t) * stream->channelCount; int samples_per_frame = frame_size * stream->channelCount;
std::thread thread { encodeThread, packets, samples, config }; std::thread thread { encodeThread, packets, samples, config };
while(packets->running()) { while(packets->running()) {
auto sample = platf::audio(mic, bytes_per_frame); auto sample = mic->sample(samples_per_frame);
samples->raise(std::move(sample)); samples->raise(std::move(sample));
} }
+9 -10
View File
@@ -22,26 +22,25 @@ public:
class display_t { class display_t {
public: public:
virtual std::unique_ptr<img_t> snapshot(bool cursor) = 0; virtual std::unique_ptr<img_t> snapshot(bool cursor) = 0;
virtual ~display_t() {}; virtual ~display_t() = default;
};
class mic_t {
public:
virtual std::vector<std::int16_t> sample(std::size_t sample_size) = 0;
virtual ~mic_t() = default;
}; };
void freeAudio(void*);
void freeMic(void*);
void freeInput(void*); void freeInput(void*);
using mic_t = util::safe_ptr<void, freeMic>;
using audio_t = util::safe_ptr<void, freeAudio>;
using input_t = util::safe_ptr<void, freeInput>; using input_t = util::safe_ptr<void, freeInput>;
std::string get_local_ip(); std::string get_local_ip();
mic_t microphone(); std::unique_ptr<mic_t> microphone();
audio_t audio(mic_t &mic, std::uint32_t sample_size);
std::unique_ptr<display_t> display(); std::unique_ptr<display_t> display();
int16_t *audio_data(audio_t &);
input_t input(); input_t input();
void move_mouse(input_t &input, int deltaX, int deltaY); void move_mouse(input_t &input, int deltaX, int deltaY);
void button_mouse(input_t &input, int button, bool release); void button_mouse(input_t &input, int button, bool release);
+21 -35
View File
@@ -211,9 +211,23 @@ struct shm_attr_t : display_t {
} }
}; };
struct mic_attr_t { struct mic_attr_t : public mic_t {
pa_sample_spec ss; pa_sample_spec ss;
util::safe_ptr<pa_simple, pa_simple_free> mic; util::safe_ptr<pa_simple, pa_simple_free> mic;
explicit mic_attr_t(const pa_sample_spec& ss) : ss(ss), mic {} {}
std::vector<std::int16_t> sample(std::size_t sample_size) override {
std::vector<std::int16_t> sample_buf;
sample_buf.resize(sample_size);
auto buf = sample_buf.data();
int error;
if(pa_simple_read(mic.get(), buf, sample_size * 2, &error)) {
std::cout << "pa_simple_read() failed: "sv << pa_strerror(error) << std::endl;
}
return sample_buf;
}
}; };
std::unique_ptr<display_t> shm_display() { std::unique_ptr<display_t> shm_display() {
@@ -264,21 +278,19 @@ std::unique_ptr<display_t> display() {
} }
//FIXME: Pass frame_rate instead of hard coding it //FIXME: Pass frame_rate instead of hard coding it
mic_t microphone() { std::unique_ptr<mic_t> microphone() {
mic_t mic { std::unique_ptr<mic_attr_t> mic {
new mic_attr_t { new mic_attr_t {
{ PA_SAMPLE_S16LE, 48000, 2 }, { PA_SAMPLE_S16LE, 48000, 2 }
{ }
} }
}; };
int error; int error;
mic_attr_t *mic_attr = (mic_attr_t*)mic.get(); mic->mic.reset(
mic_attr->mic.reset( pa_simple_new(nullptr, "sunshine", pa_stream_direction_t::PA_STREAM_RECORD, nullptr, "sunshine_record", &mic->ss, nullptr, nullptr, &error)
pa_simple_new(nullptr, "sunshine", pa_stream_direction_t::PA_STREAM_RECORD, nullptr, "sunshine_record", &mic_attr->ss, nullptr, nullptr, &error)
); );
if(!mic_attr->mic) { if(!mic->mic) {
auto err_str = pa_strerror(error); auto err_str = pa_strerror(error);
std::cout << "pa_simple_new() failed: "sv << err_str << std::endl; std::cout << "pa_simple_new() failed: "sv << err_str << std::endl;
@@ -288,24 +300,6 @@ mic_t microphone() {
return mic; return mic;
} }
audio_t audio(mic_t &mic, std::uint32_t buf_size) {
auto mic_attr = (mic_attr_t*)mic.get();
audio_t result { new std::uint8_t[buf_size] };
auto buf = (std::uint8_t*)result.get();
int error;
if(pa_simple_read(mic_attr->mic.get(), buf, buf_size, &error)) {
std::cout << "pa_simple_read() failed: "sv << pa_strerror(error) << std::endl;
}
return result;
}
std::int16_t *audio_data(audio_t &audio) {
return (int16_t*)audio.get();
}
ifaddr_t get_ifaddrs() { ifaddr_t get_ifaddrs() {
ifaddrs *p { nullptr }; ifaddrs *p { nullptr };
@@ -368,12 +362,4 @@ std::string get_local_ip() { return get_local_ip(AF_INET); }
void freeImage(XImage *p) { void freeImage(XImage *p) {
XDestroyImage(p); XDestroyImage(p);
} }
void freeMic(void*p) {
delete (mic_attr_t*)p;
}
void freeAudio(void*p) {
delete[] (std::uint8_t*)p;
}
} }