/* This file is part of Ingen. Copyright 2007-2017 David Robillard Ingen is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. Ingen is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. You should have received a copy of the GNU Affero General Public License along with Ingen. If not, see . */ #ifndef INGEN_ENGINE_PORTAUDIODRIVER_HPP #define INGEN_ENGINE_PORTAUDIODRIVER_HPP #include "Driver.hpp" #include "EnginePort.hpp" // IWYU pragma: keep #include "types.hpp" #include "ingen/URI.hpp" #include "raul/Semaphore.hpp" #include #include #include #include #include #include namespace raul { class Path; } // namespace raul namespace ingen { class Atom; namespace server { class Buffer; class DuplexPort; class Engine; class FrameTimer; class RunContext; class PortAudioDriver : public Driver { public: explicit PortAudioDriver(Engine& engine); ~PortAudioDriver() override; bool attach(); bool activate() override; void deactivate() override; EnginePort* create_port(DuplexPort* graph_port) override; EnginePort* get_port(const raul::Path& path) override; void rename_port(const raul::Path& old_path, const raul::Path& new_path) override; void port_property(const raul::Path& path, const URI& uri, const Atom& value) override; void add_port(RunContext& ctx, EnginePort* port) override; void remove_port(RunContext& ctx, EnginePort* port) override; void register_port(EnginePort& port) override; void unregister_port(EnginePort& port) override; void append_time_events(RunContext& ctx, Buffer& buffer) override {} SampleCount frame_time() const override; int real_time_priority() override { return 80; } SampleCount block_length() const override { return _block_length; } uint32_t seq_size() const override { return _seq_size; } SampleCount sample_rate() const override { return _sample_rate; } private: friend class PortAudioPort; static int pa_process_cb(const void* inputs, void* outputs, unsigned long nframes, const PaStreamCallbackTimeInfo* time, PaStreamCallbackFlags flags, void* handle) { return static_cast(handle)->process_cb( inputs, outputs, nframes, time, flags); } int process_cb(const void* inputs, void* outputs, unsigned long nframes, const PaStreamCallbackTimeInfo* time, PaStreamCallbackFlags flags); void pre_process_port(RunContext& ctx, EnginePort* port, const void* inputs, void* outputs); void post_process_port(RunContext& ctx, EnginePort* port, const void* inputs, void* outputs); protected: using Ports = boost::intrusive::slist>; Engine& _engine; Ports _ports; PaStreamParameters _inputParameters; PaStreamParameters _outputParameters; raul::Semaphore _sem{0U}; std::unique_ptr _timer; PaStream* _stream{nullptr}; uint32_t _seq_size{4096U}; uint32_t _block_length; uint32_t _sample_rate{48000U}; uint32_t _n_inputs{0U}; uint32_t _n_outputs{0U}; std::atomic _flag{false}; bool _is_activated{false}; }; } // namespace server } // namespace ingen #endif // INGEN_ENGINE_PORTAUDIODRIVER_HPP