/*
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
#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; }
size_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{0};
std::unique_ptr _timer;
PaStream* _stream{nullptr};
size_t _seq_size{4096};
uint32_t _block_length;
uint32_t _sample_rate{48000};
uint32_t _n_inputs{0};
uint32_t _n_outputs{0};
std::atomic _flag{false};
bool _is_activated{false};
};
} // namespace server
} // namespace ingen
#endif // INGEN_ENGINE_PORTAUDIODRIVER_HPP