diff --git a/sunshine/audio.cpp b/sunshine/audio.cpp index 2bd76b16..1d78175a 100644 --- a/sunshine/audio.cpp +++ b/sunshine/audio.cpp @@ -12,6 +12,7 @@ namespace audio { using namespace std::literals; using opus_t = util::safe_ptr; +using sample_queue_t = std::shared_ptr>>; struct opus_stream_config_t { std::int32_t sampleRate; @@ -49,7 +50,7 @@ static opus_stream_config_t HighSurround51 = { map_high_surround51 }; -void encodeThread(std::shared_ptr> packets, std::shared_ptr> samples, config_t config) { +void encodeThread(std::shared_ptr> packets, sample_queue_t samples, config_t config) { //FIXME: Pick correct opus_stream_config_t based on config.channels auto stream = &stereo; opus_t opus { opus_multistream_encoder_create( @@ -66,7 +67,7 @@ void encodeThread(std::shared_ptr> packets, std::shared_ while(auto sample = samples->pop()) { 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) { std::cout << "Error: "sv << opus_strerror(bytes) << std::endl; exit(7); @@ -78,7 +79,7 @@ void encodeThread(std::shared_ptr> packets, std::shared_ } void capture(std::shared_ptr> packets, config_t config) { - auto samples = std::make_shared>(); + auto samples = std::make_shared(); auto mic = platf::microphone(); if(!mic) { @@ -89,11 +90,11 @@ void capture(std::shared_ptr> packets, config_t config) auto stream = &stereo; 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 }; while(packets->running()) { - auto sample = platf::audio(mic, bytes_per_frame); + auto sample = mic->sample(samples_per_frame); samples->raise(std::move(sample)); } diff --git a/sunshine/platform/common.h b/sunshine/platform/common.h index 8e7ca0ce..770d2a9b 100644 --- a/sunshine/platform/common.h +++ b/sunshine/platform/common.h @@ -22,26 +22,25 @@ public: class display_t { public: virtual std::unique_ptr snapshot(bool cursor) = 0; - virtual ~display_t() {}; + virtual ~display_t() = default; +}; + +class mic_t { +public: + virtual std::vector sample(std::size_t sample_size) = 0; + + virtual ~mic_t() = default; }; -void freeAudio(void*); -void freeMic(void*); void freeInput(void*); -using mic_t = util::safe_ptr; -using audio_t = util::safe_ptr; using input_t = util::safe_ptr; std::string get_local_ip(); -mic_t microphone(); -audio_t audio(mic_t &mic, std::uint32_t sample_size); - +std::unique_ptr microphone(); std::unique_ptr display(); -int16_t *audio_data(audio_t &); - input_t input(); void move_mouse(input_t &input, int deltaX, int deltaY); void button_mouse(input_t &input, int button, bool release); diff --git a/sunshine/platform/linux.cpp b/sunshine/platform/linux.cpp index 929cba11..5efeb0b6 100644 --- a/sunshine/platform/linux.cpp +++ b/sunshine/platform/linux.cpp @@ -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; util::safe_ptr mic; + + explicit mic_attr_t(const pa_sample_spec& ss) : ss(ss), mic {} {} + std::vector sample(std::size_t sample_size) override { + std::vector 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 shm_display() { @@ -264,21 +278,19 @@ std::unique_ptr display() { } //FIXME: Pass frame_rate instead of hard coding it -mic_t microphone() { - mic_t mic { - new mic_attr_t { - { PA_SAMPLE_S16LE, 48000, 2 }, - { } +std::unique_ptr microphone() { + std::unique_ptr mic { + new mic_attr_t { + { PA_SAMPLE_S16LE, 48000, 2 } } }; int error; - mic_attr_t *mic_attr = (mic_attr_t*)mic.get(); - mic_attr->mic.reset( - pa_simple_new(nullptr, "sunshine", pa_stream_direction_t::PA_STREAM_RECORD, nullptr, "sunshine_record", &mic_attr->ss, nullptr, nullptr, &error) + mic->mic.reset( + pa_simple_new(nullptr, "sunshine", pa_stream_direction_t::PA_STREAM_RECORD, nullptr, "sunshine_record", &mic->ss, nullptr, nullptr, &error) ); - if(!mic_attr->mic) { + if(!mic->mic) { auto err_str = pa_strerror(error); std::cout << "pa_simple_new() failed: "sv << err_str << std::endl; @@ -288,24 +300,6 @@ mic_t microphone() { 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() { ifaddrs *p { nullptr }; @@ -368,12 +362,4 @@ std::string get_local_ip() { return get_local_ip(AF_INET); } void freeImage(XImage *p) { XDestroyImage(p); } - -void freeMic(void*p) { - delete (mic_attr_t*)p; -} - -void freeAudio(void*p) { - delete[] (std::uint8_t*)p; -} }