summaryrefslogtreecommitdiffstats
path: root/src/server/PortAudioDriver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/PortAudioDriver.cpp')
-rw-r--r--src/server/PortAudioDriver.cpp297
1 files changed, 0 insertions, 297 deletions
diff --git a/src/server/PortAudioDriver.cpp b/src/server/PortAudioDriver.cpp
deleted file mode 100644
index f892c99f..00000000
--- a/src/server/PortAudioDriver.cpp
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2007-2017 David Robillard <http://drobilla.net/>
-
- 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 <http://www.gnu.org/licenses/>.
-*/
-
-#include "ingen_config.h"
-
-#include <cstdlib>
-#include <string>
-
-#include <portaudio.h>
-
-#include "ingen/Configuration.hpp"
-#include "ingen/LV2Features.hpp"
-#include "ingen/Log.hpp"
-#include "ingen/URIMap.hpp"
-#include "ingen/World.hpp"
-#include "lv2/lv2plug.in/ns/ext/atom/util.h"
-
-#include "Buffer.hpp"
-#include "DuplexPort.hpp"
-#include "Engine.hpp"
-#include "GraphImpl.hpp"
-#include "PortAudioDriver.hpp"
-#include "PortImpl.hpp"
-#include "FrameTimer.hpp"
-#include "ThreadManager.hpp"
-#include "util.hpp"
-
-namespace Ingen {
-namespace Server {
-
-static bool
-pa_error(const char* msg, PaError err)
-{
- fprintf(stderr, "error: %s (%s)\n", msg, Pa_GetErrorText(err));
- Pa_Terminate();
- return false;
-}
-
-PortAudioDriver::PortAudioDriver(Engine& engine)
- : _engine(engine)
- , _sem(0)
- , _stream(nullptr)
- , _seq_size(4096)
- , _block_length(engine.world()->conf().option("buffer-size").get<int32_t>())
- , _sample_rate(48000)
- , _n_inputs(0)
- , _n_outputs(0)
- , _flag(false)
- , _is_activated(false)
-{
-}
-
-PortAudioDriver::~PortAudioDriver()
-{
- deactivate();
- _ports.clear_and_dispose([](EnginePort* p) { delete p; });
-}
-
-bool
-PortAudioDriver::attach()
-{
- PaError st = paNoError;
- if ((st = Pa_Initialize())) {
- return pa_error("Failed to initialize audio system", st);
- }
-
- // Get default input and output devices
- _inputParameters.device = Pa_GetDefaultInputDevice();
- _outputParameters.device = Pa_GetDefaultOutputDevice();
- if (_inputParameters.device == paNoDevice) {
- return pa_error("No default input device", paDeviceUnavailable);
- } else if (_outputParameters.device == paNoDevice) {
- return pa_error("No default output device", paDeviceUnavailable);
- }
-
- const PaDeviceInfo* in_dev = Pa_GetDeviceInfo(_inputParameters.device);
-
- /* TODO: It looks like it is somehow actually impossible to request the
- best/native buffer size then retrieve what it actually is with
- PortAudio. How such a glaring useless flaw exists in such a widespread
- library is beyond me... */
-
- _sample_rate = in_dev->defaultSampleRate;
-
- _timer = std::unique_ptr<FrameTimer>(
- new FrameTimer(_block_length, _sample_rate));
-
- return true;
-}
-
-bool
-PortAudioDriver::activate()
-{
- const PaDeviceInfo* in_dev = Pa_GetDeviceInfo(_inputParameters.device);
- const PaDeviceInfo* out_dev = Pa_GetDeviceInfo(_outputParameters.device);
-
- // Count number of input and output audio ports/channels
- _inputParameters.channelCount = 0;
- _outputParameters.channelCount = 0;
- for (const auto& port : _ports) {
- if (port.graph_port()->is_a(PortType::AUDIO)) {
- if (port.graph_port()->is_input()) {
- ++_inputParameters.channelCount;
- } else if (port.graph_port()->is_output()) {
- ++_outputParameters.channelCount;
- }
- }
- }
-
- // Configure audio format
- _inputParameters.sampleFormat = paFloat32|paNonInterleaved;
- _inputParameters.suggestedLatency = in_dev->defaultLowInputLatency;
- _inputParameters.hostApiSpecificStreamInfo = nullptr;
- _outputParameters.sampleFormat = paFloat32|paNonInterleaved;
- _outputParameters.suggestedLatency = out_dev->defaultLowOutputLatency;
- _outputParameters.hostApiSpecificStreamInfo = nullptr;
-
- // Open stream
- PaError st = paNoError;
- if ((st = Pa_OpenStream(
- &_stream,
- _inputParameters.channelCount ? &_inputParameters : nullptr,
- _outputParameters.channelCount ? &_outputParameters : nullptr,
- in_dev->defaultSampleRate,
- _block_length, // paFramesPerBufferUnspecified, // FIXME: ?
- 0,
- pa_process_cb,
- this))) {
- return pa_error("Failed to open audio stream", st);
- }
-
- _is_activated = true;
- if ((st = Pa_StartStream(_stream))) {
- return pa_error("Error starting audio stream", st);
- }
-
- return true;
-}
-
-void
-PortAudioDriver::deactivate()
-{
- Pa_Terminate();
-}
-
-SampleCount
-PortAudioDriver::frame_time() const
-{
- return _timer->frame_time(_engine.current_time()) + _engine.block_length();
-}
-
-EnginePort*
-PortAudioDriver::get_port(const Raul::Path& path)
-{
- for (auto& p : _ports) {
- if (p.graph_port()->path() == path) {
- return &p;
- }
- }
-
- return nullptr;
-}
-
-void
-PortAudioDriver::add_port(RunContext& context, EnginePort* port)
-{
- _ports.push_back(*port);
-}
-
-void
-PortAudioDriver::remove_port(RunContext& context, EnginePort* port)
-{
- _ports.erase(_ports.iterator_to(*port));
-}
-
-void
-PortAudioDriver::register_port(EnginePort& port)
-{
-}
-
-void
-PortAudioDriver::unregister_port(EnginePort& port)
-{
-}
-
-void
-PortAudioDriver::rename_port(const Raul::Path& old_path,
- const Raul::Path& new_path)
-{
-}
-
-void
-PortAudioDriver::port_property(const Raul::Path& path,
- const URI& uri,
- const Atom& value)
-{
-}
-
-EnginePort*
-PortAudioDriver::create_port(DuplexPort* graph_port)
-{
- EnginePort* eport = nullptr;
- if (graph_port->is_a(PortType::AUDIO) || graph_port->is_a(PortType::CV)) {
- // Audio buffer port, use Jack buffer directly
- eport = new EnginePort(graph_port);
- graph_port->set_is_driver_port(*_engine.buffer_factory());
- } else if (graph_port->is_a(PortType::ATOM) &&
- graph_port->buffer_type() == _engine.world()->uris().atom_Sequence) {
- // Sequence port, make Jack port but use internal LV2 format buffer
- eport = new EnginePort(graph_port);
- }
-
- if (graph_port->is_a(PortType::AUDIO)) {
- if (graph_port->is_input()) {
- eport->set_driver_index(_n_inputs++);
- } else {
- eport->set_driver_index(_n_outputs++);
- }
- }
-
- if (eport) {
- register_port(*eport);
- }
-
- return eport;
-}
-
-void
-PortAudioDriver::pre_process_port(RunContext& context,
- EnginePort* port,
- const void* inputs,
- void* outputs)
-{
- if (!port->graph_port()->is_a(PortType::AUDIO)) {
- return;
- }
-
- if (port->is_input()) {
- port->set_buffer(((float**)inputs)[port->driver_index()]);
- } else {
- port->set_buffer(((float**)outputs)[port->driver_index()]);
- memset(port->buffer(), 0, _block_length * sizeof(float));
- }
-
- port->graph_port()->set_driver_buffer(
- port->buffer(), _block_length * sizeof(float));
-}
-
-void
-PortAudioDriver::post_process_port(RunContext& context,
- EnginePort* port,
- const void* inputs,
- void* outputs)
-{
-}
-
-int
-PortAudioDriver::process_cb(const void* inputs,
- void* outputs,
- unsigned long nframes,
- const PaStreamCallbackTimeInfo* time,
- PaStreamCallbackFlags flags)
-{
- _engine.advance(nframes);
- _timer->update(_engine.current_time(), _engine.run_context().start());
-
- // Read input
- for (auto& p : _ports) {
- pre_process_port(_engine.run_context(), &p, inputs, outputs);
- }
-
- // Process
- _engine.run(nframes);
-
- // Write output
- for (auto& p : _ports) {
- post_process_port(_engine.run_context(), &p, inputs, outputs);
- }
-
- return 0;
-}
-
-} // namespace Server
-} // namespace Ingen