mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-15 19:16:40 +01:00
new internal port type, round I, plus tiny fix for legalize_for_xml() (also for 2.0-ongoing)
git-svn-id: svn://localhost/ardour2/trunk@2559 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
df28e90c67
commit
239ec39da6
18 changed files with 546 additions and 48 deletions
|
|
@ -1694,7 +1694,7 @@ static string
|
|||
legalize_for_xml_node (string str)
|
||||
{
|
||||
string::size_type pos;
|
||||
string legal_chars = "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_+=:";
|
||||
string legal_chars = "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_=:";
|
||||
string legal;
|
||||
|
||||
legal = str;
|
||||
|
|
|
|||
|
|
@ -65,6 +65,8 @@ gain.cc
|
|||
gdither.cc
|
||||
globals.cc
|
||||
import.cc
|
||||
internal_port.cc
|
||||
internal_audio_port.cc
|
||||
io.cc
|
||||
io_processor.cc
|
||||
jack_port.cc
|
||||
|
|
|
|||
|
|
@ -102,6 +102,12 @@ public:
|
|||
_silent = false;
|
||||
}
|
||||
|
||||
/** Reallocate the buffer used internally to handle at least @nframes of data
|
||||
*
|
||||
* Constructor MUST have been passed capacity!=0 or this will die (to prevent mem leaks).
|
||||
*/
|
||||
void resize (size_t nframes);
|
||||
|
||||
const Sample* data () const { return _data; }
|
||||
Sample* data () { return _data; }
|
||||
|
||||
|
|
|
|||
|
|
@ -35,11 +35,11 @@ class AudioPort : public virtual Port {
|
|||
public:
|
||||
DataType type() const { return DataType::AUDIO; }
|
||||
|
||||
Buffer& get_buffer () {
|
||||
virtual Buffer& get_buffer () {
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
AudioBuffer& get_audio_buffer() {
|
||||
virtual AudioBuffer& get_audio_buffer() {
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
|
|
@ -70,7 +70,8 @@ class AudioPort : public virtual Port {
|
|||
protected:
|
||||
friend class AudioEngine;
|
||||
|
||||
AudioPort ();
|
||||
AudioPort (); // data buffer comes from elsewhere (e.g. JACK)
|
||||
AudioPort (nframes_t); // data buffer owned by ardour
|
||||
void reset ();
|
||||
|
||||
/* engine isn't supposed to access below here */
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ namespace ARDOUR {
|
|||
|
||||
class Session;
|
||||
class Port;
|
||||
class InternalPort;
|
||||
|
||||
class AudioEngine : public sigc::trackable
|
||||
{
|
||||
|
|
@ -113,8 +114,8 @@ class AudioEngine : public sigc::trackable
|
|||
virtual const char *what() const throw() { return "could not connect to engine backend"; }
|
||||
};
|
||||
|
||||
Port *register_input_port (DataType type, const std::string& portname);
|
||||
Port *register_output_port (DataType type, const std::string& portname);
|
||||
Port *register_input_port (PortType, DataType, const std::string& portname);
|
||||
Port *register_output_port (PortType, DataType, const std::string& portname);
|
||||
int unregister_port (Port &);
|
||||
|
||||
int connect (const std::string& source, const std::string& destination);
|
||||
|
|
@ -219,11 +220,13 @@ class AudioEngine : public sigc::trackable
|
|||
|
||||
SerializedRCUManager<Ports> ports;
|
||||
|
||||
Port *register_port (DataType type, const std::string& portname, bool input);
|
||||
Port *register_port (PortType ptype, DataType type, const std::string& portname, bool input);
|
||||
|
||||
int process_callback (nframes_t nframes);
|
||||
void remove_all_ports ();
|
||||
|
||||
InternalPort* get_internal_port (const std::string& short_name);
|
||||
|
||||
typedef std::pair<std::string,std::string> PortConnection;
|
||||
typedef std::list<PortConnection> PortConnections;
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,13 @@ public:
|
|||
DataType type() const { return _type; }
|
||||
|
||||
bool silent() const { return _silent; }
|
||||
|
||||
/** Reallocate the buffer used internally to handle at least @a size_t units of data.
|
||||
*
|
||||
* The buffer is not silent after this operation. the @a capacity argument
|
||||
* passed to the constructor must have been non-zero.
|
||||
*/
|
||||
virtual void resize(size_t) = 0;
|
||||
|
||||
/** Clear (eg zero, or empty) buffer starting at TIME @a offset */
|
||||
virtual void silence(nframes_t len, nframes_t offset=0) = 0;
|
||||
|
|
|
|||
55
libs/ardour/ardour/internal_audio_port.h
Normal file
55
libs/ardour/ardour/internal_audio_port.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
Copyright (C) 2007 Paul Davis
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: port.h 712 2006-07-28 01:08:57Z drobilla $
|
||||
*/
|
||||
|
||||
#ifndef __ardour_internal_audio_port_h__
|
||||
#define __ardour_internal_audio_port_h__
|
||||
|
||||
#include <sigc++/signal.h>
|
||||
#include <pbd/failed_constructor.h>
|
||||
#include <ardour/ardour.h>
|
||||
#include <ardour/internal_port.h>
|
||||
#include <ardour/audio_port.h>
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
class AudioEngine;
|
||||
class InternalAudioPort : public AudioPort, public InternalPort {
|
||||
public:
|
||||
void cycle_start(nframes_t nframes) {
|
||||
_buffer.silence (nframes);
|
||||
}
|
||||
|
||||
AudioBuffer& get_audio_buffer();
|
||||
|
||||
void set_mixdown_function (void (*func)(const std::list<InternalPort*>&, AudioBuffer&, nframes_t, nframes_t));
|
||||
void reset ();
|
||||
|
||||
protected:
|
||||
friend class AudioEngine;
|
||||
|
||||
InternalAudioPort (const std::string& name, Flags flags);
|
||||
void (*_mixdown)(const std::list<InternalPort*>&, AudioBuffer&, nframes_t, nframes_t);
|
||||
|
||||
static void default_mixdown (const std::list<InternalPort*>&, AudioBuffer&, nframes_t, nframes_t);
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
#endif /* __ardour_internal_audio_port_h__ */
|
||||
82
libs/ardour/ardour/internal_port.h
Normal file
82
libs/ardour/ardour/internal_port.h
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
Copyright (C) 2007 Paul Davis
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __ardour_internal_port_h__
|
||||
#define __ardour_internal_port_h__
|
||||
|
||||
#include <list>
|
||||
|
||||
#include <sigc++/signal.h>
|
||||
#include <pbd/failed_constructor.h>
|
||||
#include <ardour/port.h>
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
class AudioEngine;
|
||||
class Buffer;
|
||||
|
||||
/** Abstract class representing internal (ardour<->ardour only) ports
|
||||
*/
|
||||
class InternalPort : public virtual Port {
|
||||
public:
|
||||
|
||||
~InternalPort();
|
||||
|
||||
std::string short_name();
|
||||
|
||||
int set_name (std::string str);
|
||||
|
||||
int connected () const;
|
||||
|
||||
int reestablish ();
|
||||
|
||||
bool connected_to (const std::string& portname) const;
|
||||
|
||||
const char ** get_connections () const;
|
||||
bool monitoring_input () const { return false; }
|
||||
|
||||
void ensure_monitor_input (bool yn) {}
|
||||
void request_monitor_input (bool yn) {}
|
||||
|
||||
nframes_t latency () const { return _latency; }
|
||||
nframes_t total_latency() const { return _latency; }
|
||||
|
||||
void set_latency (nframes_t nframes);
|
||||
|
||||
static void connect (InternalPort& src, InternalPort& dst);
|
||||
static void disconnect (InternalPort& a, InternalPort& b);
|
||||
|
||||
protected:
|
||||
friend class AudioEngine;
|
||||
|
||||
InternalPort (const std::string&, DataType type, Flags flags);
|
||||
|
||||
int disconnect ();
|
||||
void recompute_total_latency() const;
|
||||
|
||||
std::list<InternalPort*> _connections;
|
||||
nframes_t _latency;
|
||||
|
||||
static AudioEngine* engine;
|
||||
static void set_engine (AudioEngine* e);
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
#endif /* __ardour_internal_port_h__ */
|
||||
|
|
@ -42,6 +42,8 @@ public:
|
|||
bool push_back(const ARDOUR::MidiEvent& event);
|
||||
bool push_back(const jack_midi_event_t& event);
|
||||
Byte* reserve(double time, size_t size);
|
||||
|
||||
void resize(size_t);
|
||||
|
||||
bool merge(const MidiBuffer& a, const MidiBuffer& b);
|
||||
|
||||
|
|
|
|||
|
|
@ -379,6 +379,11 @@ namespace ARDOUR {
|
|||
SrcFastest
|
||||
};
|
||||
|
||||
enum PortType {
|
||||
Jack,
|
||||
Internal
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
std::istream& operator>>(std::istream& o, ARDOUR::SampleFormat& sf);
|
||||
|
|
|
|||
|
|
@ -29,19 +29,13 @@ namespace ARDOUR {
|
|||
|
||||
AudioBuffer::AudioBuffer(size_t capacity)
|
||||
: Buffer(DataType::AUDIO, capacity)
|
||||
, _owns_data(false)
|
||||
, _data(NULL)
|
||||
, _owns_data (false)
|
||||
, _data (0)
|
||||
{
|
||||
_size = capacity; // For audio buffers, size = capacity (always)
|
||||
if (capacity > 0) {
|
||||
#ifdef NO_POSIX_MEMALIGN
|
||||
_data = (Sample *) malloc(sizeof(Sample) * capacity);
|
||||
#else
|
||||
posix_memalign((void**)&_data, CPU_CACHE_ALIGN, sizeof(Sample) * capacity);
|
||||
#endif
|
||||
assert(_data);
|
||||
_owns_data = true;
|
||||
clear();
|
||||
if (_capacity) {
|
||||
_owns_data = true; // prevent resize() from gagging
|
||||
resize (_capacity);
|
||||
silence (_capacity);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -51,6 +45,31 @@ AudioBuffer::~AudioBuffer()
|
|||
free(_data);
|
||||
}
|
||||
|
||||
void
|
||||
AudioBuffer::resize (size_t size)
|
||||
{
|
||||
assert (_owns_data);
|
||||
|
||||
if (size < _capacity) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_data) {
|
||||
free (_data);
|
||||
}
|
||||
|
||||
_capacity = size;
|
||||
_size = size;
|
||||
_silent = false;
|
||||
|
||||
#ifdef NO_POSIX_MEMALIGN
|
||||
_data = (Sample *) malloc(sizeof(Sample) * _capacity);
|
||||
#else
|
||||
posix_memalign((void**)&_data, CPU_CACHE_ALIGN, sizeof(Sample) * _capacity);
|
||||
#endif
|
||||
|
||||
_owns_data = true;
|
||||
}
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,13 @@ AudioPort::AudioPort()
|
|||
reset();
|
||||
}
|
||||
|
||||
AudioPort::AudioPort(nframes_t nframes)
|
||||
: _buffer (nframes)
|
||||
{
|
||||
_type = DataType::AUDIO;
|
||||
reset();
|
||||
}
|
||||
|
||||
void
|
||||
AudioPort::reset()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include <ardour/buffer.h>
|
||||
#include <ardour/port.h>
|
||||
#include <ardour/jack_audio_port.h>
|
||||
#include <ardour/internal_audio_port.h>
|
||||
#include <ardour/jack_midi_port.h>
|
||||
#include <ardour/session.h>
|
||||
#include <ardour/cycle_timer.h>
|
||||
|
|
@ -508,17 +509,33 @@ AudioEngine::remove_session ()
|
|||
}
|
||||
|
||||
Port *
|
||||
AudioEngine::register_port (DataType type, const string& portname, bool input)
|
||||
AudioEngine::register_port (PortType ptype, DataType dtype, const string& portname, bool input)
|
||||
{
|
||||
Port* newport = 0;
|
||||
|
||||
try {
|
||||
if (type == DataType::AUDIO)
|
||||
newport = new JackAudioPort (portname, (input ? Port::IsInput : Port::IsOutput));
|
||||
else if (type == DataType::MIDI)
|
||||
newport = new JackMidiPort (portname, (input ? Port::IsInput : Port::IsOutput));
|
||||
else
|
||||
throw unknown_type();
|
||||
switch (ptype) {
|
||||
case Jack:
|
||||
if (dtype == DataType::AUDIO) {
|
||||
newport = new JackAudioPort (portname, (input ? Port::IsInput : Port::IsOutput));
|
||||
} else if (dtype == DataType::MIDI) {
|
||||
newport = new JackMidiPort (portname, (input ? Port::IsInput : Port::IsOutput));
|
||||
} else {
|
||||
throw unknown_type();
|
||||
}
|
||||
break;
|
||||
|
||||
case Internal:
|
||||
if (dtype == DataType::AUDIO) {
|
||||
newport = new InternalAudioPort (portname, (input ? Port::IsInput : Port::IsOutput));
|
||||
} else if (dtype == DataType::MIDI) {
|
||||
error << _("Internal MIDI ports are not implemented yet!") << endmsg;
|
||||
throw unknown_type();
|
||||
} else {
|
||||
throw unknown_type();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (newport != 0) {
|
||||
RCUWriter<Ports> writer (ports);
|
||||
|
|
@ -535,16 +552,30 @@ AudioEngine::register_port (DataType type, const string& portname, bool input)
|
|||
}
|
||||
}
|
||||
|
||||
Port *
|
||||
AudioEngine::register_input_port (DataType type, const string& portname)
|
||||
InternalPort*
|
||||
AudioEngine::get_internal_port (const std::string& short_name)
|
||||
{
|
||||
return register_port (type, portname, true);
|
||||
boost::shared_ptr<Ports> p = ports.reader();
|
||||
|
||||
for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
|
||||
if ((*i)->short_name() == short_name) {
|
||||
return dynamic_cast<InternalPort*> (*i);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Port *
|
||||
AudioEngine::register_input_port (PortType ptype, DataType type, const string& portname)
|
||||
{
|
||||
return register_port (ptype, type, portname, true);
|
||||
}
|
||||
|
||||
Port *
|
||||
AudioEngine::register_output_port (DataType type, const string& portname)
|
||||
AudioEngine::register_output_port (PortType ptype, DataType type, const string& portname)
|
||||
{
|
||||
return register_port (type, portname, false);
|
||||
return register_port (ptype, type, portname, false);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -565,7 +596,6 @@ AudioEngine::unregister_port (Port& port)
|
|||
for (Ports::iterator i = ps->begin(); i != ps->end(); ++i) {
|
||||
if ((*i) == &port) {
|
||||
remove_connections_for (port);
|
||||
cerr << "eraseing " << (*i)->name() << endl;
|
||||
delete *i;
|
||||
ps->erase (i);
|
||||
break;
|
||||
|
|
@ -581,6 +611,8 @@ AudioEngine::unregister_port (Port& port)
|
|||
int
|
||||
AudioEngine::connect (const string& source, const string& destination)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!_running) {
|
||||
if (!_has_run) {
|
||||
fatal << _("connect called before engine was started") << endmsg;
|
||||
|
|
@ -589,11 +621,26 @@ AudioEngine::connect (const string& source, const string& destination)
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
string s = make_port_name_non_relative (source);
|
||||
string d = make_port_name_non_relative (destination);
|
||||
|
||||
if (source.substr (0, 9) == "internal:") {
|
||||
if (destination.substr (0, 9) == "internal:") {
|
||||
InternalPort* src = get_internal_port (source);
|
||||
InternalPort* dst = get_internal_port (destination);
|
||||
|
||||
int ret = jack_connect (_jack, s.c_str(), d.c_str());
|
||||
InternalPort::connect (*src, *dst);
|
||||
ret = 0;
|
||||
|
||||
} else {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
ret = jack_connect (_jack, s.c_str(), d.c_str());
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
pair<string,string> c (s, d);
|
||||
|
|
@ -614,6 +661,8 @@ AudioEngine::connect (const string& source, const string& destination)
|
|||
int
|
||||
AudioEngine::disconnect (const string& source, const string& destination)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!_running) {
|
||||
if (!_has_run) {
|
||||
fatal << _("disconnect called before engine was started") << endmsg;
|
||||
|
|
@ -626,7 +675,21 @@ AudioEngine::disconnect (const string& source, const string& destination)
|
|||
string s = make_port_name_non_relative (source);
|
||||
string d = make_port_name_non_relative (destination);
|
||||
|
||||
int ret = jack_disconnect (_jack, s.c_str(), d.c_str());
|
||||
if (source.substr (0, 9) == "internal:") {
|
||||
if (destination.substr (0, 9) == "internal:") {
|
||||
InternalPort* src = get_internal_port (source);
|
||||
InternalPort* dst = get_internal_port (destination);
|
||||
|
||||
InternalPort::disconnect (*src, *dst);
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
ret = jack_disconnect (_jack, s.c_str(), d.c_str());
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
pair<string,string> c (s, d);
|
||||
|
|
|
|||
70
libs/ardour/internal_audio_port.cc
Normal file
70
libs/ardour/internal_audio_port.cc
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
Copyright (C) 2006 Paul Davis
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include <ardour/internal_audio_port.h>
|
||||
#include <ardour/audioengine.h>
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace std;
|
||||
|
||||
void
|
||||
InternalAudioPort::default_mixdown (const list<InternalPort*>& ports, AudioBuffer& dest, nframes_t cnt, nframes_t offset)
|
||||
{
|
||||
list<InternalPort*>::const_iterator p = ports.begin();
|
||||
|
||||
dest.read_from ((dynamic_cast<AudioPort*>(*p))->get_audio_buffer(), cnt, offset);
|
||||
|
||||
for (; p != ports.end(); ++p) {
|
||||
dest.accumulate_from ((dynamic_cast<AudioPort*>(*p))->get_audio_buffer(), cnt, offset);
|
||||
}
|
||||
}
|
||||
|
||||
InternalAudioPort::InternalAudioPort(const string& name, Flags flgs)
|
||||
: AudioPort (engine->frames_per_cycle())
|
||||
, InternalPort (name, DataType::AUDIO, flgs)
|
||||
{
|
||||
_mixdown = default_mixdown;
|
||||
}
|
||||
|
||||
void
|
||||
InternalAudioPort::set_mixdown_function (void (*func)(const list<InternalPort*>&, AudioBuffer&, nframes_t, nframes_t))
|
||||
{
|
||||
_mixdown = func;
|
||||
}
|
||||
|
||||
void
|
||||
InternalAudioPort::reset ()
|
||||
{
|
||||
_buffer.resize (engine->frames_per_cycle());
|
||||
_buffer.silence (_buffer.size());
|
||||
}
|
||||
|
||||
AudioBuffer&
|
||||
InternalAudioPort::get_audio_buffer ()
|
||||
{
|
||||
if (_connections.empty()) {
|
||||
return AudioPort::get_audio_buffer();
|
||||
}
|
||||
|
||||
/* XXX what about offset/size being more dynamic ? */
|
||||
|
||||
(*_mixdown) (_connections, _buffer, _buffer.size(), 0);
|
||||
|
||||
return _buffer;
|
||||
}
|
||||
164
libs/ardour/internal_port.cc
Normal file
164
libs/ardour/internal_port.cc
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
Copyright (C) 2007 Paul Davis
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include <pbd/error.h>
|
||||
#include <ardour/internal_port.h>
|
||||
#include <ardour/audioengine.h>
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace std;
|
||||
|
||||
AudioEngine* InternalPort::engine = 0;
|
||||
|
||||
void
|
||||
InternalPort::set_engine (AudioEngine* e)
|
||||
{
|
||||
engine = e;
|
||||
}
|
||||
|
||||
InternalPort::InternalPort (const string& str, DataType type, Flags flags)
|
||||
{
|
||||
set_name (str);
|
||||
_type = type;
|
||||
_flags = flags;
|
||||
}
|
||||
|
||||
InternalPort::~InternalPort ()
|
||||
{
|
||||
disconnect ();
|
||||
}
|
||||
|
||||
void
|
||||
InternalPort::set_latency (nframes_t val)
|
||||
{
|
||||
_latency = val;
|
||||
}
|
||||
|
||||
bool
|
||||
InternalPort::connected_to (const string& portname) const
|
||||
{
|
||||
/* caller must hold process lock */
|
||||
|
||||
for (list<InternalPort*>::const_iterator p = _connections.begin(); p != _connections.end(); ++p) {
|
||||
if ((*p)->name() == portname) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const char**
|
||||
InternalPort::get_connections () const
|
||||
{
|
||||
/* caller must hold process lock */
|
||||
|
||||
int i;
|
||||
list<InternalPort*>::const_iterator p;
|
||||
|
||||
if (_connections.empty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char **names = (char**) malloc (sizeof (char*) * ( _connections.size() + 1));
|
||||
|
||||
|
||||
for (i = 0, p = _connections.begin(); p != _connections.end(); ++p, ++i) {
|
||||
names[i] = (char*) (*p)->name().c_str();
|
||||
}
|
||||
|
||||
names[i] = 0;
|
||||
|
||||
return (const char**) names;
|
||||
}
|
||||
|
||||
int
|
||||
InternalPort::connected() const
|
||||
{
|
||||
/* caller must hold process lock */
|
||||
return !_connections.empty();
|
||||
}
|
||||
|
||||
int
|
||||
InternalPort::set_name (string str)
|
||||
{
|
||||
_name = "internal:";
|
||||
_name += str;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
string
|
||||
InternalPort::short_name ()
|
||||
{
|
||||
return _name.substr (9);
|
||||
}
|
||||
|
||||
void
|
||||
InternalPort::connect (InternalPort& src, InternalPort& dst)
|
||||
{
|
||||
/* caller must hold process lock */
|
||||
|
||||
src._connections.push_back (&dst);
|
||||
dst._connections.push_back (&src);
|
||||
}
|
||||
|
||||
void
|
||||
InternalPort::disconnect (InternalPort& a, InternalPort& b)
|
||||
{
|
||||
/* caller must hold process lock */
|
||||
a._connections.remove (&b);
|
||||
b._connections.remove (&a);
|
||||
}
|
||||
|
||||
int
|
||||
InternalPort::disconnect ()
|
||||
{
|
||||
/* caller must hold process lock */
|
||||
|
||||
for (list<InternalPort*>::const_iterator p = _connections.begin(); p != _connections.end(); ) {
|
||||
list<InternalPort*>::const_iterator tmp;
|
||||
|
||||
tmp = p;
|
||||
++tmp;
|
||||
|
||||
disconnect (*this, **p);
|
||||
|
||||
p = tmp;
|
||||
}
|
||||
|
||||
_connections.clear ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
InternalPort::reestablish ()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
InternalPort::recompute_total_latency () const
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -602,7 +602,7 @@ IO::add_output_port (string destination, void* src, DataType type)
|
|||
snprintf (name, sizeof (name), _("%s/out %u"), _name.c_str(), find_output_port_hole());
|
||||
}
|
||||
|
||||
if ((our_port = _session.engine().register_output_port (type, name)) == 0) {
|
||||
if ((our_port = _session.engine().register_output_port (Jack, type, name)) == 0) {
|
||||
error << string_compose(_("IO: cannot register output port %1"), name) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -713,7 +713,7 @@ IO::add_input_port (string source, void* src, DataType type)
|
|||
snprintf (name, sizeof (name), _("%s/in %u"), _name.c_str(), find_input_port_hole());
|
||||
}
|
||||
|
||||
if ((our_port = _session.engine().register_input_port (type, name)) == 0) {
|
||||
if ((our_port = _session.engine().register_input_port (Jack, type, name)) == 0) {
|
||||
error << string_compose(_("IO: cannot register input port %1"), name) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -822,7 +822,7 @@ IO::ensure_inputs_locked (ChanCount count, bool clear, void* src)
|
|||
|
||||
try {
|
||||
|
||||
if ((input_port = _session.engine().register_input_port (*t, buf)) == 0) {
|
||||
if ((input_port = _session.engine().register_input_port (Jack, *t, buf)) == 0) {
|
||||
error << string_compose(_("IO: cannot register input port %1"), buf) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -938,7 +938,7 @@ IO::ensure_io (ChanCount in, ChanCount out, bool clear, void* src)
|
|||
}
|
||||
|
||||
try {
|
||||
if ((port = _session.engine().register_input_port (*t, buf)) == 0) {
|
||||
if ((port = _session.engine().register_input_port (Jack, *t, buf)) == 0) {
|
||||
error << string_compose(_("IO: cannot register input port %1"), buf) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -970,7 +970,7 @@ IO::ensure_io (ChanCount in, ChanCount out, bool clear, void* src)
|
|||
}
|
||||
|
||||
try {
|
||||
if ((port = _session.engine().register_output_port (*t, buf)) == 0) {
|
||||
if ((port = _session.engine().register_output_port (Jack, *t, buf)) == 0) {
|
||||
error << string_compose(_("IO: cannot register output port %1"), buf) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1090,7 +1090,7 @@ IO::ensure_outputs_locked (ChanCount count, bool clear, void* src)
|
|||
snprintf (buf, sizeof (buf), _("%s/out %u"), _name.c_str(), find_output_port_hole());
|
||||
}
|
||||
|
||||
if ((output_port = _session.engine().register_output_port (*t, buf)) == 0) {
|
||||
if ((output_port = _session.engine().register_output_port (Jack, *t, buf)) == 0) {
|
||||
error << string_compose(_("IO: cannot register output port %1"), buf) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,3 +109,4 @@ JackPort::recompute_total_latency () const
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -38,20 +38,31 @@ MidiBuffer::MidiBuffer(size_t capacity)
|
|||
, _events(NULL)
|
||||
, _data(NULL)
|
||||
{
|
||||
assert(capacity > 0);
|
||||
_data = 0;
|
||||
resize (_capacity);
|
||||
silence(_capacity);
|
||||
}
|
||||
|
||||
void
|
||||
MidiBuffer::resize (size_t size)
|
||||
{
|
||||
assert(size > 0);
|
||||
|
||||
if (_data) {
|
||||
free (_data);
|
||||
}
|
||||
|
||||
_size = 0;
|
||||
|
||||
_capacity = size;
|
||||
#ifdef NO_POSIX_MEMALIGN
|
||||
_events = (MidiEvent *) malloc(sizeof(MidiEvent) * capacity);
|
||||
_data = (Byte *) malloc(sizeof(Byte) * capacity * MAX_EVENT_SIZE);
|
||||
_events = (MidiEvent *) malloc(sizeof(MidiEvent) * _capacity);
|
||||
_data = (Byte *) malloc(sizeof(Byte) * _capacity * MAX_EVENT_SIZE);
|
||||
#else
|
||||
posix_memalign((void**)&_events, CPU_CACHE_ALIGN, sizeof(MidiEvent) * capacity);
|
||||
posix_memalign((void**)&_data, CPU_CACHE_ALIGN, sizeof(Byte) * capacity * MAX_EVENT_SIZE);
|
||||
posix_memalign((void**)&_events, CPU_CACHE_ALIGN, sizeof(MidiEvent) * _capacity);
|
||||
posix_memalign((void**)&_data, CPU_CACHE_ALIGN, sizeof(Byte) * _capacity * MAX_EVENT_SIZE);
|
||||
#endif
|
||||
assert(_data);
|
||||
assert(_events);
|
||||
silence(_capacity);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue