fix merge conflicts with master

This commit is contained in:
Paul Davis
2013-09-14 16:42:40 -04:00
213 changed files with 29641 additions and 21838 deletions

View File

@@ -75,9 +75,7 @@ namespace ARDOUR {
bool translations_are_enabled ();
bool set_translations_enabled (bool);
static inline microseconds_t get_microseconds () {
return (microseconds_t) jack_get_time();
}
microseconds_t get_microseconds ();
void setup_fpu ();
std::vector<SyncSource> get_available_sync_options();

View File

@@ -16,14 +16,12 @@
*/
#ifndef __libmidi_port_h__
#define __libmidi_port_h__
#ifndef __libardour_async_midiport_h__
#define __libardour_async_midiport_h__
#include <string>
#include <iostream>
#include <jack/types.h>
#include "pbd/xml++.h"
#include "pbd/crossthread.h"
#include "pbd/signals.h"
@@ -36,68 +34,46 @@
#include "midi++/parser.h"
#include "midi++/port.h"
namespace MIDI {
#include "ardour/midi_port.h"
class Channel;
class PortRequest;
namespace ARDOUR {
class AsyncMIDIPort : public ARDOUR::MidiPort, public MIDI::Port {
class JackMIDIPort : public Port {
public:
JackMIDIPort (std::string const &, Port::Flags, jack_client_t *);
JackMIDIPort (const XMLNode&, jack_client_t *);
~JackMIDIPort ();
AsyncMIDIPort (std::string const &, PortFlags);
~AsyncMIDIPort ();
XMLNode& get_state () const;
void set_state (const XMLNode&);
/* called from an RT context */
void cycle_start (pframes_t nframes);
void cycle_end ();
void cycle_end (pframes_t nframes);
/* called from non-RT context */
void parse (framecnt_t timestamp);
int write (const byte *msg, size_t msglen, timestamp_t timestamp);
int read (byte *buf, size_t bufsize);
int write (const MIDI::byte *msg, size_t msglen, MIDI::timestamp_t timestamp);
int read (MIDI::byte *buf, size_t bufsize);
void drain (int check_interval_usecs);
int selectable () const { return xthread.selectable(); }
pframes_t nframes_this_cycle() const { return _nframes_this_cycle; }
void reestablish (jack_client_t *);
void reconnect ();
static void set_process_thread (pthread_t);
static pthread_t get_process_thread () { return _process_thread; }
static bool is_process_thread();
static PBD::Signal0<void> MakeConnections;
static PBD::Signal0<void> JackHalted;
private:
bool _currently_in_cycle;
pframes_t _nframes_this_cycle;
jack_client_t* _jack_client;
jack_port_t* _jack_port;
timestamp_t _last_write_timestamp;
private:
bool _currently_in_cycle;
MIDI::timestamp_t _last_write_timestamp;
RingBuffer< Evoral::Event<double> > output_fifo;
Evoral::EventRingBuffer<timestamp_t> input_fifo;
Glib::Threads::Mutex output_fifo_lock;
CrossThreadChannel xthread;
Evoral::EventRingBuffer<MIDI::timestamp_t> input_fifo;
Glib::Threads::Mutex output_fifo_lock;
CrossThreadChannel xthread;
int create_port ();
/** Channel used to signal to the MidiControlUI that input has arrived */
std::string _connections;
PBD::ScopedConnection connect_connection;
PBD::ScopedConnection halt_connection;
void flush (void* jack_port_buffer);
void jack_halted ();
void make_connections ();
void init (std::string const &, Flags);
void flush_output_fifo (pframes_t);
static pthread_t _process_thread;
};
} // namespace MIDI
} // namespace ARDOUR
#endif // __libmidi_port_h__
#endif /* __libardour_async_midiport_h__ */

View File

@@ -0,0 +1,444 @@
/*
Copyright (C) 2013 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 __libardour_audiobackend_h__
#define __libardour_audiobackend_h__
#include <string>
#include <vector>
#include <stdint.h>
#include <stdlib.h>
#include <boost/function.hpp>
#include "ardour/types.h"
#include "ardour/audioengine.h"
#include "ardour/port_engine.h"
#include "ardour/visibility.h"
#ifdef ARDOURBACKEND_DLL_EXPORTS // defined if we are building the ARDOUR Panners DLLs (instead of using them)
#define ARDOURBACKEND_API LIBARDOUR_HELPER_DLL_EXPORT
#else
#define ARDOURBACKEND_API LIBARDOUR_HELPER_DLL_IMPORT
#endif
#define ARDOURBACKEND_LOCAL LIBARDOUR_HELPER_DLL_LOCAL
namespace ARDOUR {
class AudioBackend : public PortEngine {
public:
AudioBackend (AudioEngine& e) : PortEngine (e), engine (e) {}
virtual ~AudioBackend () {}
/** Return the name of this backend.
*
* Should use a well-known, unique term. Expected examples
* might include "JACK", "CoreAudio", "ASIO" etc.
*/
virtual std::string name() const = 0;
/** Return true if the callback from the underlying mechanism/API
* (CoreAudio, JACK, ASIO etc.) occurs in a thread subject to realtime
* constraints. Return false otherwise.
*/
virtual bool is_realtime () const = 0;
/* Discovering devices and parameters */
/** Return true if this backend requires the selection of a "driver"
* before any device can be selected. Return false otherwise.
*
* Intended mainly to differentiate between meta-APIs like JACK
* which can still expose different backends (such as ALSA or CoreAudio
* or FFADO or netjack) and those like ASIO or CoreAudio which
* do not.
*/
virtual bool requires_driver_selection() const { return false; }
/** If the return value of requires_driver_selection() is true,
* then this function can return the list of known driver names.
*
* If the return value of requires_driver_selection() is false,
* then this function should not be called. If it is called
* its return value is an empty vector of strings.
*/
virtual std::vector<std::string> enumerate_drivers() const { return std::vector<std::string>(); }
/** Returns zero if the backend can successfully use @param name as the
* driver, non-zero otherwise.
*
* Should not be used unless the backend returns true from
* requires_driver_selection()
*/
virtual int set_driver (const std::string& /*drivername*/) { return 0; }
/** used to list device names along with whether or not they are currently
* available.
*/
struct DeviceStatus {
std::string name;
bool available;
DeviceStatus (const std::string& s, bool avail) : name (s), available (avail) {}
};
/** Returns a collection of DeviceStatuses identifying devices discovered
* by this backend since the start of the process.
*
* Any of the names in each DeviceStatus may be used to identify a
* device in other calls to the backend, though any of them may become
* invalid at any time.
*/
virtual std::vector<DeviceStatus> enumerate_devices () const = 0;
/** Returns a collection of float identifying sample rates that are
* potentially usable with the hardware identified by @param device.
* Any of these values may be supplied in other calls to this backend
* as the desired sample rate to use with the name device, but the
* requested sample rate may turn out to be unavailable, or become invalid
* at any time.
*/
virtual std::vector<float> available_sample_rates (const std::string& device) const = 0;
/** Returns a collection of uint32 identifying buffer sizes that are
* potentially usable with the hardware identified by @param device.
* Any of these values may be supplied in other calls to this backend
* as the desired buffer size to use with the name device, but the
* requested buffer size may turn out to be unavailable, or become invalid
* at any time.
*/
virtual std::vector<uint32_t> available_buffer_sizes (const std::string& device) const = 0;
/** Returns the maximum number of input channels that are potentially
* usable with the hardware identified by @param device. Any number from 1
* to the value returned may be supplied in other calls to this backend as
* the input channel count to use with the name device, but the requested
* count may turn out to be unavailable, or become invalid at any time.
*/
virtual uint32_t available_input_channel_count (const std::string& device) const = 0;
/** Returns the maximum number of output channels that are potentially
* usable with the hardware identified by @param device. Any number from 1
* to the value returned may be supplied in other calls to this backend as
* the output channel count to use with the name device, but the requested
* count may turn out to be unavailable, or become invalid at any time.
*/
virtual uint32_t available_output_channel_count (const std::string& device) const = 0;
/* Return true if the derived class can change the sample rate of the
* device in use while the device is already being used. Return false
* otherwise. (example: JACK cannot do this as of September 2013)
*/
virtual bool can_change_sample_rate_when_running () const = 0;
/* Return true if the derived class can change the buffer size of the
* device in use while the device is already being used. Return false
* otherwise.
*/
virtual bool can_change_buffer_size_when_running () const = 0;
/* Set the hardware parameters.
*
* If called when the current state is stopped or paused,
* the changes will not take effect until the state changes to running.
*
* If called while running, the state will change as fast as the
* implementation allows.
*
* All set_*() methods return zero on success, non-zero otherwise.
*/
/** Set the name of the device to be used
*/
virtual int set_device_name (const std::string&) = 0;
/** Set the sample rate to be used
*/
virtual int set_sample_rate (float) = 0;
/** Set the buffer size to be used.
*
* The device is assumed to use a double buffering scheme, so that one
* buffer's worth of data can be processed by hardware while software works
* on the other buffer. All known suitable audio APIs support this model
* (though ALSA allows for alternate numbers of buffers, and CoreAudio
* doesn't directly expose the concept).
*/
virtual int set_buffer_size (uint32_t) = 0;
/** Set the preferred underlying hardware sample format
*
* This does not change the sample format (32 bit float) read and
* written to the device via the Port API.
*/
virtual int set_sample_format (SampleFormat) = 0;
/** Set the preferred underlying hardware data layout.
* If @param yn is true, then the hardware will interleave
* samples for successive channels; otherwise, the hardware will store
* samples for a single channel contiguously.
*
* Setting this does not change the fact that all data streams
* to and from Ports are mono (essentially, non-interleaved)
*/
virtual int set_interleaved (bool yn) = 0;
/** Set the number of input channels that should be used
*/
virtual int set_input_channels (uint32_t) = 0;
/** Set the number of output channels that should be used
*/
virtual int set_output_channels (uint32_t) = 0;
/** Set the (additional) input latency that cannot be determined via
* the implementation's underlying code (e.g. latency from
* external D-A/D-A converters. Units are samples.
*/
virtual int set_systemic_input_latency (uint32_t) = 0;
/** Set the (additional) output latency that cannot be determined via
* the implementation's underlying code (e.g. latency from
* external D-A/D-A converters. Units are samples.
*/
virtual int set_systemic_output_latency (uint32_t) = 0;
/* Retrieving parameters */
virtual std::string device_name () const = 0;
virtual float sample_rate () const = 0;
virtual uint32_t buffer_size () const = 0;
virtual SampleFormat sample_format () const = 0;
virtual bool interleaved () const = 0;
virtual uint32_t input_channels () const = 0;
virtual uint32_t output_channels () const = 0;
virtual uint32_t systemic_input_latency () const = 0;
virtual uint32_t systemic_output_latency () const = 0;
/** Return the name of a control application for the
* selected/in-use device. If no such application exists,
* or if no device has been selected or is in-use,
* return an empty string.
*/
virtual std::string control_app_name() const = 0;
/** Launch the control app for the currently in-use or
* selected device. May do nothing if the control
* app is undefined or cannot be launched.
*/
virtual void launch_control_app () = 0;
/* Basic state control */
/** Start using the device named in the most recent call
* to set_device(), with the parameters set by various
* the most recent calls to set_sample_rate() etc. etc.
*
* At some undetermined time after this function is successfully called,
* the backend will start calling the ::process_callback() method of
* the AudioEngine referenced by @param engine. These calls will
* occur in a thread created by and/or under the control of the backend.
*
* Return zero if successful, negative values otherwise.
*/
virtual int start () = 0;
/** Stop using the device currently in use.
*
* If the function is successfully called, no subsequent calls to the
* process_callback() of @param engine will be made after the function
* returns, until parameters are reset and start() are called again.
*
* The backend is considered to be un-configured after a successful
* return, and requires calls to set hardware parameters before it can be
* start()-ed again. See pause() for a way to avoid this. stop() should
* only be used when reconfiguration is required OR when there are no
* plans to use the backend in the future with a reconfiguration.
*
* Return zero if successful, 1 if the device is not in use, negative values on error
*/
virtual int stop () = 0;
/** Temporarily cease using the device named in the most recent call to set_parameters().
*
* If the function is successfully called, no subsequent calls to the
* process_callback() of @param engine will be made after the function
* returns, until start() is called again.
*
* The backend will retain its existing parameter configuration after a successful
* return, and does NOT require any calls to set hardware parameters before it can be
* start()-ed again.
*
* Return zero if successful, 1 if the device is not in use, negative values on error
*/
virtual int pause () = 0;
/** While remaining connected to the device, and without changing its
* configuration, start (or stop) calling the process_callback() of @param engine
* without waiting for the device. Once process_callback() has returned, it
* will be called again immediately, thus allowing for faster-than-realtime
* processing.
*
* All registered ports remain in existence and all connections remain
* unaltered. However, any physical ports should NOT be used by the
* process_callback() during freewheeling - the data behaviour is undefined.
*
* If @param start_stop is true, begin this behaviour; otherwise cease this
* behaviour if it currently occuring, and return to calling
* process_callback() of @param engine by waiting for the device.
*
* Return zero on success, non-zero otherwise.
*/
virtual int freewheel (bool start_stop) = 0;
/** return the fraction of the time represented by the current buffer
* size that is being used for each buffer process cycle, as a value
* from 0.0 to 1.0
*
* E.g. if the buffer size represents 5msec and current processing
* takes 1msec, the returned value should be 0.2.
*
* Implementations can feel free to smooth the values returned over
* time (e.g. high pass filtering, or its equivalent).
*/
virtual float cpu_load() const = 0;
/* Transport Control (JACK is the only audio API that currently offers
the concept of shared transport control)
*/
/** Attempt to change the transport state to TransportRolling.
*/
virtual void transport_start () {}
/** Attempt to change the transport state to TransportStopped.
*/
virtual void transport_stop () {}
/** return the current transport state
*/
virtual TransportState transport_state () const { return TransportStopped; }
/** Attempt to locate the transport to @param pos
*/
virtual void transport_locate (framepos_t /*pos*/) {}
/** Return the current transport location, in samples measured
* from the origin (defined by the transport time master)
*/
virtual framepos_t transport_frame() const { return 0; }
/** If @param yn is true, become the time master for any inter-application transport
* timebase, otherwise cease to be the time master for the same.
*
* Return zero on success, non-zero otherwise
*
* JACK is the only currently known audio API with the concept of a shared
* transport timebase.
*/
virtual int set_time_master (bool /*yn*/) { return 0; }
virtual int usecs_per_cycle () const { return 1000000 * (buffer_size() / sample_rate()); }
virtual size_t raw_buffer_size (DataType t) = 0;
/* Process time */
/** return the time according to the sample clock in use, measured in
* samples since an arbitrary zero time in the past. The value should
* increase monotonically and linearly, without interruption from any
* source (including CPU frequency scaling).
*
* It is extremely likely that any implementation will use a DLL, since
* this function can be called from any thread, at any time, and must be
* able to accurately determine the correct sample time.
*
* Can be called from any thread.
*/
virtual pframes_t sample_time () = 0;
/** Return the time according to the sample clock in use when the most
* recent buffer process cycle began. Can be called from any thread.
*/
virtual pframes_t sample_time_at_cycle_start () = 0;
/** Return the time since the current buffer process cycle started,
* in samples, according to the sample clock in use.
*
* Can ONLY be called from within a process() callback tree (which
* implies that it can only be called by a process thread)
*/
virtual pframes_t samples_since_cycle_start () = 0;
/** Return true if it possible to determine the offset in samples of the
* first video frame that starts within the current buffer process cycle,
* measured from the first sample of the cycle. If returning true,
* set @param offset to that offset.
*
* Eg. if it can be determined that the first video frame within the cycle
* starts 28 samples after the first sample of the cycle, then this method
* should return true and set @param offset to 28.
*
* May be impossible to support outside of JACK, which has specific support
* (in some cases, hardware support) for this feature.
*
* Can ONLY be called from within a process() callback tree (which implies
* that it can only be called by a process thread)
*/
virtual bool get_sync_offset (pframes_t& /*offset*/) const { return false; }
/** Create a new thread suitable for running part of the buffer process
* cycle (i.e. Realtime scheduling, memory allocation, etc. etc are all
* correctly setup), with a stack size given in bytes by specified @param
* stacksize. The thread will begin executing @param func, and will exit
* when that function returns.
*/
virtual int create_process_thread (boost::function<void()> func, AudioBackendNativeThread*, size_t stacksize) = 0;
/** Wait for the thread specified by @param thread to exit.
*
* Return zero on success, non-zero on failure.
*/
virtual int wait_for_process_thread_exit (AudioBackendNativeThread thread) = 0;
virtual void update_latencies () = 0;
protected:
AudioEngine& engine;
};
struct AudioBackendInfo {
const char* name;
/** Using arg1 and arg2, initialize this audiobackend.
*
* Returns zero on success, non-zero otherwise.
*/
int (*instantiate) (const std::string& arg1, const std::string& arg2);
/** Release all resources associated with this audiobackend
*/
int (*deinstantiate) (void);
/** Factory method to create an AudioBackend-derived class.
*
* Returns a valid shared_ptr to the object if successfull,
* or a "null" shared_ptr otherwise.
*/
boost::shared_ptr<AudioBackend> (*factory) (AudioEngine&);
/** Return true if the underlying mechanism/API has been
* configured and does not need (re)configuration in order
* to be usable. Return false otherwise.
*
* Note that this may return true if (re)configuration, even though
* not currently required, is still possible.
*/
bool (*already_configured)();
};
} // namespace
#endif /* __libardour_audiobackend_h__ */

View File

@@ -114,7 +114,7 @@ class AudioDiskstream : public Diskstream
XMLNode& get_state(void);
int set_state(const XMLNode& node, int version);
void request_jack_monitors_input (bool);
void request_input_monitoring (bool);
static void swap_by_ptr (Sample *first, Sample *last) {
while (first < last) {
@@ -160,7 +160,7 @@ class AudioDiskstream : public Diskstream
std::string name;
bool is_physical () const;
void request_jack_monitors_input (bool) const;
void request_input_monitoring (bool) const;
};
/** Information about one of our channels */

View File

@@ -46,10 +46,10 @@ class AudioPort : public Port
AudioBuffer& get_audio_buffer (pframes_t nframes);
protected:
friend class AudioEngine;
friend class PortManager;
AudioPort (std::string const &, PortFlags);
AudioPort (std::string const &, Flags);
/* special access for engine only */
/* special access for PortManager only (hah, C++) */
Sample* engine_get_whole_audio_buffer ();
private:

View File

@@ -33,26 +33,22 @@
#include <glibmm/threads.h>
#include "pbd/rcu.h"
#include "pbd/signals.h"
#include "pbd/stacktrace.h"
#include <jack/weakjack.h>
#include <jack/jack.h>
#include <jack/transport.h>
#include <jack/thread.h>
#include "ardour/ardour.h"
#include "ardour/data_type.h"
#include "ardour/session_handle.h"
#include "ardour/types.h"
#include "ardour/chan_count.h"
#include "ardour/port_manager.h"
#ifdef HAVE_JACK_SESSION
#include <jack/session.h>
#endif
class MTDM;
namespace ARDOUR {
class InternalPort;
@@ -60,299 +56,191 @@ class MidiPort;
class Port;
class Session;
class ProcessThread;
class AudioBackend;
class AudioBackendInfo;
class AudioEngine : public SessionHandlePtr
class AudioEngine : public SessionHandlePtr, public PortManager
{
public:
typedef std::map<std::string,boost::shared_ptr<Port> > Ports;
AudioEngine (std::string client_name, std::string session_uuid);
virtual ~AudioEngine ();
jack_client_t* jack() const;
bool connected() const { return _jack != 0; }
bool is_realtime () const;
ProcessThread* main_thread() const { return _main_thread; }
std::string client_name() const { return jack_client_name; }
int reconnect_to_jack ();
int disconnect_from_jack();
int stop (bool forever = false);
int start ();
bool running() const { return _running; }
Glib::Threads::Mutex& process_lock() { return _process_lock; }
framecnt_t frame_rate () const;
pframes_t frames_per_cycle () const;
size_t raw_buffer_size(DataType t);
int usecs_per_cycle () const { return _usecs_per_cycle; }
bool get_sync_offset (pframes_t & offset) const;
pframes_t frames_since_cycle_start () {
jack_client_t* _priv_jack = _jack;
if (!_running || !_priv_jack) {
return 0;
}
return jack_frames_since_cycle_start (_priv_jack);
}
pframes_t frame_time () {
jack_client_t* _priv_jack = _jack;
if (!_running || !_priv_jack) {
return 0;
}
return jack_frame_time (_priv_jack);
}
pframes_t frame_time_at_cycle_start () {
jack_client_t* _priv_jack = _jack;
if (!_running || !_priv_jack) {
return 0;
}
return jack_last_frame_time (_priv_jack);
}
pframes_t transport_frame () const {
const jack_client_t* _priv_jack = _jack;
if (!_running || !_priv_jack) {
return 0;
}
return jack_get_current_transport_frame (_priv_jack);
}
int request_buffer_size (pframes_t);
framecnt_t processed_frames() const { return _processed_frames; }
float get_cpu_load() {
jack_client_t* _priv_jack = _jack;
if (!_running || !_priv_jack) {
return 0;
}
return jack_cpu_load (_priv_jack);
}
void set_session (Session *);
void remove_session (); // not a replacement for SessionHandle::session_going_away()
class PortRegistrationFailure : public std::exception {
public:
PortRegistrationFailure (std::string const & why = "")
: reason (why) {}
~PortRegistrationFailure () throw () {}
virtual const char *what() const throw () { return reason.c_str(); }
private:
std::string reason;
};
class NoBackendAvailable : public std::exception {
public:
virtual const char *what() const throw() { return "could not connect to engine backend"; }
};
boost::shared_ptr<Port> register_input_port (DataType, const std::string& portname);
boost::shared_ptr<Port> register_output_port (DataType, const std::string& portname);
int unregister_port (boost::shared_ptr<Port>);
bool port_is_physical (const std::string&) const;
void request_jack_monitors_input (const std::string&, bool) const;
void split_cycle (pframes_t offset);
int connect (const std::string& source, const std::string& destination);
int disconnect (const std::string& source, const std::string& destination);
int disconnect (boost::shared_ptr<Port>);
const char ** get_ports (const std::string& port_name_pattern, const std::string& type_name_pattern, uint32_t flags);
bool can_request_hardware_monitoring ();
ChanCount n_physical_outputs () const;
ChanCount n_physical_inputs () const;
void get_physical_outputs (DataType type, std::vector<std::string>&);
void get_physical_inputs (DataType type, std::vector<std::string>&);
boost::shared_ptr<Port> get_port_by_name (const std::string &);
void port_renamed (const std::string&, const std::string&);
enum TransportState {
TransportStopped = JackTransportStopped,
TransportRolling = JackTransportRolling,
TransportLooping = JackTransportLooping,
TransportStarting = JackTransportStarting
};
void transport_start ();
void transport_stop ();
void transport_locate (framepos_t);
TransportState transport_state ();
int reset_timebase ();
void update_latencies ();
/* start/stop freewheeling */
int freewheel (bool onoff);
bool freewheeling() const { return _freewheeling; }
/* this signal is sent for every process() cycle while freewheeling.
_ the regular process() call to session->process() is not made.
*/
PBD::Signal1<int, pframes_t> Freewheel;
PBD::Signal0<void> Xrun;
/* this signal is if JACK notifies us of a graph order event */
PBD::Signal0<void> GraphReordered;
#ifdef HAVE_JACK_SESSION
PBD::Signal1<void,jack_session_event_t *> JackSessionEvent;
#endif
/* this signal is emitted if the sample rate changes */
PBD::Signal1<void, framecnt_t> SampleRateChanged;
/* this signal is sent if JACK ever disconnects us */
PBD::Signal1<void,const char*> Halted;
/* these two are emitted when the engine itself is
started and stopped
*/
PBD::Signal0<void> Running;
PBD::Signal0<void> Stopped;
/** Emitted if a JACK port is registered or unregistered */
PBD::Signal0<void> PortRegisteredOrUnregistered;
/** Emitted if a JACK port is connected or disconnected.
* The Port parameters are the ports being connected / disconnected, or 0 if they are not known to Ardour.
* The std::string parameters are the (long) port names.
* The bool parameter is true if ports were connected, or false for disconnected.
*/
PBD::Signal5<void, boost::weak_ptr<Port>, std::string, boost::weak_ptr<Port>, std::string, bool> PortConnectedOrDisconnected;
std::string make_port_name_relative (std::string) const;
std::string make_port_name_non_relative (std::string) const;
bool port_is_mine (const std::string&) const;
static AudioEngine* instance() { return _instance; }
static void destroy();
void died ();
int create_process_thread (boost::function<void()>, pthread_t*, size_t stacksize);
private:
static AudioEngine* _instance;
jack_client_t* volatile _jack; /* could be reset to null by SIGPIPE or another thread */
std::string jack_client_name;
Glib::Threads::Mutex _process_lock;
Glib::Threads::Cond session_removed;
bool session_remove_pending;
frameoffset_t session_removal_countdown;
gain_t session_removal_gain;
gain_t session_removal_gain_step;
bool _running;
bool _has_run;
mutable framecnt_t _buffer_size;
std::map<DataType,size_t> _raw_buffer_sizes;
mutable framecnt_t _frame_rate;
/// number of frames between each check for changes in monitor input
framecnt_t monitor_check_interval;
/// time of the last monitor check in frames
framecnt_t last_monitor_check;
/// the number of frames processed since start() was called
framecnt_t _processed_frames;
bool _freewheeling;
bool _pre_freewheel_mmc_enabled;
int _usecs_per_cycle;
bool port_remove_in_progress;
Glib::Threads::Thread* m_meter_thread;
ProcessThread* _main_thread;
SerializedRCUManager<Ports> ports;
boost::shared_ptr<Port> register_port (DataType type, const std::string& portname, bool input);
int process_callback (pframes_t nframes);
void* process_thread ();
void remove_all_ports ();
ChanCount n_physical (unsigned long) const;
void get_physical (DataType, unsigned long, std::vector<std::string> &);
void port_registration_failure (const std::string& portname);
static int _xrun_callback (void *arg);
#ifdef HAVE_JACK_SESSION
static void _session_callback (jack_session_event_t *event, void *arg);
#endif
static int _graph_order_callback (void *arg);
static void* _process_thread (void *arg);
static int _sample_rate_callback (pframes_t nframes, void *arg);
static int _bufsize_callback (pframes_t nframes, void *arg);
static void _jack_timebase_callback (jack_transport_state_t, pframes_t, jack_position_t*, int, void*);
static int _jack_sync_callback (jack_transport_state_t, jack_position_t*, void *arg);
static void _freewheel_callback (int , void *arg);
static void _registration_callback (jack_port_id_t, int, void *);
static void _connect_callback (jack_port_id_t, jack_port_id_t, int, void *);
void jack_timebase_callback (jack_transport_state_t, pframes_t, jack_position_t*, int);
int jack_sync_callback (jack_transport_state_t, jack_position_t*);
int jack_bufsize_callback (pframes_t);
int jack_sample_rate_callback (pframes_t);
void freewheel_callback (int);
void connect_callback (jack_port_id_t, jack_port_id_t, int);
void set_jack_callbacks ();
static void _latency_callback (jack_latency_callback_mode_t, void*);
void jack_latency_callback (jack_latency_callback_mode_t);
int connect_to_jack (std::string client_name, std::string session_uuid);
static void halted (void *);
static void halted_info (jack_status_t,const char*,void *);
void meter_thread ();
void start_metering_thread ();
void stop_metering_thread ();
static gint m_meter_exit;
struct ThreadData {
AudioEngine* engine;
boost::function<void()> f;
size_t stacksize;
ThreadData (AudioEngine* ae, boost::function<void()> fp, size_t stacksz)
: engine (ae) , f (fp) , stacksize (stacksz) {}
};
static void* _start_process_thread (void*);
void parameter_changed (const std::string&);
PBD::ScopedConnection config_connection;
static AudioEngine* create ();
virtual ~AudioEngine ();
int discover_backends();
std::vector<const AudioBackendInfo*> available_backends() const;
std::string current_backend_name () const;
boost::shared_ptr<AudioBackend> set_backend (const std::string&, const std::string& arg1, const std::string& arg2);
boost::shared_ptr<AudioBackend> current_backend() const { return _backend; }
bool setup_required () const;
ProcessThread* main_thread() const { return _main_thread; }
/* START BACKEND PROXY API
*
* See audio_backend.h for full documentation and semantics. These wrappers
* just forward to a backend implementation.
*/
int start ();
int stop ();
int pause ();
int freewheel (bool start_stop);
float get_cpu_load() const ;
void transport_start ();
void transport_stop ();
TransportState transport_state ();
void transport_locate (framepos_t pos);
framepos_t transport_frame();
framecnt_t sample_rate () const;
pframes_t samples_per_cycle () const;
int usecs_per_cycle () const;
size_t raw_buffer_size (DataType t);
pframes_t sample_time ();
pframes_t sample_time_at_cycle_start ();
pframes_t samples_since_cycle_start ();
bool get_sync_offset (pframes_t& offset) const;
int create_process_thread (boost::function<void()> func, AudioBackendNativeThread*, size_t stacksize);
int wait_for_process_thread_exit (AudioBackendNativeThread);
bool is_realtime() const;
bool connected() const;
int set_device_name (const std::string&);
int set_sample_rate (float);
int set_buffer_size (uint32_t);
int set_sample_format (SampleFormat);
int set_interleaved (bool yn);
int set_input_channels (uint32_t);
int set_output_channels (uint32_t);
int set_systemic_input_latency (uint32_t);
int set_systemic_output_latency (uint32_t);
/* END BACKEND PROXY API */
bool freewheeling() const { return _freewheeling; }
bool running() const { return _running; }
Glib::Threads::Mutex& process_lock() { return _process_lock; }
int request_buffer_size (pframes_t samples) {
return set_buffer_size (samples);
}
framecnt_t processed_frames() const { return _processed_frames; }
void set_session (Session *);
void remove_session (); // not a replacement for SessionHandle::session_going_away()
Session* session() const { return _session; }
class NoBackendAvailable : public std::exception {
public:
virtual const char *what() const throw() { return "could not connect to engine backend"; }
};
void split_cycle (pframes_t offset);
int reset_timebase ();
void update_latencies ();
/* this signal is sent for every process() cycle while freewheeling.
(the regular process() call to session->process() is not made)
*/
PBD::Signal1<int, pframes_t> Freewheel;
PBD::Signal0<void> Xrun;
/* this signal is emitted if the sample rate changes */
PBD::Signal1<void, framecnt_t> SampleRateChanged;
/* this signal is sent if the backend ever disconnects us */
PBD::Signal1<void,const char*> Halted;
/* these two are emitted when the engine itself is
started and stopped
*/
PBD::Signal0<void> Running;
PBD::Signal0<void> Stopped;
static AudioEngine* instance() { return _instance; }
static void destroy();
void died ();
/* The backend will cause these at the appropriate time(s)
*/
int process_callback (pframes_t nframes);
int buffer_size_change (pframes_t nframes);
int sample_rate_change (pframes_t nframes);
void freewheel_callback (bool);
void timebase_callback (TransportState state, pframes_t nframes, framepos_t pos, int new_position);
int sync_callback (TransportState state, framepos_t position);
int port_registration_callback ();
void latency_callback (bool for_playback);
void halted_callback (const char* reason);
/* sets up the process callback thread */
static void thread_init_callback (void *);
/* latency measurement */
MTDM* mtdm();
int prepare_for_latency_measurement ();
void start_latency_detection ();
void stop_latency_detection ();
void set_latency_input_port (const std::string&);
void set_latency_output_port (const std::string&);
uint32_t latency_signal_delay () const { return _latency_signal_latency; }
private:
AudioEngine ();
static AudioEngine* _instance;
Glib::Threads::Mutex _process_lock;
Glib::Threads::Cond session_removed;
bool session_remove_pending;
frameoffset_t session_removal_countdown;
gain_t session_removal_gain;
gain_t session_removal_gain_step;
bool _running;
bool _freewheeling;
/// number of frames between each check for changes in monitor input
framecnt_t monitor_check_interval;
/// time of the last monitor check in frames
framecnt_t last_monitor_check;
/// the number of frames processed since start() was called
framecnt_t _processed_frames;
Glib::Threads::Thread* m_meter_thread;
ProcessThread* _main_thread;
MTDM* _mtdm;
bool _measuring_latency;
PortEngine::PortHandle _latency_input_port;
PortEngine::PortHandle _latency_output_port;
framecnt_t _latency_flush_frames;
std::string _latency_input_name;
std::string _latency_output_name;
framecnt_t _latency_signal_latency;
bool _started_for_latency;
void meter_thread ();
void start_metering_thread ();
void stop_metering_thread ();
static gint m_meter_exit;
void parameter_changed (const std::string&);
PBD::ScopedConnection config_connection;
typedef std::map<std::string,AudioBackendInfo*> BackendMap;
BackendMap _backends;
AudioBackendInfo* backend_discover (const std::string&);
void drop_backend ();
};
} // namespace ARDOUR
#endif /* __ardour_audioengine_h__ */

View File

@@ -0,0 +1,39 @@
/*
Copyright (C) 2011 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_backend_search_path_h__
#define __ardour_backend_search_path_h__
#include "pbd/search_path.h"
namespace ARDOUR {
/**
* return a SearchPath containing directories in which to look for
* backend plugins.
*
* If ARDOUR_BACKEND_PATH is defined then the SearchPath returned
* will contain only those directories specified in it, otherwise it will
* contain the user and system directories which may contain audio/MIDI
* backends.
*/
PBD::SearchPath backend_search_path ();
} // namespace ARDOUR
#endif /* __ardour_backend_search_path_h__ */

View File

@@ -70,7 +70,7 @@ public:
void clear();
void attach_buffers (PortSet& ports);
void get_jack_port_addresses (PortSet &, framecnt_t);
void get_backend_port_addresses (PortSet &, framecnt_t);
/* the capacity here is a size_t and has a different interpretation depending
on the DataType of the buffers. for audio, its a frame count. for MIDI

View File

@@ -21,11 +21,11 @@
#define __ardour_data_type_h__
#include <string>
#include <jack/jack.h>
#include <stdint.h>
#include <glib.h>
namespace ARDOUR {
/** A type of Data Ardour is capable of processing.
*
* The majority of this class is dedicated to conversion to and from various
@@ -61,33 +61,25 @@ public:
/** Construct from a string (Used for loading from XML and Ports)
* The string can be as in an XML file (eg "audio" or "midi"), or a
* Jack type string (from jack_port_type) */
*/
DataType(const std::string& str)
: _symbol(NIL) {
if (str == "audio" || str == JACK_DEFAULT_AUDIO_TYPE)
if (!g_ascii_strncasecmp(str.c_str(), "audio", str.length())) {
_symbol = AUDIO;
else if (str == "midi" || str == JACK_DEFAULT_MIDI_TYPE)
} else if (!g_ascii_strncasecmp(str.c_str(), "midi", str.length())) {
_symbol = MIDI;
}
/** Get the Jack type this DataType corresponds to */
const char* to_jack_type() const {
switch (_symbol) {
case AUDIO: return JACK_DEFAULT_AUDIO_TYPE;
case MIDI: return JACK_DEFAULT_MIDI_TYPE;
default: return "";
}
}
/** Inverse of the from-string constructor */
const char* to_string() const {
switch (_symbol) {
case AUDIO: return "audio";
case MIDI: return "midi";
default: return "unknown"; // reeeally shouldn't ever happen
case AUDIO: return "audio";
case MIDI: return "midi";
default: return "unknown"; // reeeally shouldn't ever happen
}
}
const char* to_i18n_string () const;
inline operator uint32_t() const { return (uint32_t)_symbol; }
@@ -125,7 +117,6 @@ private:
};
} // namespace ARDOUR
#endif // __ardour_data_type_h__

View File

@@ -63,6 +63,7 @@ namespace PBD {
extern uint64_t OrderKeys;
extern uint64_t Automation;
extern uint64_t WiimoteControl;
extern uint64_t Ports;
}
}

View File

@@ -38,6 +38,7 @@ extern const char* const route_templates_dir_name;
extern const char* const surfaces_dir_name;
extern const char* const user_config_dir_name;
extern const char* const panner_dir_name;
extern const char* const backend_dir_name;
};

View File

@@ -133,8 +133,8 @@ class Diskstream : public SessionObject, public PublicDiskstream
virtual XMLNode& get_state(void);
virtual int set_state(const XMLNode&, int version);
virtual void request_jack_monitors_input (bool) {}
virtual void ensure_jack_monitors_input (bool) {}
virtual void request_input_monitoring (bool) {}
virtual void ensure_input_monitoring (bool) {}
framecnt_t capture_offset() const { return _capture_offset; }
virtual void set_capture_offset ();

View File

@@ -49,6 +49,7 @@ class ExportFormatBase {
F_None = 0,
F_WAV = SF_FORMAT_WAV,
F_W64 = SF_FORMAT_W64,
F_CAF = SF_FORMAT_CAF,
F_AIFF = SF_FORMAT_AIFF,
F_AU = SF_FORMAT_AU,
F_IRCAM = SF_FORMAT_IRCAM,

View File

@@ -36,6 +36,7 @@
#include "pbd/semutils.h"
#include "ardour/types.h"
#include "ardour/audio_backend.h"
#include "ardour/session_handle.h"
namespace ARDOUR
@@ -92,7 +93,7 @@ protected:
virtual void session_going_away ();
private:
std::list<pthread_t> _thread_list;
std::list<AudioBackendNativeThread> _thread_list;
volatile bool _quit_threads;
void reset_thread_list ();

View File

@@ -75,6 +75,7 @@ class LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee
const void* c_ui_type();
bool is_external_ui () const;
bool is_external_kx () const;
bool ui_is_resizable () const;
const char* port_symbol (uint32_t port) const;

View File

@@ -44,7 +44,6 @@ public:
void copy(const MidiBuffer& copy);
bool push_back(const Evoral::MIDIEvent<TimeType>& event);
bool push_back(const jack_midi_event_t& event);
bool push_back(TimeType time, size_t size, const uint8_t* data);
uint8_t* reserve(TimeType time, size_t size);

View File

@@ -81,7 +81,7 @@ class MidiDiskstream : public Diskstream
XMLNode& get_state(void);
int set_state(const XMLNode&, int version);
void ensure_jack_monitors_input (bool);
void ensure_input_monitoring (bool);
boost::shared_ptr<SMFSource> write_source () { return _write_source; }

View File

@@ -21,6 +21,8 @@
#ifndef __ardour_midi_port_h__
#define __ardour_midi_port_h__
#include "midi++/parser.h"
#include "ardour/port.h"
#include "ardour/midi_buffer.h"
#include "ardour/midi_state_tracker.h"
@@ -56,18 +58,35 @@ class MidiPort : public Port {
MidiBuffer& get_midi_buffer (pframes_t nframes);
protected:
friend class AudioEngine;
void set_always_parse (bool yn);
MIDI::Parser& self_parser() { return _self_parser; }
MidiPort (const std::string& name, Flags);
protected:
friend class PortManager;
MidiPort (const std::string& name, PortFlags);
private:
MidiBuffer* _buffer;
bool _has_been_mixed_down;
bool _resolve_required;
bool _input_active;
bool _always_parse;
void resolve_notes (void* jack_buffer, MidiBuffer::TimeType when);
/* Naming this is tricky. AsyncMIDIPort inherits (for now, aug 2013) from
* both MIDI::Port, which has _parser, and this (ARDOUR::MidiPort). We
* need parsing support in this object, independently of what the
* MIDI::Port/AsyncMIDIPort stuff does. Rather than risk errors coming
* from not explicitly naming which _parser we want, we will call this
* _self_parser for now.
*
* Ultimately, MIDI::Port should probably go away or be fully integrated
* into this object, somehow.
*/
MIDI::Parser _self_parser;
void resolve_notes (void* buffer, MidiBuffer::TimeType when);
};
} // namespace ARDOUR

View File

@@ -26,13 +26,11 @@
#include "pbd/signals.h"
#include "pbd/stacktrace.h"
namespace MIDI {
class Port;
}
namespace ARDOUR {
class Session;
class AsyncMIDIPort;
/* this is mostly a placeholder because I suspect that at some
point we will want to add more members to accomodate
@@ -67,7 +65,7 @@ class MidiControlUI : public AbstractUI<MidiUIRequest>
ARDOUR::Session& _session;
PBD::ScopedConnection rebind_connection;
bool midi_input_handler (Glib::IOCondition, MIDI::Port*);
bool midi_input_handler (Glib::IOCondition, AsyncMIDIPort*);
void reset_ports ();
void clear_ports ();

View File

@@ -0,0 +1,99 @@
/*
Copyright (C) 1998 Paul Barton-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 __midiport_manager_h__
#define __midiport_manager_h__
#include <list>
#include <string>
#include "pbd/rcu.h"
#include "midi++/types.h"
#include "midi++/port.h"
#include "ardour/types.h"
namespace ARDOUR {
class MidiPort;
class Port;
class MidiPortManager {
public:
MidiPortManager();
virtual ~MidiPortManager ();
/* Ports used for control. These are read/written to outside of the
* process callback (asynchronously with respect to when data
* actually arrives).
*
* More detail: we do actually read/write data for these ports
* inside the process callback, but incoming data is only parsed
* and outgoing data is only generated *outside* the process
* callback.
*/
MIDI::Port* midi_input_port () const { return _midi_input_port; }
MIDI::Port* midi_output_port () const { return _midi_output_port; }
MIDI::Port* mmc_input_port () const { return _mmc_input_port; }
MIDI::Port* mmc_output_port () const { return _mmc_output_port; }
/* Ports used for synchronization. These have their I/O handled inside the
* process callback.
*/
boost::shared_ptr<MidiPort> mtc_input_port() const { return _mtc_input_port; }
boost::shared_ptr<MidiPort> mtc_output_port() const { return _mtc_output_port; }
boost::shared_ptr<MidiPort> midi_clock_input_port() const { return _midi_clock_input_port; }
boost::shared_ptr<MidiPort> midi_clock_output_port() const { return _midi_clock_output_port; }
void set_midi_port_states (const XMLNodeList&);
std::list<XMLNode*> get_midi_port_states () const;
PBD::Signal0<void> PortsChanged;
protected:
/* asynchronously handled ports: MIDI::Port */
MIDI::Port* _midi_input_port;
MIDI::Port* _midi_output_port;
MIDI::Port* _mmc_input_port;
MIDI::Port* _mmc_output_port;
/* these point to the same objects as the 4 members above,
but cast to their ARDOUR::Port base class
*/
boost::shared_ptr<Port> _midi_in;
boost::shared_ptr<Port> _midi_out;
boost::shared_ptr<Port> _mmc_in;
boost::shared_ptr<Port> _mmc_out;
/* synchronously handled ports: ARDOUR::MidiPort */
boost::shared_ptr<MidiPort> _mtc_input_port;
boost::shared_ptr<MidiPort> _mtc_output_port;
boost::shared_ptr<MidiPort> _midi_clock_input_port;
boost::shared_ptr<MidiPort> _midi_clock_output_port;
void create_ports ();
};
} // namespace MIDI
#endif // __midi_port_manager_h__

View File

@@ -30,6 +30,7 @@
#include "pbd/signals.h"
#include "ardour/data_type.h"
#include "ardour/port_engine.h"
#include "ardour/types.h"
namespace ARDOUR {
@@ -40,11 +41,6 @@ class Buffer;
class Port : public boost::noncopyable
{
public:
enum Flags {
IsInput = JackPortIsInput,
IsOutput = JackPortIsOutput,
};
virtual ~Port ();
static void set_connecting_blocked( bool yn ) {
@@ -62,7 +58,7 @@ public:
int set_name (std::string const &);
/** @return flags */
Flags flags () const {
PortFlags flags () const {
return _flags;
}
@@ -90,24 +86,24 @@ public:
virtual int connect (Port *);
int disconnect (Port *);
void ensure_jack_monitors_input (bool);
bool jack_monitoring_input () const;
void request_input_monitoring (bool);
void ensure_input_monitoring (bool);
bool monitoring_input () const;
int reestablish ();
int reconnect ();
void request_jack_monitors_input (bool);
bool last_monitor() const { return _last_monitor; }
void set_last_monitor (bool yn) { _last_monitor = yn; }
jack_port_t* jack_port() const { return _jack_port; }
PortEngine::PortHandle port_handle() { return _port_handle; }
void get_connected_latency_range (jack_latency_range_t& range, bool playback) const;
void get_connected_latency_range (LatencyRange& range, bool playback) const;
void set_private_latency_range (jack_latency_range_t& range, bool playback);
const jack_latency_range_t& private_latency_range (bool playback) const;
void set_private_latency_range (LatencyRange& range, bool playback);
const LatencyRange& private_latency_range (bool playback) const;
void set_public_latency_range (jack_latency_range_t& range, bool playback) const;
jack_latency_range_t public_latency_range (bool playback) const;
void set_public_latency_range (LatencyRange& range, bool playback) const;
LatencyRange public_latency_range (bool playback) const;
virtual void reset ();
@@ -122,8 +118,6 @@ public:
bool physically_connected () const;
static void set_engine (AudioEngine *);
PBD::Signal1<void,bool> MonitorInputChanged;
static PBD::Signal2<void,boost::shared_ptr<Port>,boost::shared_ptr<Port> > PostDisconnect;
static PBD::Signal0<void> PortDrop;
@@ -141,11 +135,16 @@ public:
virtual void increment_port_buffer_offset (pframes_t n);
virtual XMLNode& get_state (void) const;
virtual int set_state (const XMLNode&, int version);
static std::string state_node_name;
protected:
Port (std::string const &, DataType, Flags);
Port (std::string const &, DataType, PortFlags);
jack_port_t* _jack_port; ///< JACK port
PortEngine::PortHandle _port_handle;
static bool _connecting_blocked;
static pframes_t _global_port_buffer_offset; /* access only from process() tree */
@@ -153,18 +152,16 @@ protected:
framecnt_t _port_buffer_offset; /* access only from process() tree */
jack_latency_range_t _private_playback_latency;
jack_latency_range_t _private_capture_latency;
static AudioEngine* _engine; ///< the AudioEngine
LatencyRange _private_playback_latency;
LatencyRange _private_capture_latency;
private:
std::string _name; ///< port short name
Flags _flags; ///< flags
PortFlags _flags; ///< flags
bool _last_monitor;
/** ports that we are connected to, kept so that we can
reconnect to JACK when required
reconnect to the backend when required
*/
std::set<std::string> _connections;

View File

@@ -0,0 +1,345 @@
/*
Copyright (C) 2013 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 __libardour_port_engine_h__
#define __libardour_port_engine_h__
#include <vector>
#include <string>
#include <stdint.h>
#include "ardour/data_type.h"
#include "ardour/types.h"
namespace ARDOUR {
class PortManager;
/** PortEngine is an abstract base class that defines the functionality
* required by Ardour.
*
* A Port is basically an endpoint for a datastream (which can either be
* continuous, like audio, or event-based, like MIDI). Ports have buffers
* associated with them into which data can be written (if they are output
* ports) and from which data can be read (if they input ports). Ports can be
* connected together so that data written to an output port can be read from
* an input port. These connections can be 1:1, 1:N OR N:1.
*
* Ports may be associated with software only, or with hardware. Hardware
* related ports are often referred to as physical, and correspond to some
* relevant physical entity on a hardware device, such as an audio jack or a
* MIDI connector. Physical ports may be potentially asked to monitor their
* inputs, though some implementations may not support this.
*
* Most physical ports will also be considered "terminal", which means that
* data delivered there or read from there will go to or comes from a system
* outside of the PortEngine implementation's control (e.g. the analog domain
* for audio, or external MIDI devices for MIDI). Non-physical ports can also
* be considered "terminal". For example, the output port of a software
* synthesizer is a terminal port, because the data contained in its buffer
* does not and cannot be considered to come from any other port - it is
* synthesized by its owner.
*
* Ports also have latency associated with them. Each port has a playback
* latency and a capture latency:
*
* <b>capture latency</b>: how long since the data read from the buffer of a
* port arrived at at a terminal port. The data will have
* come from the "outside world" if the terminal port is also
* physical, or will have been synthesized by the entity that
* owns the terminal port.
*
* <b>playback latency</b>: how long until the data written to the buffer of
* port will reach a terminal port.
*
*
* For more detailed questions about the PortEngine API, consult the JACK API
* documentation, on which this entire object is based.
*/
class PortEngine {
public:
PortEngine (PortManager& pm) : manager (pm) {}
virtual ~PortEngine() {}
/** Return a private, type-free pointer to any data
* that might be useful to a concrete implementation
*/
virtual void* private_handle() const = 0;
/* We use void* here so that the API can be defined for any implementation.
*
* We could theoretically use a template (PortEngine<T>) and define
* PortHandle as T, but this complicates the desired inheritance
* pattern in which FooPortEngine handles things for the Foo API,
* rather than being a derivative of PortEngine<Foo>.
*/
typedef void* PortHandle;
/** Return the name of this process as used by the port manager
* when naming ports.
*/
virtual const std::string& my_name() const = 0;
/** Return true if the underlying mechanism/API is still available
* for us to utilize. return false if some or all of the AudioBackend
* API can no longer be effectively used.
*/
virtual bool available() const = 0;
/** Return the maximum size of a port name
*/
virtual uint32_t port_name_size() const = 0;
/** Returns zero if the port referred to by @param port was set to @param
* name. Return non-zero otherwise.
*/
virtual int set_port_name (PortHandle port, const std::string& name) = 0;
/** Return the name of the port referred to by @param port. If the port
* does not exist, return an empty string.
*/
virtual std::string get_port_name (PortHandle) const = 0;
/** Return a reference to a port with the fullname @param name. Return
* a null pointer if no such port exists.
*/
virtual PortHandle* get_port_by_name (const std::string&) const = 0;
/** Find the set of ports whose names, types and flags match
* specified values, place the names of each port into @param ports,
* and return the count of the number found.
*
* To avoid selecting by name, pass an empty string for @param
* port_name_pattern.
*
* To avoid selecting by type, pass DataType::NIL as @param type.
*
* To avoid selecting by flags, pass PortFlags (0) as @param flags.
*/
virtual int get_ports (const std::string& port_name_pattern, DataType type, PortFlags flags, std::vector<std::string>& ports) const = 0;
/** Return the Ardour data type handled by the port referred to by @param
* port. Returns DataType::NIL if the port does not exist.
*/
virtual DataType port_data_type (PortHandle port) const = 0;
/** Create a new port whose fullname will be the conjuction of my_name(),
* ":" and @param shortname. The port will handle data specified by @param
* type and will have the flags given by @param flags. If successfull,
* return a reference to the port, otherwise return a null pointer.
*/
virtual PortHandle register_port (const std::string& shortname, ARDOUR::DataType type, ARDOUR::PortFlags flags) = 0;
/* Destroy the port referred to by @param port, including all resources
* associated with it. This will also disconnect @param port from any ports it
* is connected to.
*/
virtual void unregister_port (PortHandle) = 0;
/* Connection management */
/** Ensure that data written to the port named by @param src will be
* readable from the port named by @param dst. Return zero on success,
* non-zero otherwise.
*/
virtual int connect (const std::string& src, const std::string& dst) = 0;
/** Remove any existing connection between the ports named by @param src and
* @param dst. Return zero on success, non-zero otherwise.
*/
virtual int disconnect (const std::string& src, const std::string& dst) = 0;
/** Ensure that data written to the port referenced by @param portwill be
* readable from the port named by @param dst. Return zero on success,
* non-zero otherwise.
*/
virtual int connect (PortHandle src, const std::string& dst) = 0;
/** Remove any existing connection between the port referenced by @param src and
* the port named @param dst. Return zero on success, non-zero otherwise.
*/
virtual int disconnect (PortHandle src, const std::string& dst) = 0;
/** Remove all connections between the port referred to by @param port and
* any other ports. Return zero on success, non-zero otherwise.
*/
virtual int disconnect_all (PortHandle port) = 0;
/** Return true if the port referred to by @param port has any connections
* to other ports. Return false otherwise.
*/
virtual bool connected (PortHandle port, bool process_callback_safe = true) = 0;
/** Return true if the port referred to by @param port is connected to
* the port named by @param name. Return false otherwise.
*/
virtual bool connected_to (PortHandle, const std::string& name, bool process_callback_safe = true) = 0;
/** Return true if the port referred to by @param port has any connections
* to ports marked with the PortFlag IsPhysical. Return false otherwise.
*/
virtual bool physically_connected (PortHandle port, bool process_callback_safe = true) = 0;
/** Place the names of all ports connected to the port named by @param
* ports into @param names, and return the number of connections.
*/
virtual int get_connections (PortHandle port, std::vector<std::string>& names, bool process_callback_safe = true) = 0;
/* MIDI */
/** Retrieve a MIDI event from the data at @param port_buffer. The event
number to be retrieved is given by @param event_index (a value of zero
indicates that the first event in the port_buffer should be retrieved).
*
* The data associated with the event will be copied into the buffer at
* @param buf and the number of bytes written will be stored in @param
* size. The timestamp of the event (which is always relative to the start
* of the current process cycle, in samples) will be stored in @param
* timestamp
*/
virtual int midi_event_get (pframes_t& timestamp, size_t& size, uint8_t** buf, void* port_buffer, uint32_t event_index) = 0;
/** Place a MIDI event consisting of @param size bytes copied from the data
* at @param buf into the port buffer referred to by @param
* port_buffer. The MIDI event will be marked with a time given by @param
* timestamp. Return zero on success, non-zero otherwise.
*
* Events must be added monotonically to a port buffer. An attempt to
* add a non-monotonic event (e.g. out-of-order) will cause this method
* to return a failure status.
*/
virtual int midi_event_put (void* port_buffer, pframes_t timestamp, const uint8_t* buffer, size_t size) = 0;
/** Return the number of MIDI events in the data at @param port_buffer
*/
virtual uint32_t get_midi_event_count (void* port_buffer) = 0;
/** Clear the buffer at @param port_buffer of all MIDI events.
*
* After a call to this method, an immediate, subsequent call to
* get_midi_event_count() with the same @param port_buffer argument must
* return zero.
*/
virtual void midi_clear (void* port_buffer) = 0;
/* Monitoring */
/** Return true if the implementation can offer input monitoring.
*
* Input monitoring involves the (selective) routing of incoming data
* to an outgoing data stream, without the data being passed to the CPU.
*
* Only certain audio hardware can provide this, and only certain audio
* APIs can offer it.
*/
virtual bool can_monitor_input() const = 0;
/** Increment or decrement the number of requests to monitor the input
* of the hardware channel represented by the port referred to by @param
* port.
*
* If the number of requests rises above zero, input monitoring will
* be enabled (if can_monitor_input() returns true for the implementation).
*
* If the number of requests falls to zero, input monitoring will be
* disabled (if can_monitor_input() returns true for the implementation)
*/
virtual int request_input_monitoring (PortHandle port, bool yn) = 0;
/* Force input monitoring of the hardware channel represented by the port
* referred to by @param port to be on or off, depending on the true/false
* status of @param yn. The request count is ignored when using this
* method, so if this is called with yn set to false, input monitoring will
* be disabled regardless of the number of requests to enable it.
*/
virtual int ensure_input_monitoring (PortHandle port, bool yn) = 0;
/** Return true if input monitoring is enabled for the hardware channel
* represented by the port referred to by @param port. Return false
* otherwise.
*/
virtual bool monitoring_input (PortHandle port) = 0;
/* Latency management
*/
/** Set the latency range for the port referred to by @param port to @param
* r. The playback range will be set if @param for_playback is true,
* otherwise the capture range will be set.
*/
virtual void set_latency_range (PortHandle port, bool for_playback, LatencyRange r) = 0;
/** Return the latency range for the port referred to by @param port.
* The playback range will be returned if @param for_playback is true,
* otherwise the capture range will be returned.
*/
virtual LatencyRange get_latency_range (PortHandle port, bool for_playback) = 0;
/* Discovering physical ports */
/** Return true if the port referred to by @param port has the IsPhysical
* flag set. Return false otherwise.
*/
virtual bool port_is_physical (PortHandle port) const = 0;
/** Store into @param names the names of all ports with the IsOutput and
* IsPhysical flag set, that handle data of type @param type.
*
* This can be used to discover outputs associated with hardware devices.
*/
virtual void get_physical_outputs (DataType type, std::vector<std::string>& names) = 0;
/** Store into @param names the names of all ports with the IsInput and
* IsPhysical flags set, that handle data of type @param type.
*
* This can be used to discover inputs associated with hardware devices.
*/
virtual void get_physical_inputs (DataType type, std::vector<std::string>& names) = 0;
/** Return the total count (possibly mixed between different data types)
of the number of ports with the IsPhysical and IsOutput flags set.
*/
virtual ChanCount n_physical_outputs () const = 0;
/** Return the total count (possibly mixed between different data types)
of the number of ports with the IsPhysical and IsInput flags set.
*/
virtual ChanCount n_physical_inputs () const = 0;
/** Return the address of the memory area where data for the port can be
* written (if the port has the PortFlag IsOutput set) or read (if the port
* has the PortFlag IsInput set).
*
* The return value is untyped because buffers containing different data
* depending on the port type.
*/
virtual void* get_buffer (PortHandle, pframes_t) = 0;
/* MIDI ports (the ones in libmidi++) need this to be able to correctly
* schedule MIDI events within their buffers. It is a bit odd that we
* expose this here, because it is also exposed by AudioBackend, but they
* only have access to a PortEngine object, not an AudioBackend.
*
* Return the time according to the sample clock in use when the current
* buffer process cycle began.
*
* XXX to be removed after some more design cleanup.
*/
virtual pframes_t sample_time_at_cycle_start () = 0;
protected:
PortManager& manager;
};
}
#endif /* __libardour_port_engine_h__ */

View File

@@ -0,0 +1,170 @@
/*
Copyright (C) 2013 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 __libardour_port_manager_h__
#define __libardour_port_manager_h__
#include <vector>
#include <string>
#include <exception>
#include <map>
#include <stdint.h>
#include <boost/shared_ptr.hpp>
#include "pbd/rcu.h"
#include "ardour/chan_count.h"
#include "ardour/midiport_manager.h"
#include "ardour/port.h"
namespace ARDOUR {
class PortEngine;
class AudioBackend;
class PortManager
{
public:
typedef std::map<std::string,boost::shared_ptr<Port> > Ports;
typedef std::list<boost::shared_ptr<Port> > PortList;
PortManager ();
virtual ~PortManager() {}
PortEngine& port_engine();
uint32_t port_name_size() const;
std::string my_name() const;
/* Port registration */
boost::shared_ptr<Port> register_input_port (DataType, const std::string& portname, bool async = false);
boost::shared_ptr<Port> register_output_port (DataType, const std::string& portname, bool async = false);
int unregister_port (boost::shared_ptr<Port>);
/* Port connectivity */
int connect (const std::string& source, const std::string& destination);
int disconnect (const std::string& source, const std::string& destination);
int disconnect (boost::shared_ptr<Port>);
int reestablish_ports ();
int reconnect_ports ();
bool connected (const std::string&);
bool connected_to (const std::string&, const std::string&);
bool physically_connected (const std::string&);
int get_connections (const std::string&, std::vector<std::string>&);
/* Naming */
boost::shared_ptr<Port> get_port_by_name (const std::string &);
void port_renamed (const std::string&, const std::string&);
std::string make_port_name_relative (const std::string& name) const;
std::string make_port_name_non_relative (const std::string& name) const;
bool port_is_mine (const std::string& fullname) const;
/* other Port management */
bool port_is_physical (const std::string&) const;
void get_physical_outputs (DataType type, std::vector<std::string>&);
void get_physical_inputs (DataType type, std::vector<std::string>&);
ChanCount n_physical_outputs () const;
ChanCount n_physical_inputs () const;
int get_ports (const std::string& port_name_pattern, DataType type, PortFlags flags, std::vector<std::string>&);
int get_ports (DataType, PortList&);
void remove_all_ports ();
/* per-Port monitoring */
bool can_request_input_monitoring () const;
void request_input_monitoring (const std::string&, bool) const;
void ensure_input_monitoring (const std::string&, bool) const;
class PortRegistrationFailure : public std::exception {
public:
PortRegistrationFailure (std::string const & why = "")
: reason (why) {}
~PortRegistrationFailure () throw () {}
const char *what() const throw () { return reason.c_str(); }
private:
std::string reason;
};
/* the port engine will invoke these callbacks when the time is right */
void registration_callback ();
int graph_order_callback ();
void connect_callback (const std::string&, const std::string&, bool connection);
bool port_remove_in_progress() const { return _port_remove_in_progress; }
/** Emitted if the backend notifies us of a graph order event */
PBD::Signal0<void> GraphReordered;
/** Emitted if a Port is registered or unregistered */
PBD::Signal0<void> PortRegisteredOrUnregistered;
/** Emitted if a Port is connected or disconnected.
* The Port parameters are the ports being connected / disconnected, or 0 if they are not known to Ardour.
* The std::string parameters are the (long) port names.
* The bool parameter is true if ports were connected, or false for disconnected.
*/
PBD::Signal5<void, boost::weak_ptr<Port>, std::string, boost::weak_ptr<Port>, std::string, bool> PortConnectedOrDisconnected;
protected:
boost::shared_ptr<AudioBackend> _backend;
SerializedRCUManager<Ports> ports;
bool _port_remove_in_progress;
boost::shared_ptr<Port> register_port (DataType type, const std::string& portname, bool input, bool async = false);
void port_registration_failure (const std::string& portname);
/** List of ports to be used between ::cycle_start() and ::cycle_end()
*/
boost::shared_ptr<Ports> _cycle_ports;
void fade_out (gain_t, gain_t, pframes_t);
void silence (pframes_t nframes);
void check_monitoring ();
/** Signal the start of an audio cycle.
* This MUST be called before any reading/writing for this cycle.
* Realtime safe.
*/
void cycle_start (pframes_t nframes);
/** Signal the end of an audio cycle.
* This signifies that the cycle began with @ref cycle_start has ended.
* This MUST be called at the end of each cycle.
* Realtime safe.
*/
void cycle_end (pframes_t nframes);
};
} // namespace
#endif /* __libardour_port_manager_h__ */

View File

@@ -33,8 +33,8 @@ public:
virtual ~PublicDiskstream() {}
virtual boost::shared_ptr<Playlist> playlist () = 0;
virtual void request_jack_monitors_input (bool) = 0;
virtual void ensure_jack_monitors_input (bool) = 0;
virtual void request_input_monitoring (bool) = 0;
virtual void ensure_input_monitoring (bool) = 0;
virtual bool destructive () const = 0;
virtual std::list<boost::shared_ptr<Source> > & last_capture_sources () = 0;
virtual void set_capture_offset () = 0;

View File

@@ -52,7 +52,6 @@ class RCConfiguration : public Configuration
XMLNode * instant_xml (const std::string& str);
XMLNode* control_protocol_state () { return _control_protocol_state; }
std::list<XMLNode*> midi_port_states () { return _midi_port_states; }
/* define accessor methods */
@@ -81,11 +80,6 @@ class RCConfiguration : public Configuration
#undef CONFIG_VARIABLE_SPECIAL
XMLNode* _control_protocol_state;
/** MIDI port nodes from the RC configuration. We store them so that we can set their
state once the audio engine and hence ports are up.
*/
std::list<XMLNode*> _midi_port_states;
};
/* XXX: rename this */

View File

@@ -110,6 +110,8 @@ class IOProcessor;
class ImportStatus;
class MidiClockTicker;
class MidiControlUI;
class MidiPortManager;
class MidiPort;
class MidiRegion;
class MidiSource;
class MidiTrack;
@@ -381,9 +383,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
framecnt_t worst_track_latency () const { return _worst_track_latency; }
framecnt_t worst_playback_latency () const { return _worst_output_latency + _worst_track_latency; }
#ifdef HAVE_JACK_SESSION
void jack_session_event (jack_session_event_t* event);
#endif
int save_state (std::string snapshot_name, bool pending = false, bool switch_to_snapshot = false);
int restore_state (std::string snapshot_name);
int save_template (std::string template_name);
@@ -556,6 +555,11 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
int remove_last_capture ();
/** handlers should return 0 for "everything OK", and any other value for
* "cannot setup audioengine".
*/
static PBD::Signal1<int,uint32_t> AudioEngineSetupRequired;
/** handlers should return -1 for "stop cleanup",
0 for "yes, delete this playlist",
1 for "no, don't delete this playlist".
@@ -813,8 +817,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
boost::shared_ptr<SessionPlaylists> playlists;
void send_mmc_locate (framepos_t);
int send_full_time_code (framepos_t);
void send_song_position_pointer (framepos_t);
void queue_full_time_code () { _send_timecode_update = true; }
void queue_song_position_pointer () { /* currently does nothing */ }
bool step_editing() const { return (_step_editors > 0); }
@@ -863,6 +867,27 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
boost::shared_ptr<IO> ltc_input_io() { return _ltc_input; }
boost::shared_ptr<IO> ltc_output_io() { return _ltc_output; }
MIDI::Port* midi_input_port () const;
MIDI::Port* midi_output_port () const;
MIDI::Port* mmc_output_port () const;
MIDI::Port* mmc_input_port () const;
boost::shared_ptr<MidiPort> midi_clock_output_port () const;
boost::shared_ptr<MidiPort> midi_clock_input_port () const;
boost::shared_ptr<MidiPort> mtc_output_port () const;
boost::shared_ptr<MidiPort> mtc_input_port () const;
MIDI::MachineControl& mmc() { return *_mmc; }
/* Callbacks specifically related to JACK, and called directly
* from the JACK audio backend.
*/
#ifdef HAVE_JACK_SESSION
void jack_session_event (jack_session_event_t* event);
#endif
void jack_timebase_callback (jack_transport_state_t, pframes_t, jack_position_t*, int);
protected:
friend class AudioEngine;
void set_block_size (pframes_t nframes);
@@ -1046,7 +1071,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
boost::scoped_ptr<SessionDirectory> _session_dir;
void hookup_io ();
void when_engine_running ();
int when_engine_running ();
void graph_reordered ();
/** current snapshot name, without the .ardour suffix */
@@ -1112,8 +1137,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void auto_loop_changed (Location *);
void auto_loop_declick_range (Location *, framepos_t &, framepos_t &);
void first_stage_init (std::string path, std::string snapshot_name);
int second_stage_init ();
void pre_engine_init (std::string path);
int post_engine_init ();
void remove_empty_sounds ();
void setup_midi_control ();
@@ -1216,7 +1241,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
framepos_t ltc_timecode_offset;
bool ltc_timecode_negative_offset;
jack_latency_range_t ltc_out_latency;
LatencyRange ltc_out_latency;
void ltc_tx_initialize();
void ltc_tx_cleanup();
@@ -1261,6 +1286,13 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void engine_halted ();
void xrun_recovery ();
/* These are synchronous and so can only be called from within the process
* cycle
*/
int send_full_time_code (framepos_t, pframes_t nframes);
void send_song_position_pointer (framepos_t);
TempoMap *_tempo_map;
void tempo_map_changed (const PBD::PropertyChange&);
@@ -1429,9 +1461,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
*/
std::list<GQuark> _current_trans_quarks;
void jack_timebase_callback (jack_transport_state_t, pframes_t, jack_position_t*, int);
int jack_sync_callback (jack_transport_state_t, jack_position_t*);
void reset_jack_connection (jack_client_t* jack);
int backend_sync_callback (TransportState, framepos_t);
void process_rtop (SessionEvent*);
void update_latency (bool playback);
@@ -1585,6 +1616,15 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void reconnect_ltc_input ();
void reconnect_ltc_output ();
/* persistent, non-track related MIDI ports */
MidiPortManager* _midi_ports;
MIDI::MachineControl* _mmc;
void setup_ltc ();
void setup_click ();
void setup_bundles ();
int ensure_engine (uint32_t desired_sample_rate);
};
} // namespace ARDOUR

View File

@@ -40,14 +40,12 @@
#define PLUSMINUS(A) ( ((A)<0) ? "-" : (((A)>0) ? "+" : "\u00B1") )
#define LEADINGZERO(A) ( (A)<10 ? " " : (A)<100 ? " " : (A)<1000 ? " " : "" )
namespace MIDI {
class Port;
}
namespace ARDOUR {
class TempoMap;
class Session;
class AudioEngine;
class MidiPort;
/**
* @class Slave
@@ -252,10 +250,10 @@ class TimecodeSlave : public Slave {
class MTC_Slave : public TimecodeSlave {
public:
MTC_Slave (Session&, MIDI::Port&);
MTC_Slave (Session&, MidiPort&);
~MTC_Slave ();
void rebind (MIDI::Port&);
void rebind (MidiPort&);
bool speed_and_position (double&, framepos_t&);
bool locked() const;
@@ -273,7 +271,7 @@ class MTC_Slave : public TimecodeSlave {
private:
Session& session;
MIDI::Port* port;
MidiPort* port;
PBD::ScopedConnectionList port_connections;
PBD::ScopedConnection config_connection;
bool can_notify_on_unknown_rate;
@@ -354,7 +352,7 @@ public:
std::string approximate_current_delta() const;
private:
void parse_ltc(const jack_nframes_t, const jack_default_audio_sample_t * const, const framecnt_t);
void parse_ltc(const pframes_t, const Sample* const, const framecnt_t);
void process_ltc(framepos_t const);
void init_engine_dll (framepos_t, int32_t);
bool detect_discontinuity(LTCFrameExt *, int, bool);
@@ -391,7 +389,7 @@ public:
PBD::ScopedConnectionList port_connections;
PBD::ScopedConnection config_connection;
jack_latency_range_t ltc_slave_latency;
LatencyRange ltc_slave_latency;
/* DLL - chase LTC */
int transport_direction;
@@ -404,13 +402,13 @@ public:
class MIDIClock_Slave : public Slave {
public:
MIDIClock_Slave (Session&, MIDI::Port&, int ppqn = 24);
MIDIClock_Slave (Session&, MidiPort&, int ppqn = 24);
/// Constructor for unit tests
MIDIClock_Slave (ISlaveSessionProxy* session_proxy = 0, int ppqn = 24);
~MIDIClock_Slave ();
void rebind (MIDI::Port&);
void rebind (MidiPort&);
bool speed_and_position (double&, framepos_t&);
bool locked() const;
@@ -426,7 +424,6 @@ class MIDIClock_Slave : public Slave {
protected:
ISlaveSessionProxy* session;
MIDI::Port* port;
PBD::ScopedConnectionList port_connections;
/// pulses per quarter note for one MIDI clock frame (default 24)
@@ -492,7 +489,7 @@ class MIDIClock_Slave : public Slave {
class JACK_Slave : public Slave
{
public:
JACK_Slave (jack_client_t*);
JACK_Slave (AudioEngine&);
~JACK_Slave ();
bool speed_and_position (double& speed, framepos_t& pos);
@@ -502,11 +499,10 @@ class JACK_Slave : public Slave
bool ok() const;
framecnt_t resolution () const { return 1; }
bool requires_seekahead () const { return false; }
void reset_client (jack_client_t* jack);
bool is_always_synced() const { return true; }
private:
jack_client_t* jack;
AudioEngine& engine;
double speed;
bool _starting;
};

View File

@@ -27,17 +27,13 @@
#include "ardour/session_handle.h"
#ifndef TICKER_H_
#define TICKER_H_
#ifndef __libardour_ticker_h__
#define __libardour_ticker_h__
namespace MIDI {
class Port;
}
namespace ARDOUR
{
namespace ARDOUR {
class Session;
class MidiPort;
class MidiClockTicker : public SessionHandlePtr, boost::noncopyable
{
@@ -45,7 +41,7 @@ public:
MidiClockTicker ();
virtual ~MidiClockTicker();
void tick (const framepos_t& transport_frames);
void tick (const framepos_t& transport_frames, pframes_t nframes);
bool has_midi_port() const { return _midi_port != 0; }
@@ -58,9 +54,6 @@ public:
/// slot for the signal session::TransportStateChange
void transport_state_changed();
/// slot for the signal session::PositionChanged
void position_changed (framepos_t position);
/// slot for the signal session::TransportLooped
void transport_looped();
@@ -70,23 +63,25 @@ public:
/// pulses per quarter note (default 24)
void set_ppqn(int ppqn) { _ppqn = ppqn; }
private:
MIDI::Port* _midi_port;
int _ppqn;
double _last_tick;
private:
boost::shared_ptr<MidiPort> _midi_port;
int _ppqn;
double _last_tick;
bool _send_pos;
bool _send_state;
class Position;
boost::scoped_ptr<Position> _pos;
class Position;
boost::scoped_ptr<Position> _pos;
double one_ppqn_in_frames (framepos_t transport_position);
double one_ppqn_in_frames (framepos_t transport_position);
void send_midi_clock_event (pframes_t offset);
void send_start_event (pframes_t offset);
void send_continue_event (pframes_t offset);
void send_stop_event (pframes_t offset);
void send_position_event (uint32_t midi_clocks, pframes_t offset);
void send_midi_clock_event (pframes_t offset, pframes_t nframes);
void send_start_event (pframes_t offset, pframes_t nframes);
void send_continue_event (pframes_t offset, pframes_t nframes);
void send_stop_event (pframes_t offset, pframes_t nframes);
void send_position_event (uint32_t midi_clocks, pframes_t offset, pframes_t nframes);
};
}
// namespace
#endif /* TICKER_H_ */
#endif /* __libardour_ticker_h__ */

View File

@@ -115,8 +115,8 @@ class Track : public Route, public PublicDiskstream
/* PublicDiskstream interface */
boost::shared_ptr<Playlist> playlist ();
void request_jack_monitors_input (bool);
void ensure_jack_monitors_input (bool);
void request_input_monitoring (bool);
void ensure_input_monitoring (bool);
bool destructive () const;
std::list<boost::shared_ptr<Source> > & last_capture_sources ();
void set_capture_offset ();

View File

@@ -26,10 +26,9 @@
#include <boost/shared_ptr.hpp>
#include <sys/types.h>
#include <stdint.h>
#include <pthread.h>
#include <inttypes.h>
#include <jack/types.h>
#include <jack/midiport.h>
#include "timecode/bbt_time.h"
#include "timecode/time.h"
@@ -53,12 +52,12 @@ namespace ARDOUR {
class Route;
class Region;
typedef jack_default_audio_sample_t Sample;
typedef float pan_t;
typedef float gain_t;
typedef uint32_t layer_t;
typedef uint64_t microseconds_t;
typedef jack_nframes_t pframes_t;
typedef float Sample;
typedef float pan_t;
typedef float gain_t;
typedef uint32_t layer_t;
typedef uint64_t microseconds_t;
typedef uint32_t pframes_t;
/* Any position measured in audio frames.
Assumed to be non-negative but not enforced.
@@ -585,6 +584,42 @@ namespace ARDOUR {
FadeSymmetric,
};
enum TransportState {
/* these values happen to match the constants used by JACK but
this equality cannot be assumed.
*/
TransportStopped = 0,
TransportRolling = 1,
TransportLooping = 2,
TransportStarting = 3,
};
enum PortFlags {
/* these values happen to match the constants used by JACK but
this equality cannot be assumed.
*/
IsInput = 0x1,
IsOutput = 0x2,
IsPhysical = 0x4,
CanMonitor = 0x8,
IsTerminal = 0x10
};
struct LatencyRange {
uint32_t min; //< samples
uint32_t max; //< samples
};
/* PLATFORM SPECIFIC #ifdef's here */
/** Define the native thread type used on the platform */
typedef pthread_t AudioBackendNativeThread;
static inline bool self_thread_equal (AudioBackendNativeThread thr) {
return pthread_equal (thr, pthread_self());
}
/* PLATFORM SPECIFIC #endif's here */
} // namespace ARDOUR

View File

@@ -0,0 +1,44 @@
/*
Copyright (C) 2013 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 __libardour_visibility_h__
#define __libardour_visibility_h__
/* _WIN32 is defined by most compilers targetting Windows, but within the
* ardour source tree, we also define COMPILER_MSVC or COMPILER_MINGW depending
* on how a Windows build is built.
*/
#if defined _WIN32 || defined __CYGWIN__ || defined(COMPILER_MSVC) || defined(COMPILER_MINGW)
#define LIBARDOUR_HELPER_DLL_IMPORT __declspec(dllimport)
#define LIBARDOUR_HELPER_DLL_EXPORT __declspec(dllexport)
#define LIBARDOUR_HELPER_DLL_LOCAL
#else
#if __GNUC__ >= 4
#define LIBARDOUR_HELPER_DLL_IMPORT __attribute__ ((visibility ("default")))
#define LIBARDOUR_HELPER_DLL_EXPORT __attribute__ ((visibility ("default")))
#define LIBARDOUR_HELPER_DLL_LOCAL __attribute__ ((visibility ("hidden")))
#else
#define LIBARDOUR_HELPER_DLL_IMPORT
#define LIBARDOUR_HELPER_DLL_EXPORT
#define LIBARDOUR_HELPER_DLL_LOCAL
#endif
#endif
#endif /* __libardour_visibility_h__ */

View File

@@ -0,0 +1,303 @@
/*
Copyright (C) 1998 Paul Barton-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$
*/
#include <iostream>
#include "pbd/error.h"
#include "pbd/stacktrace.h"
#include "midi++/types.h"
#include "ardour/async_midi_port.h"
#include "ardour/audioengine.h"
#include "ardour/midi_buffer.h"
using namespace MIDI;
using namespace ARDOUR;
using namespace std;
using namespace PBD;
namespace Evoral {
template class EventRingBuffer<timestamp_t>;
}
pthread_t AsyncMIDIPort::_process_thread;
#define port_engine AudioEngine::instance()->port_engine()
AsyncMIDIPort::AsyncMIDIPort (string const & name, PortFlags flags)
: MidiPort (name, flags)
, MIDI::Port (name, MIDI::Port::Flags (0))
, _currently_in_cycle (false)
, _last_write_timestamp (0)
, output_fifo (512)
, input_fifo (1024)
, xthread (true)
{
}
AsyncMIDIPort::~AsyncMIDIPort ()
{
}
void
AsyncMIDIPort::flush_output_fifo (pframes_t nframes)
{
RingBuffer< Evoral::Event<double> >::rw_vector vec = { { 0, 0 }, { 0, 0 } };
size_t written;
output_fifo.get_read_vector (&vec);
MidiBuffer& mb (get_midi_buffer (nframes));
if (vec.len[0]) {
Evoral::Event<double>* evp = vec.buf[0];
for (size_t n = 0; n < vec.len[0]; ++n, ++evp) {
mb.push_back (evp->time(), evp->size(), evp->buffer());
}
}
if (vec.len[1]) {
Evoral::Event<double>* evp = vec.buf[1];
for (size_t n = 0; n < vec.len[1]; ++n, ++evp) {
mb.push_back (evp->time(), evp->size(), evp->buffer());
}
}
if ((written = vec.len[0] + vec.len[1]) != 0) {
output_fifo.increment_read_idx (written);
}
}
void
AsyncMIDIPort::cycle_start (pframes_t nframes)
{
_currently_in_cycle = true;
MidiPort::cycle_start (nframes);
/* dump anything waiting in the output FIFO at the start of the port
* buffer
*/
if (ARDOUR::Port::sends_output()) {
flush_output_fifo (nframes);
}
/* copy incoming data from the port buffer into the input FIFO
and if necessary wakeup the reader
*/
if (ARDOUR::Port::receives_input()) {
MidiBuffer& mb (get_midi_buffer (nframes));
pframes_t when = AudioEngine::instance()->sample_time_at_cycle_start();
for (MidiBuffer::iterator b = mb.begin(); b != mb.end(); ++b) {
input_fifo.write (when, (Evoral::EventType) 0, (*b).size(), (*b).buffer());
}
if (!mb.empty()) {
xthread.wakeup ();
}
}
}
void
AsyncMIDIPort::cycle_end (pframes_t nframes)
{
if (ARDOUR::Port::sends_output()) {
/* move any additional data from output FIFO into the port
buffer.
*/
flush_output_fifo (nframes);
}
MidiPort::cycle_end (nframes);
_currently_in_cycle = false;
}
/** wait for the output FIFO to be emptied by successive process() callbacks.
*
* Cannot be called from a processing thread.
*/
void
AsyncMIDIPort::drain (int check_interval_usecs)
{
RingBuffer< Evoral::Event<double> >::rw_vector vec = { { 0, 0 }, { 0, 0} };
if (!AudioEngine::instance()->running() || AudioEngine::instance()->session() == 0) {
/* no more process calls - it will never drain */
return;
}
if (is_process_thread()) {
error << "Process thread called MIDI::AsyncMIDIPort::drain() - this cannot work" << endmsg;
return;
}
while (1) {
output_fifo.get_write_vector (&vec);
if (vec.len[0] + vec.len[1] >= output_fifo.bufsize() - 1) {
break;
}
usleep (check_interval_usecs);
}
}
int
AsyncMIDIPort::write (const byte * msg, size_t msglen, timestamp_t timestamp)
{
int ret = 0;
if (!ARDOUR::Port::sends_output()) {
return ret;
}
if (!is_process_thread()) {
/* this is the best estimate of "when" this MIDI data is being
* delivered
*/
_parser->set_timestamp (AudioEngine::instance()->sample_time() + timestamp);
for (size_t n = 0; n < msglen; ++n) {
_parser->scanner (msg[n]);
}
Glib::Threads::Mutex::Lock lm (output_fifo_lock);
RingBuffer< Evoral::Event<double> >::rw_vector vec = { { 0, 0 }, { 0, 0} };
output_fifo.get_write_vector (&vec);
if (vec.len[0] + vec.len[1] < 1) {
error << "no space in FIFO for non-process thread MIDI write" << endmsg;
return 0;
}
if (vec.len[0]) {
if (!vec.buf[0]->owns_buffer()) {
vec.buf[0]->set_buffer (0, 0, true);
}
vec.buf[0]->set (msg, msglen, timestamp);
} else {
if (!vec.buf[1]->owns_buffer()) {
vec.buf[1]->set_buffer (0, 0, true);
}
vec.buf[1]->set (msg, msglen, timestamp);
}
output_fifo.increment_write_idx (1);
ret = msglen;
} else {
_parser->set_timestamp (AudioEngine::instance()->sample_time_at_cycle_start() + timestamp);
for (size_t n = 0; n < msglen; ++n) {
_parser->scanner (msg[n]);
}
if (timestamp >= _cycle_nframes) {
std::cerr << "attempting to write MIDI event of " << msglen << " bytes at time "
<< timestamp << " of " << _cycle_nframes
<< " (this will not work - needs a code fix)"
<< std::endl;
}
/* This is the process thread, which makes checking
* _currently_in_cycle atomic and safe, since it is only
* set from cycle_start() and cycle_end(), also called
* only from the process thread.
*/
if (_currently_in_cycle) {
MidiBuffer& mb (get_midi_buffer (_cycle_nframes));
if (timestamp == 0) {
timestamp = _last_write_timestamp;
}
if (mb.push_back (timestamp, msglen, msg)) {
ret = msglen;
_last_write_timestamp = timestamp;
} else {
cerr << "AsyncMIDIPort (" << ARDOUR::Port::name() << "): write of " << msglen << " @ " << timestamp << " failed\n" << endl;
PBD::stacktrace (cerr, 20);
ret = 0;
}
} else {
cerr << "write to JACK midi port failed: not currently in a process cycle." << endl;
PBD::stacktrace (cerr, 20);
}
}
return ret;
}
int
AsyncMIDIPort::read (MIDI::byte *, size_t)
{
if (!ARDOUR::Port::receives_input()) {
return 0;
}
timestamp_t time;
Evoral::EventType type;
uint32_t size;
byte buffer[input_fifo.capacity()];
while (input_fifo.read (&time, &type, &size, buffer)) {
_parser->set_timestamp (time);
for (uint32_t i = 0; i < size; ++i) {
_parser->scanner (buffer[i]);
}
}
return 0;
}
void
AsyncMIDIPort::parse (framecnt_t)
{
MIDI::byte buf[1];
/* see ::read() to realize why buf is not used */
read (buf, sizeof (buf));
}
void
AsyncMIDIPort::set_process_thread (pthread_t thr)
{
_process_thread = thr;
}
bool
AsyncMIDIPort::is_process_thread()
{
return pthread_equal (pthread_self(), _process_thread);
}

View File

@@ -925,7 +925,7 @@ AudioDiskstream::internal_playback_seek (framecnt_t distance)
boost::shared_ptr<ChannelList> c = channels.reader();
for (chan = c->begin(); chan != c->end(); ++chan) {
(*chan)->playback_buf->increment_read_ptr (llabs(distance));
(*chan)->playback_buf->increment_read_ptr (std::llabs(distance));
}
if (first_recordable_frame < max_framepos) {
@@ -1754,7 +1754,7 @@ AudioDiskstream::prep_record_enable ()
if (Config->get_monitoring_model() == HardwareMonitoring) {
for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
(*chan)->source.request_jack_monitors_input (!(_session.config.get_auto_input() && rolling));
(*chan)->source.request_input_monitoring (!(_session.config.get_auto_input() && rolling));
capturing_sources.push_back ((*chan)->write_source);
(*chan)->write_source->mark_streaming_write_started ();
}
@@ -1775,7 +1775,7 @@ AudioDiskstream::prep_record_disable ()
boost::shared_ptr<ChannelList> c = channels.reader();
if (Config->get_monitoring_model() == HardwareMonitoring) {
for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
(*chan)->source.request_jack_monitors_input (false);
(*chan)->source.request_input_monitoring (false);
}
}
capturing_sources.clear ();
@@ -2041,12 +2041,12 @@ AudioDiskstream::allocate_temporary_buffers ()
}
void
AudioDiskstream::request_jack_monitors_input (bool yn)
AudioDiskstream::request_input_monitoring (bool yn)
{
boost::shared_ptr<ChannelList> c = channels.reader();
for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
(*chan)->source.request_jack_monitors_input (yn);
(*chan)->source.request_input_monitoring (yn);
}
}
@@ -2369,13 +2369,13 @@ AudioDiskstream::ChannelSource::is_physical () const
}
void
AudioDiskstream::ChannelSource::request_jack_monitors_input (bool yn) const
AudioDiskstream::ChannelSource::request_input_monitoring (bool yn) const
{
if (name.empty()) {
return;
}
return AudioEngine::instance()->request_jack_monitors_input (name, yn);
return AudioEngine::instance()->request_input_monitoring (name, yn);
}
AudioDiskstream::ChannelInfo::ChannelInfo (framecnt_t playback_bufsize, framecnt_t capture_bufsize, framecnt_t speed_size, framecnt_t wrap_size)

View File

@@ -21,13 +21,17 @@
#include "pbd/stacktrace.h"
#include "ardour/audio_buffer.h"
#include "ardour/audioengine.h"
#include "ardour/audio_port.h"
#include "ardour/data_type.h"
#include "ardour/port_engine.h"
using namespace ARDOUR;
using namespace std;
AudioPort::AudioPort (const std::string& name, Flags flags)
#define port_engine AudioEngine::instance()->port_engine()
AudioPort::AudioPort (const std::string& name, PortFlags flags)
: Port (name, DataType::AUDIO, flags)
, _buffer (new AudioBuffer (0))
{
@@ -73,7 +77,7 @@ AudioBuffer&
AudioPort::get_audio_buffer (pframes_t nframes)
{
/* caller must hold process lock */
_buffer->set_data ((Sample *) jack_port_get_buffer (_jack_port, _cycle_nframes) +
_buffer->set_data ((Sample *) port_engine.get_buffer (_port_handle, _cycle_nframes) +
_global_port_buffer_offset + _port_buffer_offset, nframes);
return *_buffer;
}
@@ -82,7 +86,7 @@ Sample*
AudioPort::engine_get_whole_audio_buffer ()
{
/* caller must hold process lock */
return (Sample *) jack_port_get_buffer (_jack_port, _cycle_nframes);
return (Sample *) port_engine.get_buffer (_port_handle, _cycle_nframes);
}

View File

@@ -96,7 +96,7 @@ AudioTrack::set_diskstream (boost::shared_ptr<Diskstream> ds)
}
_diskstream->set_record_enabled (false);
_diskstream->request_jack_monitors_input (false);
_diskstream->request_input_monitoring (false);
DiskstreamChanged (); /* EMIT SIGNAL */
}
@@ -315,7 +315,7 @@ AudioTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_fram
if (!lm.locked()) {
boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
framecnt_t playback_distance = diskstream->calculate_playback_distance(nframes);
if (can_internal_playback_seek(llabs(playback_distance))) {
if (can_internal_playback_seek(std::llabs(playback_distance))) {
/* TODO should declick */
internal_playback_seek(playback_distance);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,45 @@
/*
Copyright (C) 2013 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 <glibmm/miscutils.h>
#include "ardour/backend_search_path.h"
#include "ardour/directory_names.h"
#include "ardour/filesystem_paths.h"
namespace {
const char * const backend_env_variable_name = "ARDOUR_BACKEND_PATH";
} // anonymous
using namespace PBD;
namespace ARDOUR {
SearchPath
backend_search_path ()
{
SearchPath spath(user_config_directory ());
spath += ardour_dll_directory ();
spath.add_subdirectory_to_paths(backend_dir_name);
spath += SearchPath(Glib::getenv(backend_env_variable_name));
return spath;
}
} // namespace ARDOUR

View File

@@ -90,7 +90,7 @@ BufferSet::clear()
/** Set up this BufferSet so that its data structures mirror a PortSet's buffers.
* This is quite expensive and not RT-safe, so it should not be called in a process context;
* get_jack_port_addresses() will fill in a structure set up by this method.
* get_backend_port_addresses() will fill in a structure set up by this method.
*
* XXX: this *is* called in a process context; I'm not sure quite what `should not' means above.
*/
@@ -114,13 +114,13 @@ BufferSet::attach_buffers (PortSet& ports)
_is_mirror = true;
}
/** Write the JACK port addresses from a PortSet into our data structures. This
/** Write the backend port addresses from a PortSet into our data structures. This
* call assumes that attach_buffers() has already been called for the same PortSet.
* Does not allocate, so RT-safe BUT you can only call Port::get_buffer() from
* the process() callback tree anyway, so this has to be called in RT context.
*/
void
BufferSet::get_jack_port_addresses (PortSet& ports, framecnt_t nframes)
BufferSet::get_backend_port_addresses (PortSet& ports, framecnt_t nframes)
{
assert (_count == ports.count ());
assert (_available == ports.count ());

View File

@@ -443,27 +443,26 @@ Bundle::connected_to (boost::shared_ptr<Bundle> other, AudioEngine & engine)
return true;
}
/** This must not be called in code executed as a response to a JACK event,
* as it uses jack_port_get_all_connections().
/** This must not be called in code executed as a response to a backend event,
* as it uses the backend port_get_all_connections().
* @return true if any of this bundle's channels are connected to anything.
*/
bool
Bundle::connected_to_anything (AudioEngine& engine)
{
PortManager& pm (engine);
for (uint32_t i = 0; i < nchannels().n_total(); ++i) {
Bundle::PortList const & ports = channel_ports (i);
for (uint32_t j = 0; j < ports.size(); ++j) {
/* ports[j] may not be an Ardour port, so use JACK directly
/* ports[j] may not be an Ardour port, so use the port manager directly
rather than doing it with Port.
*/
jack_port_t* jp = jack_port_by_name (engine.jack(), ports[j].c_str());
if (jp) {
const char ** c = jack_port_get_all_connections (engine.jack(), jp);
if (c) {
jack_free (c);
return true;
}
if (pm.connected (ports[j])) {
return true;
}
}
}

View File

@@ -185,7 +185,7 @@ Butler::thread_work ()
break;
case Request::Quit:
pthread_exit_pbd (0);
return 0;
/*NOTREACHED*/
break;
@@ -327,8 +327,6 @@ restart:
empty_pool_trash ();
}
pthread_exit_pbd (0);
/*NOTREACHED*/
return (0);
}
@@ -403,6 +401,7 @@ Butler::empty_pool_trash ()
void
Butler::drop_references ()
{
cerr << "Butler drops pool trash\n";
SessionEvent::pool->set_trash (0);
}

View File

@@ -28,7 +28,7 @@ namespace ARDOUR {
CapturingProcessor::CapturingProcessor (Session & session)
: Processor (session, X_("capture point"))
, block_size (session.engine().frames_per_cycle())
, block_size (AudioEngine::instance()->samples_per_cycle())
{
realloc_buffers ();
}

View File

@@ -60,5 +60,6 @@ uint64_t PBD::DEBUG::TempoMap = PBD::new_debug_bit ("tempomap");
uint64_t PBD::DEBUG::OrderKeys = PBD::new_debug_bit ("orderkeys");
uint64_t PBD::DEBUG::Automation = PBD::new_debug_bit ("automation");
uint64_t PBD::DEBUG::WiimoteControl = PBD::new_debug_bit ("wiimotecontrol");
uint64_t PBD::DEBUG::Ports = PBD::new_debug_bit ("Ports");

View File

@@ -245,7 +245,7 @@ Delivery::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pf
processing pathway that wants to use this->output_buffers() for some reason.
*/
output_buffers().get_jack_port_addresses (ports, nframes);
output_buffers().get_backend_port_addresses (ports, nframes);
// this Delivery processor is not a derived type, and thus we assume
// we really can modify the buffers passed in (it is almost certainly

View File

@@ -37,6 +37,7 @@ const char* const templates_dir_name = X_("templates");
const char* const route_templates_dir_name = X_("route_templates");
const char* const surfaces_dir_name = X_("surfaces");
const char* const panner_dir_name = X_("panners");
const char* const backend_dir_name = X_("backends");
/* these should end up using variants of PROGRAM_NAME */
#ifdef __APPLE__

View File

@@ -509,6 +509,7 @@ setup_enum_writer ()
REGISTER_CLASS_ENUM (ExportFormatBase, F_RAW);
REGISTER_CLASS_ENUM (ExportFormatBase, F_FLAC);
REGISTER_CLASS_ENUM (ExportFormatBase, F_Ogg);
REGISTER_CLASS_ENUM (ExportFormatBase, F_CAF);
REGISTER (_ExportFormatBase_FormatId);
REGISTER_CLASS_ENUM (ExportFormatBase, E_FileDefault);

View File

@@ -117,7 +117,7 @@ RegionExportChannelFactory::RegionExportChannelFactory (Session * session, Audio
: region (region)
, track (track)
, type (type)
, frames_per_cycle (session->engine().frames_per_cycle ())
, frames_per_cycle (session->engine().samples_per_cycle ())
, buffers_up_to_date (false)
, region_start (region.position())
, position (region_start)

View File

@@ -178,6 +178,17 @@ ExportFormatManager::init_formats ()
fl_ptr->set_extension ("w64");
add_format (f_ptr);
f_ptr.reset (fl_ptr = new ExportFormatLinear ("CAF", ExportFormatBase::F_CAF));
fl_ptr->add_sample_format (ExportFormatBase::SF_U8);
fl_ptr->add_sample_format (ExportFormatBase::SF_16);
fl_ptr->add_sample_format (ExportFormatBase::SF_24);
fl_ptr->add_sample_format (ExportFormatBase::SF_32);
fl_ptr->add_sample_format (ExportFormatBase::SF_Float);
fl_ptr->add_sample_format (ExportFormatBase::SF_Double);
fl_ptr->set_default_sample_format (ExportFormatBase::SF_Float);
fl_ptr->set_extension ("caf");
add_format (f_ptr);
f_ptr.reset (fl_ptr = new ExportFormatLinear ("RAW", ExportFormatBase::F_RAW));
fl_ptr->add_sample_format (ExportFormatBase::SF_U8);
fl_ptr->add_sample_format (ExportFormatBase::SF_8);

View File

@@ -54,7 +54,7 @@ ExportGraphBuilder::ExportGraphBuilder (Session const & session)
: session (session)
, thread_pool (hardware_concurrency())
{
process_buffer_frames = session.engine().frames_per_cycle();
process_buffer_frames = session.engine().samples_per_cycle();
}
ExportGraphBuilder::~ExportGraphBuilder ()
@@ -505,7 +505,7 @@ ExportGraphBuilder::ChannelConfig::ChannelConfig (ExportGraphBuilder & parent, F
config = new_config;
framecnt_t max_frames = parent.session.engine().frames_per_cycle();
framecnt_t max_frames = parent.session.engine().samples_per_cycle();
interleaver.reset (new Interleaver<Sample> ());
interleaver->init (new_config.channel_config->get_n_chans(), max_frames);

View File

@@ -29,6 +29,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <time.h>
#ifdef WINDOWS_VST_SUPPORT
#include <fst.h>
@@ -66,11 +67,11 @@
#include "pbd/basename.h"
#include "midi++/port.h"
#include "midi++/manager.h"
#include "midi++/mmc.h"
#include "ardour/analyser.h"
#include "ardour/audio_library.h"
#include "ardour/audio_backend.h"
#include "ardour/audioengine.h"
#include "ardour/audioplaylist.h"
#include "ardour/audioregion.h"
@@ -78,6 +79,7 @@
#include "ardour/control_protocol_manager.h"
#include "ardour/filesystem_paths.h"
#include "ardour/midi_region.h"
#include "ardour/midiport_manager.h"
#include "ardour/mix.h"
#include "ardour/panner_manager.h"
#include "ardour/plugin_manager.h"
@@ -330,6 +332,8 @@ ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir
EventTypeMap::instance().new_parameter(EnvelopeAutomation);
EventTypeMap::instance().new_parameter(MidiCCAutomation);
ARDOUR::AudioEngine::create ();
libardour_initialized = true;
return true;
@@ -338,9 +342,6 @@ ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir
void
ARDOUR::init_post_engine ()
{
/* the MIDI Manager is needed by the ControlProtocolManager */
MIDI::Manager::create (AudioEngine::instance()->jack());
ControlProtocolManager::instance().discover_control_protocols ();
XMLNode* node;
@@ -536,3 +537,43 @@ ARDOUR::get_available_sync_options ()
return ret;
}
/** Return a monotonic value for the number of microseconds that have elapsed
* since an arbitrary zero origin.
*/
#ifdef __MACH__
/* Thanks Apple for not implementing this basic SUSv2, POSIX.1-2001 function
*/
#include <mach/mach_time.h>
#define CLOCK_REALTIME 0
#define CLOCK_MONOTONIC 0
int
clock_gettime (int /*clk_id*/, struct timespec *t)
{
static bool initialized = false;
static mach_timebase_info_data_t timebase;
if (!initialized) {
mach_timebase_info(&timebase);
initialized = true;
}
uint64_t time;
time = mach_absolute_time();
double nseconds = ((double)time * (double)timebase.numer)/((double)timebase.denom);
double seconds = ((double)time * (double)timebase.numer)/((double)timebase.denom * 1e9);
t->tv_sec = seconds;
t->tv_nsec = nseconds;
return 0;
}
#endif
microseconds_t
ARDOUR::get_microseconds ()
{
struct timespec ts;
if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) {
/* EEEK! */
return 0;
}
return (microseconds_t) ts.tv_sec * 1000000 + (ts.tv_nsec/1000);
}

View File

@@ -101,7 +101,7 @@ Graph::reset_thread_list ()
}
Glib::Threads::Mutex::Lock lm (_session.engine().process_lock());
pthread_t a_thread;
AudioBackendNativeThread a_thread;
if (!_thread_list.empty()) {
drop_threads ();
@@ -146,9 +146,8 @@ Graph::drop_threads ()
_callback_start_sem.signal ();
for (list<pthread_t>::iterator i = _thread_list.begin(); i != _thread_list.end(); ++i) {
void* status;
pthread_join (*i, &status);
for (list<AudioBackendNativeThread>::iterator i = _thread_list.begin(); i != _thread_list.end(); ++i) {
AudioEngine::instance()->wait_for_process_thread_exit (*i);
}
_thread_list.clear ();
@@ -584,8 +583,8 @@ Graph::process_one_route (Route* route)
bool
Graph::in_process_thread () const
{
for (list<pthread_t>::const_iterator i = _thread_list.begin (); i != _thread_list.end(); ++i) {
if (*i == pthread_self()) {
for (list<AudioBackendNativeThread>::const_iterator i = _thread_list.begin (); i != _thread_list.end(); ++i) {
if (self_thread_equal (*i)) {
return true;
}
}

View File

@@ -45,8 +45,8 @@ void Iec1ppmdsp::process (float *p, int n)
{
float z1, z2, m, t;
z1 = _z1;
z2 = _z2;
z1 = _z1 > 20 ? 20 : (_z1 < 0 ? 0 : _z1);
z2 = _z2 > 20 ? 20 : (_z2 < 0 ? 0 : _z2);
m = _res ? 0: _m;
_res = false;

View File

@@ -45,8 +45,8 @@ void Iec2ppmdsp::process (float *p, int n)
{
float z1, z2, m, t;
z1 = _z1;
z2 = _z2;
z1 = _z1 > 20 ? 20 : (_z1 < 0 ? 0 : _z1);
z2 = _z2 > 20 ? 20 : (_z2 < 0 ? 0 : _z2);
m = _res ? 0: _m;
_res = false;

View File

@@ -310,7 +310,7 @@ bool
InternalSend::configure_io (ChanCount in, ChanCount out)
{
bool ret = Send::configure_io (in, out);
set_block_size (_session.engine().frames_per_cycle());
set_block_size (_session.engine().samples_per_cycle());
return ret;
}

View File

@@ -135,17 +135,18 @@ CubicInterpolation::interpolate (int channel, framecnt_t nframes, Sample *input,
inm1 = input[i];
}
i = floor(distance);
phase[channel] = distance - floor(distance);
} else {
/* not sure that this is ever utilized - it implies that one of the input/output buffers is missing */
/* used to calculate play-distance with acceleration (silent roll)
* (use same algorithm as real playback for identical rounding/floor'ing)
*/
for (framecnt_t outsample = 0; outsample < nframes; ++outsample) {
distance += _speed + acceleration;
}
i = floor(distance);
}
i = floor(distance);
phase[channel] = distance - floor(distance);
return i;
}

View File

@@ -1337,7 +1337,7 @@ IO::bundle_changed (Bundle::Change /*c*/)
string
IO::build_legal_port_name (DataType type)
{
const int name_size = jack_port_name_size();
const int name_size = AudioEngine::instance()->port_name_size();
int limit;
string suffix;
@@ -1371,7 +1371,7 @@ IO::build_legal_port_name (DataType type)
// allow up to 4 digits for the output port number, plus the slash, suffix and extra space
limit = name_size - _session.engine().client_name().length() - (suffix.length() + 5);
limit = name_size - AudioEngine::instance()->my_name().length() - (suffix.length() + 5);
char buf1[name_size+1];
char buf2[name_size+1];
@@ -1404,10 +1404,11 @@ IO::find_port_hole (const char* base)
*/
for (n = 1; n < 9999; ++n) {
char buf[jack_port_name_size()];
size_t size = AudioEngine::instance()->port_name_size() + 1;
char buf[size];
PortSet::iterator i = _ports.begin();
snprintf (buf, jack_port_name_size(), _("%s %u"), base, n);
snprintf (buf, size, _("%s %u"), base, n);
for ( ; i != _ports.end(); ++i) {
if (i->name() == buf) {
@@ -1638,7 +1639,7 @@ IO::process_input (boost::shared_ptr<Processor> proc, framepos_t start_frame, fr
return;
}
_buffers.get_jack_port_addresses (_ports, nframes);
_buffers.get_backend_port_addresses (_ports, nframes);
if (proc) {
proc->run (_buffers, start_frame, end_frame, nframes, true);
}

View File

@@ -20,16 +20,14 @@
#include <iostream>
#include <cerrno>
#include <jack/jack.h>
#include <jack/transport.h>
#include "ardour/audioengine.h"
#include "ardour/slave.h"
using namespace std;
using namespace ARDOUR;
JACK_Slave::JACK_Slave (jack_client_t* j)
: jack (j)
JACK_Slave::JACK_Slave (AudioEngine& e)
: engine (e)
{
double x;
framepos_t p;
@@ -41,12 +39,6 @@ JACK_Slave::~JACK_Slave ()
{
}
void
JACK_Slave::reset_client (jack_client_t* j)
{
jack = j;
}
bool
JACK_Slave::locked() const
{
@@ -62,33 +54,26 @@ JACK_Slave::ok() const
bool
JACK_Slave::speed_and_position (double& sp, framepos_t& position)
{
jack_position_t pos;
jack_transport_state_t state;
state = jack_transport_query (jack, &pos);
switch (state) {
case JackTransportStopped:
switch (engine.transport_state()) {
case TransportStopped:
speed = 0;
_starting = false;
break;
case JackTransportRolling:
case TransportRolling:
speed = 1.0;
_starting = false;
break;
case JackTransportLooping:
case TransportLooping:
speed = 1.0;
_starting = false;
break;
case JackTransportStarting:
case TransportStarting:
_starting = true;
// don't adjust speed here, just leave it as it was
break;
default:
cerr << "WARNING: Unknown JACK transport state: " << state << endl;
}
sp = speed;
position = pos.frame;
position = engine.transport_frame();
return true;
}

View File

@@ -52,8 +52,8 @@ void Kmeterdsp::process (float *p, int n)
float s, z1, z2;
// Get filter state.
z1 = _z1;
z2 = _z2;
z1 = _z1 > 50 ? 50 : (_z1 < 0 ? 0 : _z1);
z2 = _z2 > 50 ? 50 : (_z2 < 0 ? 0 : _z2);
// Perform filtering. The second filter is evaluated
// only every 4th sample - this is just an optimisation.
@@ -75,6 +75,8 @@ void Kmeterdsp::process (float *p, int n)
z2 += 4 * _omega * (z1 - z2); // Update second filter.
}
if (isnan(z1)) z1 = 0;
if (isnan(z2)) z2 = 0;
// Save filter state. The added constants avoid denormals.
_z1 = z1 + 1e-20f;
_z2 = z2 + 1e-20f;

View File

@@ -36,8 +36,6 @@
#include "pbd/xml++.h"
#include "pbd/stacktrace.h"
#include "midi++/manager.h"
#include "ardour/session.h"
#include "ardour/ladspa_plugin.h"
#include "ardour/buffer_set.h"
@@ -114,7 +112,9 @@ LadspaPlugin::init (void *mod, uint32_t index, framecnt_t rate)
port_cnt = parameter_count();
_control_data = new LADSPA_Data[port_cnt];
memset (_control_data, 0, sizeof (LADSPA_Data) * port_cnt);
_shadow_data = new LADSPA_Data[port_cnt];
memset (_shadow_data, 0, sizeof (LADSPA_Data) * port_cnt);
for (i = 0; i < port_cnt; ++i) {
if (LADSPA_IS_PORT_CONTROL(port_descriptor (i))) {

View File

@@ -134,7 +134,7 @@ LTC_Slave::resync_latency()
if (!session.deletion_in_progress() && session.ltc_output_io()) { /* check if Port exits */
boost::shared_ptr<Port> ltcport = session.ltc_input_port();
ltcport->get_connected_latency_range(ltc_slave_latency, false);
ltcport->get_connected_latency_range (ltc_slave_latency, false);
}
}
@@ -150,9 +150,9 @@ LTC_Slave::reset()
}
void
LTC_Slave::parse_ltc(const jack_nframes_t nframes, const jack_default_audio_sample_t * const in, const framecnt_t posinfo)
LTC_Slave::parse_ltc(const pframes_t nframes, const Sample* const in, const framecnt_t posinfo)
{
jack_nframes_t i;
pframes_t i;
unsigned char sound[8192];
if (nframes > 8192) {
/* TODO warn once or wrap, loop conversion below
@@ -413,22 +413,22 @@ LTC_Slave::init_engine_dll (framepos_t pos, int32_t inc)
}
/* main entry point from session_process.cc
* called from jack_process callback context
* so it is OK to use jack_port_get_buffer()
* called from process callback context
* so it is OK to use get_buffer()
*/
bool
LTC_Slave::speed_and_position (double& speed, framepos_t& pos)
{
bool engine_init_called = false;
framepos_t now = session.engine().frame_time_at_cycle_start();
framepos_t now = session.engine().sample_time_at_cycle_start();
framepos_t sess_pos = session.transport_frame(); // corresponds to now
framecnt_t nframes = session.engine().frames_per_cycle();
framecnt_t nframes = session.engine().samples_per_cycle();
jack_default_audio_sample_t *in;
Sample* in;
boost::shared_ptr<Port> ltcport = session.ltc_input_port();
in = (jack_default_audio_sample_t*) jack_port_get_buffer (ltcport->jack_port(), nframes);
in = (Sample*) AudioEngine::instance()->port_engine().get_buffer (ltcport->port_handle(), nframes);
frameoffset_t skip = now - (monotonic_cnt + nframes);
monotonic_cnt = now;
@@ -441,7 +441,7 @@ LTC_Slave::speed_and_position (double& speed, framepos_t& pos)
else if (engine_dll_initstate != transport_direction && ltc_speed != 0) {
engine_dll_initstate = transport_direction;
init_engine_dll(last_ltc_frame + rint(ltc_speed * double(2 * nframes + now - last_timestamp)),
session.engine().frames_per_cycle());
session.engine().samples_per_cycle());
engine_init_called = true;
}
@@ -521,8 +521,8 @@ LTC_Slave::speed_and_position (double& speed, framepos_t& pos)
t0 = t1;
t1 += b * e + e2;
e2 += c * e;
speed_flt = (t1 - t0) / double(session.engine().frames_per_cycle());
DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC engine DLL t0:%1 t1:%2 err:%3 spd:%4 ddt:%5\n", t0, t1, e, speed_flt, e2 - session.engine().frames_per_cycle() ));
speed_flt = (t1 - t0) / double(session.engine().samples_per_cycle());
DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC engine DLL t0:%1 t1:%2 err:%3 spd:%4 ddt:%5\n", t0, t1, e, speed_flt, e2 - session.engine().samples_per_cycle() ));
} else {
DEBUG_TRACE (DEBUG::LTC, string_compose ("LTC adjusting elapsed (no DLL) from %1 by %2\n", elapsed, (2 * nframes * ltc_speed)));
speed_flt = 0;

View File

@@ -142,6 +142,7 @@ public:
LilvNode* time_Position;
LilvNode* ui_GtkUI;
LilvNode* ui_external;
LilvNode* ui_externalkx;
private:
bool _bundle_checked;
@@ -289,7 +290,7 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate)
_latency_control_port = 0;
_next_cycle_start = std::numeric_limits<framepos_t>::max();
_next_cycle_speed = 1.0;
_block_length = _engine.frames_per_cycle();
_block_length = _engine.samples_per_cycle();
_seq_size = _engine.raw_buffer_size(DataType::MIDI);
_state_version = 0;
_was_activated = false;
@@ -561,11 +562,15 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate)
if (!_impl->ui) {
LILV_FOREACH(uis, i, uis) {
const LilvUI* ui = lilv_uis_get(uis, i);
if (lilv_ui_is_a(ui, _world.ui_external)) {
if (lilv_ui_is_a(ui, _world.ui_externalkx)) {
_impl->ui = ui;
_impl->ui_type = _world.ui_external;
break;
}
if (lilv_ui_is_a(ui, _world.ui_external)) {
_impl->ui = ui;
_impl->ui_type = _world.ui_external;
}
}
}
}
@@ -613,7 +618,16 @@ LV2Plugin::is_external_ui() const
if (!_impl->ui) {
return false;
}
return lilv_ui_is_a(_impl->ui, _world.ui_external);
return lilv_ui_is_a(_impl->ui, _world.ui_external) || lilv_ui_is_a(_impl->ui, _world.ui_externalkx);
}
bool
LV2Plugin::is_external_kx() const
{
if (!_impl->ui) {
return false;
}
return lilv_ui_is_a(_impl->ui, _world.ui_externalkx);
}
bool
@@ -1367,11 +1381,6 @@ LV2Plugin::describe_parameter(Evoral::Parameter which)
return X_("hidden");
}
if (lilv_port_has_property(_impl->plugin,
lilv_plugin_get_port_by_index(_impl->plugin, which.id()), _world.lv2_sampleRate)) {
return X_("hidden");
}
if (lilv_port_has_property(_impl->plugin,
lilv_plugin_get_port_by_index(_impl->plugin, which.id()), _world.lv2_reportsLatency)) {
return X_("latency");
@@ -1915,7 +1924,7 @@ LV2Plugin::Impl::designated_input (const char* uri, void** bufptrs[], void** buf
return port;
}
static bool lv2_filter (const string& str, void * /* arg*/)
static bool lv2_filter (const string& str, void* /*arg*/)
{
/* Not a dotfile, has a prefix before a period, suffix is "lv2" */
@@ -1955,10 +1964,12 @@ LV2World::LV2World()
time_Position = lilv_new_uri(world, LV2_TIME__Position);
ui_GtkUI = lilv_new_uri(world, LV2_UI__GtkUI);
ui_external = lilv_new_uri(world, "http://lv2plug.in/ns/extensions/ui#external");
ui_externalkx = lilv_new_uri(world, "http://kxstudio.sf.net/ns/lv2ext/external-ui#Widget");
}
LV2World::~LV2World()
{
lilv_node_free(ui_externalkx);
lilv_node_free(ui_external);
lilv_node_free(ui_GtkUI);
lilv_node_free(time_Position);

View File

@@ -22,6 +22,7 @@
#include "pbd/malign.h"
#include "pbd/compose.h"
#include "pbd/debug.h"
#include "pbd/stacktrace.h"
#include "ardour/debug.h"
#include "ardour/midi_buffer.h"
@@ -133,6 +134,7 @@ MidiBuffer::push_back(const Evoral::MIDIEvent<TimeType>& ev)
if (_size + stamp_size + ev.size() >= _capacity) {
cerr << "MidiBuffer::push_back failed (buffer is full)" << endl;
PBD::stacktrace (cerr, 20);
return false;
}
@@ -171,7 +173,9 @@ MidiBuffer::push_back(TimeType time, size_t size, const uint8_t* data)
#endif
if (_size + stamp_size + size >= _capacity) {
cerr << "MidiBuffer::push_back failed (buffer is full)" << endl;
cerr << "MidiBuffer::push_back2 failed (buffer is full; _size = " << _size << " capacity "
<< _capacity << " stamp " << stamp_size << " size = " << size << ")" << endl;
PBD::stacktrace (cerr, 20);
return false;
}
@@ -190,55 +194,6 @@ MidiBuffer::push_back(TimeType time, size_t size, const uint8_t* data)
return true;
}
/** Push an event into the buffer.
*
* Note that the raw MIDI pointed to by ev will be COPIED and unmodified.
* That is, the caller still owns it, if it needs freeing it's Not My Problem(TM).
* Realtime safe.
* @return false if operation failed (not enough room)
*/
bool
MidiBuffer::push_back(const jack_midi_event_t& ev)
{
const size_t stamp_size = sizeof(TimeType);
if (_size + stamp_size + ev.size >= _capacity) {
cerr << "MidiBuffer::push_back failed (buffer is full)" << endl;
return false;
}
if (!Evoral::midi_event_is_valid(ev.buffer, ev.size)) {
cerr << "WARNING: MidiBuffer ignoring illegal MIDI event" << endl;
return false;
}
#ifndef NDEBUG
if (DEBUG::MidiIO & PBD::debug_bits) {
DEBUG_STR_DECL(a);
DEBUG_STR_APPEND(a, string_compose ("midibuffer %1 push jack event @ %2 sz %3 ", this, ev.time, ev.size));
for (size_t i=0; i < ev.size; ++i) {
DEBUG_STR_APPEND(a,hex);
DEBUG_STR_APPEND(a,"0x");
DEBUG_STR_APPEND(a,(int)ev.buffer[i]);
DEBUG_STR_APPEND(a,' ');
}
DEBUG_STR_APPEND(a,'\n');
DEBUG_TRACE (DEBUG::MidiIO, DEBUG_STR(a).str());
}
#endif
uint8_t* const write_loc = _data + _size;
*((TimeType*)write_loc) = ev.time;
memcpy(write_loc + stamp_size, ev.buffer, ev.size);
_size += stamp_size + ev.size;
_silent = false;
return true;
}
/** Reserve space for a new event in the buffer.
*
* This call is for copying MIDI directly into the buffer, the data location

View File

@@ -31,6 +31,8 @@
#include "midi++/port.h"
#include "ardour/debug.h"
#include "ardour/midi_buffer.h"
#include "ardour/midi_port.h"
#include "ardour/slave.h"
#include "ardour/tempo.h"
@@ -41,7 +43,7 @@ using namespace ARDOUR;
using namespace MIDI;
using namespace PBD;
MIDIClock_Slave::MIDIClock_Slave (Session& s, MIDI::Port& p, int ppqn)
MIDIClock_Slave::MIDIClock_Slave (Session& s, MidiPort& p, int ppqn)
: ppqn (ppqn)
, bandwidth (10.0 / 60.0) // 1 BpM = 1 / 60 Hz
{
@@ -64,19 +66,18 @@ MIDIClock_Slave::~MIDIClock_Slave()
}
void
MIDIClock_Slave::rebind (MIDI::Port& p)
MIDIClock_Slave::rebind (MidiPort& port)
{
port_connections.drop_connections();
DEBUG_TRACE (DEBUG::MidiClock, string_compose ("MIDIClock_Slave: connecting to port %1\n", port.name()));
port = &p;
port_connections.drop_connections ();
DEBUG_TRACE (DEBUG::MidiClock, string_compose ("MIDIClock_Slave: connecting to port %1\n", port->name()));
port.self_parser().timing.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::update_midi_clock, this, _1, _2));
port.self_parser().start.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::start, this, _1, _2));
port.self_parser().contineu.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::contineu, this, _1, _2));
port.self_parser().stop.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::stop, this, _1, _2));
port.self_parser().position.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::position, this, _1, _2, 3));
port->parser()->timing.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::update_midi_clock, this, _1, _2));
port->parser()->start.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::start, this, _1, _2));
port->parser()->contineu.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::contineu, this, _1, _2));
port->parser()->stop.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::stop, this, _1, _2));
port->parser()->position.connect_same_thread (port_connections, boost::bind (&MIDIClock_Slave::position, this, _1, _2, 3));
}
void

View File

@@ -202,8 +202,8 @@ MidiDiskstream::non_realtime_input_change ()
seek (_session.transport_frame());
}
g_atomic_int_set(const_cast<gint*>(&_frames_pending_write), 0);
g_atomic_int_set(const_cast<gint*>(&_num_captured_loops), 0);
g_atomic_int_set(const_cast<gint*> (&_frames_pending_write), 0);
g_atomic_int_set(const_cast<gint*> (&_num_captured_loops), 0);
}
int
@@ -376,8 +376,8 @@ MidiDiskstream::process (BufferSet& bufs, framepos_t transport_frame, pframes_t
}
_write_source->mark_write_starting_now(
capture_start_frame, capture_captured, loop_length);
g_atomic_int_set(const_cast<gint*>(&_frames_pending_write), 0);
g_atomic_int_set(const_cast<gint*>(&_num_captured_loops), 0);
g_atomic_int_set(const_cast<gint*> (&_frames_pending_write), 0);
g_atomic_int_set(const_cast<gint*> (&_num_captured_loops), 0);
was_recording = true;
}
}
@@ -799,7 +799,7 @@ MidiDiskstream::do_flush (RunContext /*context*/, bool force_flush)
return 0;
}
const framecnt_t total = g_atomic_int_get(const_cast<gint*>(&_frames_pending_write));
const framecnt_t total = g_atomic_int_get(const_cast<gint*> (&_frames_pending_write));
if (total == 0 ||
_capture_buf->read_space() == 0 ||
@@ -834,7 +834,7 @@ MidiDiskstream::do_flush (RunContext /*context*/, bool force_flush)
error << string_compose(_("MidiDiskstream %1: cannot write to disk"), id()) << endmsg;
return -1;
}
g_atomic_int_add(const_cast<gint*>(&_frames_pending_write), -to_write);
g_atomic_int_add(const_cast<gint*> (&_frames_pending_write), -to_write);
}
out:
@@ -1044,7 +1044,7 @@ MidiDiskstream::transport_looped (framepos_t)
the Source and/or entirely after the capture is finished.
*/
if (was_recording) {
g_atomic_int_add(const_cast<gint*>(&_num_captured_loops), 1);
g_atomic_int_add(const_cast<gint*> (&_num_captured_loops), 1);
}
}
@@ -1111,7 +1111,7 @@ MidiDiskstream::prep_record_enable ()
boost::shared_ptr<MidiPort> sp = _source_port.lock ();
if (sp && Config->get_monitoring_model() == HardwareMonitoring) {
sp->request_jack_monitors_input (!(_session.config.get_auto_input() && rolling));
sp->request_input_monitoring (!(_session.config.get_auto_input() && rolling));
}
return true;
@@ -1259,12 +1259,12 @@ MidiDiskstream::allocate_temporary_buffers ()
}
void
MidiDiskstream::ensure_jack_monitors_input (bool yn)
MidiDiskstream::ensure_input_monitoring (bool yn)
{
boost::shared_ptr<MidiPort> sp = _source_port.lock ();
if (sp) {
sp->ensure_jack_monitors_input (yn);
sp->ensure_input_monitoring (yn);
}
}

View File

@@ -26,11 +26,14 @@
using namespace ARDOUR;
using namespace std;
MidiPort::MidiPort (const std::string& name, Flags flags)
#define port_engine AudioEngine::instance()->port_engine()
MidiPort::MidiPort (const std::string& name, PortFlags flags)
: Port (name, DataType::MIDI, flags)
, _has_been_mixed_down (false)
, _resolve_required (false)
, _input_active (true)
, _always_parse (false)
{
_buffer = new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI));
}
@@ -43,12 +46,32 @@ MidiPort::~MidiPort()
void
MidiPort::cycle_start (pframes_t nframes)
{
framepos_t now = AudioEngine::instance()->sample_time_at_cycle_start();
Port::cycle_start (nframes);
_buffer->clear ();
if (sends_output ()) {
jack_midi_clear_buffer (jack_port_get_buffer (_jack_port, nframes));
port_engine.midi_clear (port_engine.get_buffer (_port_handle, nframes));
}
if (_always_parse) {
MidiBuffer& mb (get_midi_buffer (nframes));
/* dump incoming MIDI to parser */
for (MidiBuffer::iterator b = mb.begin(); b != mb.end(); ++b) {
uint8_t* buf = (*b).buffer();
_self_parser.set_timestamp (now + (*b).time());
uint32_t limit = (*b).size();
for (size_t n = 0; n < limit; ++n) {
_self_parser.scanner (buf[n]);
}
}
}
}
@@ -63,31 +86,33 @@ MidiPort::get_midi_buffer (pframes_t nframes)
if (_input_active) {
void* jack_buffer = jack_port_get_buffer (_jack_port, nframes);
const pframes_t event_count = jack_midi_get_event_count (jack_buffer);
/* suck all relevant MIDI events from the JACK MIDI port buffer
void* buffer = port_engine.get_buffer (_port_handle, nframes);
const pframes_t event_count = port_engine.get_midi_event_count (buffer);
/* suck all relevant MIDI events from the MIDI port buffer
into our MidiBuffer
*/
for (pframes_t i = 0; i < event_count; ++i) {
jack_midi_event_t ev;
pframes_t timestamp;
size_t size;
uint8_t* buf;
jack_midi_event_get (&ev, jack_buffer, i);
port_engine.midi_event_get (timestamp, size, &buf, buffer, i);
if (ev.buffer[0] == 0xfe) {
if (buf[0] == 0xfe) {
/* throw away active sensing */
continue;
}
/* check that the event is in the acceptable time range */
if ((ev.time >= (_global_port_buffer_offset + _port_buffer_offset)) &&
(ev.time < (_global_port_buffer_offset + _port_buffer_offset + nframes))) {
_buffer->push_back (ev);
if ((timestamp >= (_global_port_buffer_offset + _port_buffer_offset)) &&
(timestamp < (_global_port_buffer_offset + _port_buffer_offset + nframes))) {
_buffer->push_back (timestamp, size, buf);
} else {
cerr << "Dropping incoming MIDI at time " << ev.time << "; offset="
cerr << "Dropping incoming MIDI at time " << timestamp << "; offset="
<< _global_port_buffer_offset << " limit="
<< (_global_port_buffer_offset + _port_buffer_offset + nframes) << "\n";
}
@@ -121,7 +146,7 @@ MidiPort::cycle_split ()
}
void
MidiPort::resolve_notes (void* jack_buffer, MidiBuffer::TimeType when)
MidiPort::resolve_notes (void* port_buffer, MidiBuffer::TimeType when)
{
for (uint8_t channel = 0; channel <= 0xF; channel++) {
@@ -132,13 +157,13 @@ MidiPort::resolve_notes (void* jack_buffer, MidiBuffer::TimeType when)
* that prioritize sustain over AllNotesOff
*/
if (jack_midi_event_write (jack_buffer, when, ev, 3) != 0) {
if (port_engine.midi_event_put (port_buffer, when, ev, 3) != 0) {
cerr << "failed to deliver sustain-zero on channel " << channel << " on port " << name() << endl;
}
ev[1] = MIDI_CTL_ALL_NOTES_OFF;
if (jack_midi_event_write (jack_buffer, 0, ev, 3) != 0) {
if (port_engine.midi_event_put (port_buffer, 0, ev, 3) != 0) {
cerr << "failed to deliver ALL NOTES OFF on channel " << channel << " on port " << name() << endl;
}
}
@@ -149,11 +174,11 @@ MidiPort::flush_buffers (pframes_t nframes)
{
if (sends_output ()) {
void* jack_buffer = jack_port_get_buffer (_jack_port, nframes);
void* port_buffer = port_engine.get_buffer (_port_handle, nframes);
if (_resolve_required) {
/* resolve all notes at the start of the buffer */
resolve_notes (jack_buffer, 0);
resolve_notes (port_buffer, 0);
_resolve_required = false;
}
@@ -166,7 +191,7 @@ MidiPort::flush_buffers (pframes_t nframes)
assert (ev.time() < (nframes + _global_port_buffer_offset + _port_buffer_offset));
if (ev.time() >= _global_port_buffer_offset + _port_buffer_offset) {
if (jack_midi_event_write (jack_buffer, (jack_nframes_t) ev.time(), ev.buffer(), ev.size()) != 0) {
if (port_engine.midi_event_put (port_buffer, (pframes_t) ev.time(), ev.buffer(), ev.size()) != 0) {
cerr << "write failed, drop flushed note off on the floor, time "
<< ev.time() << " > " << _global_port_buffer_offset + _port_buffer_offset << endl;
}
@@ -202,6 +227,7 @@ MidiPort::reset ()
{
Port::reset ();
delete _buffer;
cerr << name() << " new MIDI buffer of size " << AudioEngine::instance()->raw_buffer_size (DataType::MIDI) << endl;
_buffer = new MidiBuffer (AudioEngine::instance()->raw_buffer_size (DataType::MIDI));
}
@@ -210,3 +236,9 @@ MidiPort::set_input_active (bool yn)
{
_input_active = yn;
}
void
MidiPort::set_always_parse (bool yn)
{
_always_parse = yn;
}

View File

@@ -321,7 +321,7 @@ MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame
if (!lm.locked()) {
boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
framecnt_t playback_distance = diskstream->calculate_playback_distance(nframes);
if (can_internal_playback_seek(llabs(playback_distance))) {
if (can_internal_playback_seek(std::llabs(playback_distance))) {
/* TODO should declick, and/or note-off */
internal_playback_seek(playback_distance);
}

View File

@@ -22,11 +22,11 @@
#include "pbd/pthread_utils.h"
#include "midi++/manager.h"
#include "midi++/port.h"
#include "ardour/async_midi_port.h"
#include "ardour/debug.h"
#include "ardour/audioengine.h"
#include "ardour/midi_port.h"
#include "ardour/midiport_manager.h"
#include "ardour/midi_ui.h"
#include "ardour/session.h"
#include "ardour/session_event.h"
@@ -48,7 +48,6 @@ MidiControlUI::MidiControlUI (Session& s)
: AbstractUI<MidiUIRequest> (X_("midiui"))
, _session (s)
{
MIDI::Manager::instance()->PortsChanged.connect_same_thread (rebind_connection, boost::bind (&MidiControlUI::change_midi_ports, this));
_instance = this;
}
@@ -83,20 +82,10 @@ MidiControlUI::do_request (MidiUIRequest* req)
}
}
void
MidiControlUI::change_midi_ports ()
{
MidiUIRequest* req = get_request (PortChange);
if (req == 0) {
return;
}
send_request (req);
}
bool
MidiControlUI::midi_input_handler (IOCondition ioc, MIDI::Port* port)
MidiControlUI::midi_input_handler (IOCondition ioc, AsyncMIDIPort* port)
{
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("something happend on %1\n", port->name()));
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("something happend on %1\n", ((ARDOUR::Port*)port)->name()));
if (ioc & ~IO_IN) {
return false;
@@ -106,8 +95,8 @@ MidiControlUI::midi_input_handler (IOCondition ioc, MIDI::Port* port)
CrossThreadChannel::drain (port->selectable());
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("data available on %1\n", port->name()));
framepos_t now = _session.engine().frame_time();
DEBUG_TRACE (DEBUG::MidiIO, string_compose ("data available on %1\n", ((ARDOUR::Port*)port)->name()));
framepos_t now = _session.engine().sample_time();
port->parse (now);
}
@@ -128,22 +117,19 @@ MidiControlUI::clear_ports ()
void
MidiControlUI::reset_ports ()
{
clear_ports ();
if (port_sources.empty()) {
AsyncMIDIPort* async = dynamic_cast<AsyncMIDIPort*> (_session.midi_input_port());
boost::shared_ptr<const MIDI::Manager::PortList> plist = MIDI::Manager::instance()->get_midi_ports ();
for (MIDI::Manager::PortList::const_iterator i = plist->begin(); i != plist->end(); ++i) {
if (!(*i)->centrally_parsed()) {
continue;
if (!async) {
return;
}
int fd;
if ((fd = (*i)->selectable ()) >= 0) {
if ((fd = async->selectable ()) >= 0) {
Glib::RefPtr<IOSource> psrc = IOSource::create (fd, IO_IN|IO_HUP|IO_ERR);
psrc->connect (sigc::bind (sigc::mem_fun (this, &MidiControlUI::midi_input_handler), *i));
psrc->connect (sigc::bind (sigc::mem_fun (this, &MidiControlUI::midi_input_handler), async));
psrc->attach (_main_loop->get_context());
// glibmm hack: for now, store only the GSource*

View File

@@ -0,0 +1,170 @@
/*
Copyright (C) 1998-99 Paul Barton-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$
*/
#include "ardour/audioengine.h"
#include "ardour/async_midi_port.h"
#include "ardour/midiport_manager.h"
#include "ardour/rc_configuration.h"
#include "i18n.h"
using namespace ARDOUR;
using namespace std;
using namespace MIDI;
using namespace PBD;
MidiPortManager::MidiPortManager ()
{
create_ports ();
}
MidiPortManager::~MidiPortManager ()
{
if (_midi_in) {
AudioEngine::instance()->unregister_port (_midi_in);
}
if (_midi_in) {
AudioEngine::instance()->unregister_port (_midi_in);
}
if (_mtc_input_port) {
AudioEngine::instance()->unregister_port (_mtc_input_port);
}
if (_mtc_output_port) {
AudioEngine::instance()->unregister_port (_mtc_output_port);
}
if (_midi_clock_input_port) {
AudioEngine::instance()->unregister_port (_midi_clock_input_port);
}
if (_midi_clock_output_port) {
AudioEngine::instance()->unregister_port (_midi_clock_output_port);
}
}
void
MidiPortManager::create_ports ()
{
/* this method is idempotent
*/
if (_midi_in) {
return;
}
_midi_in = AudioEngine::instance()->register_input_port (DataType::MIDI, _("MIDI control in"), true);
_midi_out = AudioEngine::instance()->register_output_port (DataType::MIDI, _("MIDI control out"), true);
_mmc_in = AudioEngine::instance()->register_input_port (DataType::MIDI, _("MMC in"), true);
_mmc_out = AudioEngine::instance()->register_output_port (DataType::MIDI, _("MMC out"), true);
/* XXX nasty type conversion needed because of the mixed inheritance
* required to integrate MIDI::IPMidiPort and ARDOUR::AsyncMIDIPort.
*
* At some point, we'll move IPMidiPort into Ardour and make it
* inherit from ARDOUR::MidiPort not MIDI::Port, and then this
* mess can go away
*/
_midi_input_port = boost::dynamic_pointer_cast<AsyncMIDIPort>(_midi_in).get();
_midi_output_port = boost::dynamic_pointer_cast<AsyncMIDIPort>(_midi_out).get();
_mmc_input_port = boost::dynamic_pointer_cast<AsyncMIDIPort>(_mmc_in).get();
_mmc_output_port = boost::dynamic_pointer_cast<AsyncMIDIPort>(_mmc_out).get();
/* Now register ports used for sync (MTC and MIDI Clock)
*/
boost::shared_ptr<ARDOUR::Port> p;
p = AudioEngine::instance()->register_input_port (DataType::MIDI, _("MTC in"));
_mtc_input_port = boost::dynamic_pointer_cast<MidiPort> (p);
p = AudioEngine::instance()->register_output_port (DataType::MIDI, _("MTC out"));
_mtc_output_port= boost::dynamic_pointer_cast<MidiPort> (p);
p = AudioEngine::instance()->register_input_port (DataType::MIDI, _("MIDI Clock in"));
_midi_clock_input_port = boost::dynamic_pointer_cast<MidiPort> (p);
p = AudioEngine::instance()->register_output_port (DataType::MIDI, _("MIDI Clock out"));
_midi_clock_output_port= boost::dynamic_pointer_cast<MidiPort> (p);
/* These ports all need their incoming data handled in
* Port::cycle_start() and so ...
*/
_mtc_input_port->set_always_parse (true);
_mtc_output_port->set_always_parse (true);
_midi_clock_input_port->set_always_parse (true);
_midi_clock_output_port->set_always_parse (true);
}
void
MidiPortManager::set_midi_port_states (const XMLNodeList&nodes)
{
XMLProperty* prop;
typedef map<std::string,boost::shared_ptr<Port> > PortMap;
PortMap ports;
const int version = 0;
ports.insert (make_pair (_mtc_input_port->name(), _mtc_input_port));
ports.insert (make_pair (_mtc_output_port->name(), _mtc_output_port));
ports.insert (make_pair (_midi_clock_input_port->name(), _midi_clock_input_port));
ports.insert (make_pair (_midi_clock_output_port->name(), _midi_clock_output_port));
ports.insert (make_pair (_midi_input_port->name(), _midi_in));
ports.insert (make_pair (_midi_output_port->name(), _midi_out));
ports.insert (make_pair (_mmc_input_port->name(), _mmc_in));
ports.insert (make_pair (_mmc_output_port->name(), _mmc_out));
for (XMLNodeList::const_iterator n = nodes.begin(); n != nodes.end(); ++n) {
if ((prop = (*n)->property (X_("name"))) == 0) {
continue;
}
PortMap::iterator p = ports.find (prop->value());
if (p == ports.end()) {
continue;
}
p->second->set_state (**n, version);
}
}
list<XMLNode*>
MidiPortManager::get_midi_port_states () const
{
typedef map<std::string,boost::shared_ptr<Port> > PortMap;
PortMap ports;
list<XMLNode*> s;
ports.insert (make_pair (_mtc_input_port->name(), _mtc_input_port));
ports.insert (make_pair (_mtc_output_port->name(), _mtc_output_port));
ports.insert (make_pair (_midi_clock_input_port->name(), _midi_clock_input_port));
ports.insert (make_pair (_midi_clock_output_port->name(), _midi_clock_output_port));
ports.insert (make_pair (_midi_input_port->name(), _midi_in));
ports.insert (make_pair (_midi_output_port->name(), _midi_out));
ports.insert (make_pair (_mmc_input_port->name(), _mmc_in));
ports.insert (make_pair (_mmc_output_port->name(), _mmc_out));
for (PortMap::const_iterator p = ports.begin(); p != ports.end(); ++p) {
s.push_back (&p->second->get_state());
}
return s;
}

View File

@@ -25,11 +25,12 @@
#include "pbd/error.h"
#include "midi++/port.h"
#include "ardour/debug.h"
#include "ardour/slave.h"
#include "ardour/session.h"
#include "ardour/audioengine.h"
#include "ardour/debug.h"
#include "ardour/midi_buffer.h"
#include "ardour/midi_port.h"
#include "ardour/session.h"
#include "ardour/slave.h"
#include "i18n.h"
@@ -48,8 +49,9 @@ using namespace Timecode;
*/
const int MTC_Slave::frame_tolerance = 2;
MTC_Slave::MTC_Slave (Session& s, MIDI::Port& p)
MTC_Slave::MTC_Slave (Session& s, MidiPort& p)
: session (s)
, port (&p)
{
can_notify_on_unknown_rate = true;
did_reset_tc_format = false;
@@ -70,7 +72,10 @@ MTC_Slave::MTC_Slave (Session& s, MIDI::Port& p)
session.config.ParameterChanged.connect_same_thread (config_connection, boost::bind (&MTC_Slave::parameter_changed, this, _1));
parse_timecode_offset();
reset (true);
rebind (p);
port->self_parser().mtc_time.connect_same_thread (port_connections, boost::bind (&MTC_Slave::update_mtc_time, this, _1, _2, _3));
port->self_parser().mtc_qtr.connect_same_thread (port_connections, boost::bind (&MTC_Slave::update_mtc_qtr, this, _1, _2, _3));
port->self_parser().mtc_status.connect_same_thread (port_connections, boost::bind (&MTC_Slave::update_mtc_status, this, _1));
}
MTC_Slave::~MTC_Slave()
@@ -94,15 +99,12 @@ MTC_Slave::~MTC_Slave()
}
void
MTC_Slave::rebind (MIDI::Port& p)
MTC_Slave::rebind (MidiPort& p)
{
port_connections.drop_connections ();
port = &p;
port->parser()->mtc_time.connect_same_thread (port_connections, boost::bind (&MTC_Slave::update_mtc_time, this, _1, _2, _3));
port->parser()->mtc_qtr.connect_same_thread (port_connections, boost::bind (&MTC_Slave::update_mtc_qtr, this, _1, _2, _3));
port->parser()->mtc_status.connect_same_thread (port_connections, boost::bind (&MTC_Slave::update_mtc_status, this, _1));
}
void
@@ -154,7 +156,8 @@ MTC_Slave::outside_window (framepos_t pos) const
bool
MTC_Slave::locked () const
{
return port->parser()->mtc_locked() && last_inbound_frame !=0 && engine_dll_initstate !=0;
DEBUG_TRACE (DEBUG::MTC, string_compose ("locked ? %1 last %2 initstate %3\n", port->self_parser().mtc_locked(), last_inbound_frame, engine_dll_initstate));
return port->self_parser().mtc_locked() && last_inbound_frame !=0 && engine_dll_initstate !=0;
}
bool
@@ -255,7 +258,6 @@ MTC_Slave::init_mtc_dll(framepos_t tme, double qtr)
DEBUG_TRACE (DEBUG::MTC, string_compose ("[re-]init MTC DLL %1 %2 %3\n", t0, t1, e2));
}
/* called from MIDI parser */
void
MTC_Slave::update_mtc_qtr (Parser& /*p*/, int which_qtr, framepos_t now)
@@ -306,7 +308,7 @@ MTC_Slave::update_mtc_time (const byte *msg, bool was_full, framepos_t now)
a locate command via MMC.
*/
//DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC::update_mtc_time - TID:%1\n", ::pthread_self()));
DEBUG_TRACE (DEBUG::MTC, string_compose ("MTC::update_mtc_time - TID:%1\n", ::pthread_self()));
TimecodeFormat tc_format;
bool reset_tc = true;
@@ -422,7 +424,7 @@ MTC_Slave::update_mtc_time (const byte *msg, bool was_full, framepos_t now)
now, timecode, mtc_frame, was_full, speedup_due_to_tc_mismatch));
if (was_full || outside_window (mtc_frame)) {
DEBUG_TRACE (DEBUG::MTC, string_compose ("update_mtc_time: full TC or outside window. - TID:%1\n", ::pthread_self()));
DEBUG_TRACE (DEBUG::MTC, string_compose ("update_mtc_time: full TC %1 or outside window %2\n", was_full, outside_window (mtc_frame)));
session.request_locate (mtc_frame, false);
session.request_transport_speed (0);
update_mtc_status (MIDI::MTC_Stopped);
@@ -446,7 +448,7 @@ MTC_Slave::update_mtc_time (const byte *msg, bool was_full, framepos_t now)
DEBUG_TRACE (DEBUG::MTC, string_compose ("new mtc_frame: %1 | MTC-FpT: %2 A3-FpT:%3\n",
mtc_frame, (4.0*qtr), session.frames_per_timecode_frame()));
switch (port->parser()->mtc_running()) {
switch (port->self_parser().mtc_running()) {
case MTC_Backward:
mtc_frame -= mtc_off;
qtr *= -1.0;
@@ -526,9 +528,10 @@ MTC_Slave::reset_window (framepos_t root)
of acceptable MTC frames wide open. otherwise, shrink it down to just 2 video frames
ahead of the window root (taking direction into account).
*/
framecnt_t const d = (quarter_frame_duration * 4 * frame_tolerance);
switch (port->parser()->mtc_running()) {
switch (port->self_parser().mtc_running()) {
case MTC_Forward:
window_begin = root;
transport_direction = 1;
@@ -551,7 +554,7 @@ MTC_Slave::reset_window (framepos_t root)
break;
}
DEBUG_TRACE (DEBUG::MTC, string_compose ("legal MTC window now %1 .. %2\n", window_begin, window_end));
DEBUG_TRACE (DEBUG::MTC, string_compose ("reset MTC window @ %3, now %1 .. %2\n", window_begin, window_end, root));
}
void
@@ -575,11 +578,11 @@ MTC_Slave::init_engine_dll (framepos_t pos, framepos_t inc)
}
/* main entry point from session_process.cc
* in jack_process callback context */
xo * in process callback context */
bool
MTC_Slave::speed_and_position (double& speed, framepos_t& pos)
{
framepos_t now = session.engine().frame_time_at_cycle_start();
framepos_t now = session.engine().sample_time_at_cycle_start();
framepos_t sess_pos = session.transport_frame(); // corresponds to now
//sess_pos -= session.engine().frames_since_cycle_start();
@@ -589,11 +592,21 @@ MTC_Slave::speed_and_position (double& speed, framepos_t& pos)
read_current (&last);
DEBUG_TRACE (DEBUG::MTC, string_compose ("speed&pos: timestamp %1 speed %2 initstate %3 dir %4 tpos %5 now %6 last-in %7\n",
last.timestamp,
last.speed,
engine_dll_initstate,
transport_direction,
sess_pos,
now,
last_inbound_frame));
/* re-init engine DLL here when state changed (direction, first_mtc_timestamp) */
if (last.timestamp == 0) { engine_dll_initstate = 0; }
else if (engine_dll_initstate != transport_direction && last.speed != 0) {
if (last.timestamp == 0) {
engine_dll_initstate = 0;
} else if (engine_dll_initstate != transport_direction && last.speed != 0) {
engine_dll_initstate = transport_direction;
init_engine_dll(last.position, session.engine().frames_per_cycle());
init_engine_dll(last.position, session.engine().samples_per_cycle());
engine_dll_reinitialized = true;
}
@@ -625,9 +638,7 @@ MTC_Slave::speed_and_position (double& speed, framepos_t& pos)
/* interpolate position according to speed and time since last quarter-frame*/
if (speed_flt == 0.0f) {
elapsed = 0;
}
else
{
} else {
/* scale elapsed time by the current MTC speed */
elapsed = (framecnt_t) rint (speed_flt * (now - last.timestamp));
if (give_slave_full_control_over_transport_speed() && !engine_dll_reinitialized) {
@@ -643,8 +654,8 @@ MTC_Slave::speed_and_position (double& speed, framepos_t& pos)
te0 = te1;
te1 += be * e + ee2;
ee2 += ce * e;
speed_flt = (te1 - te0) / double(session.engine().frames_per_cycle());
DEBUG_TRACE (DEBUG::MTC, string_compose ("engine DLL t0:%1 t1:%2 err:%3 spd:%4 ddt:%5\n", te0, te1, e, speed_flt, ee2 - session.engine().frames_per_cycle() ));
speed_flt = (te1 - te0) / double(session.engine().samples_per_cycle());
DEBUG_TRACE (DEBUG::MTC, string_compose ("engine DLL t0:%1 t1:%2 err:%3 spd:%4 ddt:%5\n", te0, te1, e, speed_flt, ee2 - session.engine().samples_per_cycle() ));
}
}
@@ -657,14 +668,13 @@ MTC_Slave::speed_and_position (double& speed, framepos_t& pos)
*/
if (!session.actively_recording()
&& speed != 0
&& ( (pos < 0) || (labs(pos - sess_pos) > 3 * session.frame_rate()) )
) {
&& ((pos < 0) || (labs(pos - sess_pos) > 3 * session.frame_rate()))) {
engine_dll_initstate = 0;
queue_reset (false);
}
/* provide a .1% deadzone to lock the speed */
if (fabs(speed - 1.0) <= 0.001)
if (fabs (speed - 1.0) <= 0.001)
speed = 1.0;
DEBUG_TRACE (DEBUG::MTC, string_compose ("MTCsync spd: %1 pos: %2 | last-pos: %3 elapsed: %4 delta: %5\n",

View File

@@ -79,6 +79,7 @@ PannerManager::discover_panners ()
panner_discover (*i);
}
}
int
PannerManager::panner_discover (string path)
{

View File

@@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-06-11 08:49-0400\n"
"PO-Revision-Date: 2013-03-03 09:23+0100\n"
"POT-Creation-Date: 2013-09-03 07:59-0400\n"
"PO-Revision-Date: 2013-06-13 22:47+0200\n"
"Last-Translator: Pavel Fric <pavelfric@seznam.cz>\n"
"Language-Team: Czech <kde-i18n-doc@kde.org>\n"
"Language: cs\n"
@@ -30,58 +30,58 @@ msgid "AudioDiskstream %1: there is no existing playlist to make a copy of!"
msgstr ""
"AudioDiskstream %1: není žádný seznam skladeb, který by bylo lze kopírovat!"
#: audio_diskstream.cc:823 audio_diskstream.cc:833
#: audio_diskstream.cc:848 audio_diskstream.cc:858
msgid ""
"AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3"
msgstr ""
"AudioDiskstream %1: Při doplňování nelze číst %2 ze seznamu skladeb u snímku "
"%3"
#: audio_diskstream.cc:989
#: audio_diskstream.cc:1014
msgid "AudioDiskstream %1: cannot read %2 from playlist at frame %3"
msgstr "AudioDiskstream %1: Nelze číst %2 ze seznamu skladeb u snímku %3"
#: audio_diskstream.cc:1358 audio_diskstream.cc:1375
#: audio_diskstream.cc:1383 audio_diskstream.cc:1400
msgid "AudioDiskstream %1: cannot write to disk"
msgstr "AudioDiskstream %1: Nelze zapisovat na disk"
#: audio_diskstream.cc:1418
#: audio_diskstream.cc:1443
msgid "AudioDiskstream \"%1\": cannot flush captured data to disk!"
msgstr "AudioDiskstream %1: Zachycená data nelze zapisovat na disk!"
#: audio_diskstream.cc:1512
#: audio_diskstream.cc:1537
msgid "%1: could not create region for complete audio file"
msgstr "%1: Nepodařilo se vytvořit oblast pro úplný zvukový soubor"
#: audio_diskstream.cc:1546
#: audio_diskstream.cc:1571
msgid "AudioDiskstream: could not create region for captured audio!"
msgstr ""
"AudioDiskstream: Nepodařilo se vytvořit oblast pro zaznamenaný zvukový "
"materiál!"
#: audio_diskstream.cc:1654
#: audio_diskstream.cc:1679
msgid "programmer error: %1"
msgstr "Chyba v programování: %1"
#: audio_diskstream.cc:1880
#: audio_diskstream.cc:1905
msgid "AudioDiskstream: channel %1 out of range"
msgstr "AudioDiskstream: Kanál %1 překročení rozsahu"
#: audio_diskstream.cc:1894 midi_diskstream.cc:1196
#: audio_diskstream.cc:1919 midi_diskstream.cc:1210
msgid "%1:%2 new capture file not initialized correctly"
msgstr "%1:%2 nový záznamový soubor neinicializován správně"
#: audio_diskstream.cc:2175
#: audio_diskstream.cc:2200
msgid "%1: cannot restore pending capture source file %2"
msgstr "%1: Nelze obnovit předběžný záznamový zdrojový soubor %2"
#: audio_diskstream.cc:2197
#: audio_diskstream.cc:2222
msgid "%1: incorrect number of pending sources listed - ignoring them all"
msgstr ""
"%1: Seznam obsahuje nesprávný počet předběžných zdrojů - všechny jsou "
"přehlíženy"
#: audio_diskstream.cc:2221
#: audio_diskstream.cc:2246
msgid "%1: cannot create whole-file region from pending capture sources"
msgstr ""
"%1: Z předběžných záznamových zdrojů nelze vytvořit žádnou oblast pro úplný "
@@ -133,7 +133,7 @@ msgstr "Seznamy zvukových skladeb (nepoužívané)"
#: audio_playlist_source.cc:171 audiosource.cc:913 file_source.cc:529
#: midi_playlist_source.cc:144 midi_playlist_source.cc:152
#: midi_playlist_source.cc:159 midi_source.cc:371 plugin_insert.cc:644
#: midi_playlist_source.cc:159 midi_source.cc:371 plugin_insert.cc:643
#: rb_effect.cc:332 session.cc:2465 session.cc:2498 session.cc:3643
#: session_handle.cc:87 sndfilesource.cc:121
msgid "programming error: %1"
@@ -215,7 +215,7 @@ msgstr ""
msgid "Connect session to engine"
msgstr "Spojit sezení se strojem"
#: audioengine.cc:844
#: audioengine.cc:843
msgid ""
"a port with the name \"%1\" already exists: check for duplicated track/bus "
"names"
@@ -223,7 +223,7 @@ msgstr ""
"Přípojka s názvem \"%1\" již existuje: Prověřte na zdvojené názvy stop/"
"sběrnic"
#: audioengine.cc:846 session.cc:1698
#: audioengine.cc:845 session.cc:1698
msgid ""
"No more JACK ports are available. You will need to stop %1 and restart JACK "
"with more ports if you need this many tracks."
@@ -231,35 +231,35 @@ msgstr ""
"Nejsou dostupné další přípojky JACK. Pokud potřebujete tolik stop, musíte "
"zastavit %1 a spustit JACK znovu s více přípojkami."
#: audioengine.cc:849
#: audioengine.cc:848
msgid "AudioEngine: cannot register port \"%1\": %2"
msgstr "AudioEngine: Nelze zaregistrovat přípojku \"%1\": %2"
#: audioengine.cc:879
#: audioengine.cc:878
msgid "unable to create port: %1"
msgstr "Nelze vytvořit přípojku: %1"
#: audioengine.cc:933
#: audioengine.cc:932
msgid "connect called before engine was started"
msgstr "Zavolání connect (spojení) před spuštěním stroje"
#: audioengine.cc:959
#: audioengine.cc:958
msgid "AudioEngine: cannot connect %1 (%2) to %3 (%4)"
msgstr "AudioEngine: Nelze spojit %1 (%2) s %3 (%4)"
#: audioengine.cc:974 audioengine.cc:1005
#: audioengine.cc:973 audioengine.cc:1004
msgid "disconnect called before engine was started"
msgstr "Zavolání disconnect (odpojení) před spuštěním stroje"
#: audioengine.cc:1053
#: audioengine.cc:1052
msgid "get_port_by_name() called before engine was started"
msgstr "Zavolání get_port_by_name() před spuštěním stroje"
#: audioengine.cc:1105
#: audioengine.cc:1104
msgid "get_ports called before engine was started"
msgstr "Zavolání get_ports před spuštěním stroje"
#: audioengine.cc:1428
#: audioengine.cc:1427
msgid "failed to connect to JACK"
msgstr "Nepodařilo se spojit se s JACK"
@@ -545,7 +545,7 @@ msgstr "Ztrátová komprese"
msgid "Lossless compression"
msgstr "Bezztrátová komprese"
#: export_format_manager.cc:207 export_format_specification.cc:579
#: export_format_manager.cc:218 export_format_specification.cc:579
msgid "Session rate"
msgstr "Kmitočet sezení"
@@ -577,7 +577,7 @@ msgstr "Trojúhelníkový"
msgid "Rectangular"
msgstr "Obdélníkový"
#: export_formats.cc:52 session.cc:4854 session.cc:4870
#: export_formats.cc:52 session.cc:4861 session.cc:4877
msgid "None"
msgstr "Žádný"
@@ -790,25 +790,25 @@ msgstr "Nelze určit nynější pracovní adresář (%1)"
msgid "unknown file type for session %1"
msgstr "Neznámý typ souboru pro sezení %1"
#: globals.cc:204
#: globals.cc:205
msgid "Could not set system open files limit to \"unlimited\""
msgstr ""
"Nepodařilo se nastavit systémové omezení pro otevřené soubory na \"neomezeno"
"\""
#: globals.cc:206
#: globals.cc:207
msgid "Could not set system open files limit to %1"
msgstr "Nepodařilo se nastavit systémové omezení pro otevřené soubory na %1"
#: globals.cc:210
#: globals.cc:211
msgid "Your system is configured to limit %1 to only %2 open files"
msgstr "Vaše systémové nastavení omezuje %1 na jen %2 otevřené soubory"
#: globals.cc:214
#: globals.cc:215
msgid "Could not get system open files limit (%1)"
msgstr "Nepodařilo se dostat systémové omezení pro otevřené soubory (%1)"
#: globals.cc:267
#: globals.cc:266
msgid "Loading configuration"
msgstr "Nahrává se nastavení"
@@ -961,20 +961,20 @@ msgstr "P"
msgid "%d"
msgstr "%d"
#: ladspa_plugin.cc:87
#: ladspa_plugin.cc:88
msgid "LADSPA: module has no descriptor function."
msgstr "LADSPA: Modul nemá žádnou funkci popisu"
#: ladspa_plugin.cc:92
#: ladspa_plugin.cc:93
msgid "LADSPA: plugin has gone away since discovery!"
msgstr "LADSPA: Přídavný modul už není více nalezitelný!"
#: ladspa_plugin.cc:99
#: ladspa_plugin.cc:100
msgid "LADSPA: \"%1\" cannot be used, since it cannot do inplace processing"
msgstr ""
"LADSPA: \"%1\" nemůže být použit, neboť nedělá žádný \"inplace processing\""
#: ladspa_plugin.cc:296
#: ladspa_plugin.cc:297
msgid ""
"illegal parameter number used with plugin \"%1\". This may indicate a change "
"in the plugin design, and presets may be invalid"
@@ -982,35 +982,35 @@ msgstr ""
"Špatné číslo parametru pro přídavný modul \"%1\". To může značit změnu v "
"návrhupřídavného modulu, a přednastavení jsou případně neplatná"
#: ladspa_plugin.cc:373 ladspa_plugin.cc:418
#: ladspa_plugin.cc:376 ladspa_plugin.cc:426
msgid "Bad node sent to LadspaPlugin::set_state"
msgstr "Špatný uzel poslán LadspaPlugin::set_state"
#: ladspa_plugin.cc:386 ladspa_plugin.cc:431
#: ladspa_plugin.cc:391 ladspa_plugin.cc:440
msgid "LADSPA: no ladspa port number"
msgstr "LADSPA: Žádné číslo přípojky LADSPA"
#: ladspa_plugin.cc:392 ladspa_plugin.cc:437
#: ladspa_plugin.cc:397 ladspa_plugin.cc:446
msgid "LADSPA: no ladspa port data"
msgstr "LADSPA: Žádná data přípojky LADSPA"
#: ladspa_plugin.cc:707
#: ladspa_plugin.cc:717
msgid "LADSPA: cannot load module from \"%1\""
msgstr "LADSPA: Nelze nahrát modul z \"%1\""
#: ladspa_plugin.cc:817
#: ladspa_plugin.cc:827
msgid "Could not locate HOME. Preset not removed."
msgstr "Nepodařilo se najít HOME. Přednastavení neodstraněno."
#: ladspa_plugin.cc:854 ladspa_plugin.cc:860
#: ladspa_plugin.cc:864 ladspa_plugin.cc:870
msgid "Could not create %1. Preset not saved. (%2)"
msgstr "Nepodařilo se vytvořit %1. Přednastavení neuloženo. (%2)"
#: ladspa_plugin.cc:867
#: ladspa_plugin.cc:877
msgid "Error saving presets file %1."
msgstr "Chyba při ukládání souboru s přednastavením %1."
#: ladspa_plugin.cc:905
#: ladspa_plugin.cc:915
msgid "Could not locate HOME. Preset not saved."
msgstr "Nepodařilo se najít HOME. Přednastavení neuloženo."
@@ -1050,7 +1050,7 @@ msgstr "Locations: Pokus o použití neznámé polohy jako vybrané polohy"
msgid "incorrect XML mode passed to Locations::set_state"
msgstr "Nesprávný uzel XML předán dál Locations::set_state"
#: location.cc:842 session.cc:4355 session_state.cc:1114
#: location.cc:842 session.cc:4362 session_state.cc:1114
msgid "session"
msgstr "Sezení"
@@ -1134,23 +1134,23 @@ msgid "MidiDiskstream %1: there is no existing playlist to make a copy of!"
msgstr ""
"MidiDiskstream %1: není žádný seznam skladeb, který by bylo lze kopírovat!"
#: midi_diskstream.cc:685
#: midi_diskstream.cc:699
msgid "MidiDiskstream %1: cannot read %2 from playlist at frame %3"
msgstr "MidiDiskstream %1: Nelze číst %2 ze seznamu skladeb u snímku %3"
#: midi_diskstream.cc:820
#: midi_diskstream.cc:834
msgid "MidiDiskstream %1: cannot write to disk"
msgstr "MidiDiskstream %1: Nelze zapisovat na disk"
#: midi_diskstream.cc:854
#: midi_diskstream.cc:868
msgid "MidiDiskstream \"%1\": cannot flush captured data to disk!"
msgstr "MidiDiskstream %1: Zachycená data nelze zapisovat na disk!"
#: midi_diskstream.cc:941
#: midi_diskstream.cc:955
msgid "%1: could not create region for complete midi file"
msgstr "%1: Nepodařilo se vytvořit oblast pro úplný soubor MIDI"
#: midi_diskstream.cc:978
#: midi_diskstream.cc:992
msgid "MidiDiskstream: could not create region for captured midi!"
msgstr ""
"MidiDiskstream: Nepodařilo se vytvořit oblast pro zaznamenaný materiál MIDI!"
@@ -1169,7 +1169,7 @@ msgstr "Převést"
#: midi_patch_manager.cc:126
msgid "Duplicate MIDI device `%1' in `%2' ignored"
msgstr ""
msgstr "Zdvojení zařízení MIDI `%1' v `%2' se přehlíží"
#: midi_source.cc:125
msgid "Missing parameter property on InterpolationStyle"
@@ -1189,7 +1189,7 @@ msgstr "Chybějící vlastnost \"state\" u AutomationState"
#: midi_stretch.cc:85
msgid "MIDI stretch created non-MIDI source"
msgstr ""
msgstr "Protažení MIDI vytvořilo zdroj, který není MIDI"
#: monitor_processor.cc:53
msgid "monitor dim"
@@ -1201,15 +1201,15 @@ msgstr "Přerušení sledování "
#: monitor_processor.cc:55
msgid "monitor mono"
msgstr "Monitor Mono"
msgstr "Mono sledování"
#: monitor_processor.cc:58
msgid "monitor dim level"
msgstr "Síla hlasitosti pro Utlumit Monitor"
msgstr "Síla hlasitosti pro utlumení sledování "
#: monitor_processor.cc:62
msgid "monitor solo boost level"
msgstr "Síla hlasitosti pro Monitor Solo Boost"
msgstr "Síla hlasitosti pro zdůraznění sóla sledování"
#: monitor_processor.cc:512
msgid "cut control %1"
@@ -1244,9 +1244,8 @@ msgid "Session framerate adjusted from %1 TO: MTC's %2."
msgstr "Rychlost snímkování sezení změněna z %1 na MTC: %2"
#: mtc_slave.cc:393
#, fuzzy
msgid "Session and MTC framerate mismatch: MTC:%1 %2:%3."
msgstr "Rychlost snímkování sezení a MTC se neshodují: MTC: %1 Ardour: %2"
msgstr "Rychlost snímkování sezení a MTC se neshodují: MTC: %1 %2:%3."
#: operations.cc:24
msgid "capture"
@@ -1350,23 +1349,35 @@ msgstr "Žádné ID seznamu skladeb v XML zdroje seznamu skladeb!"
msgid "Could not construct playlist for PlaylistSource from session data!"
msgstr "Nepodařilo se sestavit seznam skladeb ze zdrojových dat sezení!"
#: plugin_insert.cc:599
#: plugin.cc:324
msgid ""
"Plugin presets are not supported in this build of %1. Consider paying for a "
"full version"
msgstr ""
#: plugin.cc:398
msgid ""
"Saving plugin settings is not supported in this build of %1. Consider paying "
"for the full version"
msgstr ""
#: plugin_insert.cc:598
msgid "programming error: "
msgstr "Chyba v programování:"
#: plugin_insert.cc:908
#: plugin_insert.cc:926
msgid "XML node describing plugin is missing the `type' field"
msgstr "Uzlu XML k popisu přídavného modulu chybí pole \"type\""
#: plugin_insert.cc:923
#: plugin_insert.cc:941
msgid "unknown plugin type %1 in plugin insert state"
msgstr "Neznámý typ přídavného modulu %1 ve vkládacím stavu přídavného modulu"
#: plugin_insert.cc:951
#: plugin_insert.cc:969
msgid "Plugin has no unique ID field"
msgstr "Přídavný modul nemá žádné pole pro jedinečné ID"
#: plugin_insert.cc:960
#: plugin_insert.cc:978
msgid ""
"Found a reference to a plugin (\"%1\") that is unknown.\n"
"Perhaps it was removed or moved since it was last used."
@@ -1374,15 +1385,15 @@ msgstr ""
"Nalezen odkaz na neznámý přídavný modul (\"%1\").\n"
"Snad byl od posledního použití odstraněn nebo přesunut."
#: plugin_insert.cc:1076
#: plugin_insert.cc:1094
msgid "PluginInsert: Auto: no ladspa port number"
msgstr "PluginInsert: Auto: Žádné číslo přípojky LADSPA"
#: plugin_insert.cc:1083
#: plugin_insert.cc:1101
msgid "PluginInsert: Auto: port id out of range"
msgstr "PluginInsert: Auto: Překročení rozsahu ID přípojky"
#: plugin_insert.cc:1119
#: plugin_insert.cc:1137
msgid "PluginInsert: automatable control %1 not found - ignored"
msgstr ""
"PluginInsert: automatizovatelný prvek ovládání %1 nenalezen - přehlíží se"
@@ -1404,22 +1415,20 @@ msgid "LADSPA: module \"%1\" has no descriptor function."
msgstr "LADSPA: Modul \"%1\" nemá žádnou funkci popisu."
#: plugin_manager.cc:602
#, fuzzy
msgid ""
"VST plugin %1 does not support processReplacing, and so cannot be used in %2 "
"at this time"
msgstr ""
"Přídavný modul VST %1 nepodporuje processReplacing a z toho důvodu jej nyní "
"nelze v Ardouru použít"
"nelze v %2 použít"
#: plugin_manager.cc:709
#, fuzzy
msgid ""
"linuxVST plugin %1 does not support processReplacing, and so cannot be used "
"in %2 at this time"
msgstr ""
"Přídavný modul linuxVST %1 nepodporuje processReplacing a z toho důvodu jej "
"nyní nelze v Ardouru použít"
"nyní nelze v %2 použít"
#: plugin_manager.cc:870
msgid "unknown plugin status type \"%1\" - all entries ignored"
@@ -1535,24 +1544,24 @@ msgstr "Zavedení: Chyba v src_new() : %1"
msgid "return %1"
msgstr "Vrácená hodnota: %1"
#: route.cc:1100 route.cc:2550
#: route.cc:1105 route.cc:2581
msgid "unknown Processor type \"%1\"; ignored"
msgstr "Neznámý typ procesoru \"%1\"; přehlíží se"
#: route.cc:1112
#: route.cc:1117
msgid "processor could not be created. Ignored."
msgstr "Procesor se nepodařilo vytvořit. Přehlíží se."
#: route.cc:1983 route.cc:2203
#: route.cc:2007 route.cc:2234
msgid "Bad node sent to Route::set_state() [%1]"
msgstr "Špatný uzel poslán Route::set_state() [%1]"
#: route.cc:2042
#: route.cc:2067
msgid "Pannable state found for route (%1) without a panner!"
msgstr ""
"Nalezen stav cíle vyvážení pro cestu (%1), aniž by bylo nalezeno vyvážení!"
#: route.cc:2106 route.cc:2110 route.cc:2317 route.cc:2321
#: route.cc:2137 route.cc:2141 route.cc:2348 route.cc:2352
msgid "badly formed order key string in state file! [%1] ... ignored."
msgstr ""
"Špatně utvořený řetězec znaků pro klíč pořadí roztřídění v souboru sezení! "
@@ -1814,7 +1823,7 @@ msgstr "%1: Polohu souboru %2 nelze vyhledat pro vyvedení"
msgid "Export ended unexpectedly: %1"
msgstr "Vyvedení skončilo neočekávaně: %1"
#: session_ltc.cc:220
#: session_ltc.cc:222
msgid ""
"LTC encoder: invalid framerate - LTC encoding is disabled for the remainder "
"of this session."
@@ -1822,11 +1831,11 @@ msgstr ""
"Kodér LTC: Neplatná rychlost snímkování - Kódování LTC je pro zbývající část "
"tohoto sezení zakázáno."
#: session_midi.cc:427
#: session_midi.cc:428
msgid "Session: could not send full MIDI time code"
msgstr "Sezení: Nepodařilo se poslat úplný časový kód MIDI"
#: session_midi.cc:519
#: session_midi.cc:520
msgid "Session: cannot send quarter-frame MTC message (%1)"
msgstr "Sezení: Nelze poslat quarter-frame MTC (%1)"
@@ -1834,18 +1843,17 @@ msgstr "Sezení: Nelze poslat quarter-frame MTC (%1)"
msgid "Session: cannot create Playlist from XML description."
msgstr "Sezení: Nelze vytvořit seznam skladeb z popisu XML"
#: session_process.cc:135
#: session_process.cc:133
msgid "Session: error in no roll for %1"
msgstr "Sezení: Chyba v no_roll pro %1"
#: session_process.cc:1160
#: session_process.cc:1158
msgid "Programming error: illegal event type in process_event (%1)"
msgstr "Chyba v programování: Neplatný typ události v process_event (%1)"
#: session_state.cc:139
#, fuzzy
msgid "Could not use path %1 (%2)"
msgstr "Nepodařilo se použít cestu %1 (%s)"
msgstr "Nepodařilo se použít cestu %1 (%2)"
#: session_state.cc:267
msgid "solo cut control (dB)"
@@ -2210,7 +2218,7 @@ msgstr "Neznámý stav transportu JACK v Sync-Callback"
msgid "Cannot loop - no loop range defined"
msgstr "Nelze přehrávat ve smyčce - Nestanovena žádná oblast smyčky"
#: session_transport.cc:727
#: session_transport.cc:728
msgid ""
"Seamless looping cannot be supported while %1 is using JACK transport.\n"
"Recommend changing the configured options"
@@ -2218,7 +2226,7 @@ msgstr ""
"Souvislé přehrávání ve smyčce není možné, dokud %1 používá transport JACK.\n"
"Doporučuje se změna volby v nastavení"
#: session_transport.cc:1092
#: session_transport.cc:1094
msgid ""
"Global varispeed cannot be supported while %1 is connected to JACK transport "
"control"
@@ -2227,25 +2235,20 @@ msgstr ""
"dokud je %1 spojen s transportem JACK."
#: smf_source.cc:252
#, fuzzy
msgid "Unable to read event prefix, corrupt MIDI ring"
msgstr ""
"Nelze přečíst předponu události, poškozená kruhová vyrovnávací paměť MIDI"
msgstr "Nelze přečíst předponu události, poškozen okraj MIDI"
#: smf_source.cc:265
#, fuzzy
msgid "Event has time and size but no body, corrupt MIDI ring"
msgstr ""
"Přečteny čas/velikost, ale ne vyrovnávací paměť, poškozená kruhová "
"vyrovnávací paměť MIDI"
msgstr "Událost má čas a velikost, ale nemá tělo, poškozen okraj MIDI"
#: smf_source.cc:271
msgid "Event time is before MIDI source position"
msgstr ""
msgstr "Čas události je před polohou zdroje MIDI"
#: smf_source.cc:306 smf_source.cc:345
msgid "Skipping event with unordered time %1"
msgstr ""
msgstr "Přeskakuje se událost s neuspořádaným časem %1"
#: smf_source.cc:410
msgid "cannot open MIDI file %1 for write"
@@ -2374,7 +2377,7 @@ msgid "attempt to write a non-writable audio file source (%1)"
msgstr ""
"Pokus o zápis zvukového zdrojového souboru chráněného proti zápisu (%1)"
#: sndfilesource.cc:396 utils.cc:497 utils.cc:521 utils.cc:535 utils.cc:554
#: sndfilesource.cc:396 utils.cc:507 utils.cc:531 utils.cc:545 utils.cc:564
msgid "programming error: %1 %2"
msgstr "Chyba v programování: %1 %2"
@@ -2639,11 +2642,11 @@ msgstr "M-Clock"
msgid "LTC"
msgstr "LTC"
#: utils.cc:589
#: utils.cc:599
msgid "programming error: unknown native header format: %1"
msgstr "Chyba v programování: neznámý nativní formát hlavičky: %1"
#: utils.cc:604
#: utils.cc:614
msgid "cannot open directory %1 (%2)"
msgstr "Nelze otevřít adresář %1 (%2)"

View File

@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-07-17 11:09+0200\n"
"POT-Creation-Date: 2013-09-03 07:59-0400\n"
"PO-Revision-Date: 2013-07-23 15:04+0200\n"
"Last-Translator: Edgar Aichinger <edogawa@aon.at>\n"
"Language-Team: German <ardour-dev@lists.ardour.org>\n"
@@ -31,58 +31,58 @@ msgid "AudioDiskstream %1: there is no existing playlist to make a copy of!"
msgstr ""
"AudioDiskstream %1: es gibt keine Wiedergabeliste, die kopiert werden kann!"
#: audio_diskstream.cc:823 audio_diskstream.cc:833
#: audio_diskstream.cc:848 audio_diskstream.cc:858
msgid ""
"AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3"
msgstr ""
"AudioDiskstream %1: Kann während des Befüllens %2 nicht aus Wiedergabeliste "
"bei Frame %3 lesen"
#: audio_diskstream.cc:989
#: audio_diskstream.cc:1014
msgid "AudioDiskstream %1: cannot read %2 from playlist at frame %3"
msgstr ""
"AudioDiskstream %1: Kann %2 nicht aus Wiedergabeliste bei Frame %3 lesen"
#: audio_diskstream.cc:1358 audio_diskstream.cc:1375
#: audio_diskstream.cc:1383 audio_diskstream.cc:1400
msgid "AudioDiskstream %1: cannot write to disk"
msgstr "AudioDiskstream %1: Kann nicht auf Disk schreiben"
#: audio_diskstream.cc:1418
#: audio_diskstream.cc:1443
msgid "AudioDiskstream \"%1\": cannot flush captured data to disk!"
msgstr "AudioDiskstream %1: Kann aufgenommene Daten nicht auf Disk schreiben!"
#: audio_diskstream.cc:1512
#: audio_diskstream.cc:1537
msgid "%1: could not create region for complete audio file"
msgstr "%1: konnte keine Region für die komplette Audiodatei erzeugen"
#: audio_diskstream.cc:1546
#: audio_diskstream.cc:1571
msgid "AudioDiskstream: could not create region for captured audio!"
msgstr ""
"AudioDiskstream: konnte keine Region für das aufgenommene Audiomaterial "
"erzeugen!"
#: audio_diskstream.cc:1654
#: audio_diskstream.cc:1679
msgid "programmer error: %1"
msgstr "Programmierfehler: %1"
#: audio_diskstream.cc:1880
#: audio_diskstream.cc:1905
msgid "AudioDiskstream: channel %1 out of range"
msgstr "AudioDiskstream: Kanal %1 Bereichsüberschreitung"
#: audio_diskstream.cc:1894 midi_diskstream.cc:1196
#: audio_diskstream.cc:1919 midi_diskstream.cc:1210
msgid "%1:%2 new capture file not initialized correctly"
msgstr "%1:%2 neue Aufnahmedatei nicht korrekt initialisiert"
#: audio_diskstream.cc:2175
#: audio_diskstream.cc:2200
msgid "%1: cannot restore pending capture source file %2"
msgstr "%1: kann vorläufige Aufnahme-Quelldatei %2 nicht wiederherstellen"
#: audio_diskstream.cc:2197
#: audio_diskstream.cc:2222
msgid "%1: incorrect number of pending sources listed - ignoring them all"
msgstr ""
"%1: Liste enthält falsche Anzahl vorläufiger Quellen - alle werden ignoriert"
#: audio_diskstream.cc:2221
#: audio_diskstream.cc:2246
msgid "%1: cannot create whole-file region from pending capture sources"
msgstr ""
"%1: kann aus vorläufigen Aufnahmequellen keine Region für die komplette "
@@ -136,7 +136,7 @@ msgstr "Audio-Wiedergabelisten (unbenutzt)"
#: audio_playlist_source.cc:171 audiosource.cc:913 file_source.cc:529
#: midi_playlist_source.cc:144 midi_playlist_source.cc:152
#: midi_playlist_source.cc:159 midi_source.cc:371 plugin_insert.cc:644
#: midi_playlist_source.cc:159 midi_source.cc:371 plugin_insert.cc:643
#: rb_effect.cc:332 session.cc:2465 session.cc:2498 session.cc:3643
#: session_handle.cc:87 sndfilesource.cc:121
msgid "programming error: %1"
@@ -316,8 +316,8 @@ msgstr "AudioSource: kann Pfad für Peaks (b) \"%1\" nicht öffnen (%2)"
msgid ""
"AudioSource[%1]: peak read - cannot read %2 samples at offset %3 of %4 (%5)"
msgstr ""
"AudioSource[%1]: peak read - kann %2 Samples bei Offset %3 von %4 nicht "
"lesen(%5)"
"AudioSource[%1]: peak read - kann %2 Samples bei Offset %3 von %4 nicht lesen"
"(%5)"
#: audiosource.cc:667
msgid "%1: could not write read raw data for peak computation (%2)"
@@ -550,7 +550,7 @@ msgstr "Verlustbehaftete Kompression"
msgid "Lossless compression"
msgstr "Verlustfreie Kompression"
#: export_format_manager.cc:207 export_format_specification.cc:579
#: export_format_manager.cc:218 export_format_specification.cc:579
msgid "Session rate"
msgstr "Projektrate"
@@ -582,7 +582,7 @@ msgstr "Dreieck"
msgid "Rectangular"
msgstr "Rechteck"
#: export_formats.cc:52 session.cc:4854 session.cc:4870
#: export_formats.cc:52 session.cc:4861 session.cc:4877
msgid "None"
msgstr "Kein"
@@ -800,24 +800,24 @@ msgstr "kann momentanes Arbeitsverzeichnis nicht bestimmen (%1)"
msgid "unknown file type for session %1"
msgstr "Unbekannter Dateityp für Projekt %1"
#: globals.cc:204
#: globals.cc:205
msgid "Could not set system open files limit to \"unlimited\""
msgstr ""
"Konnte die Systemgrenze für offene Dateien nicht auf \"unbeschränkt\" setzen"
#: globals.cc:206
#: globals.cc:207
msgid "Could not set system open files limit to %1"
msgstr "Konnte die Systemgrenze für offene Dateien nicht auf %1 setzen"
#: globals.cc:210
#: globals.cc:211
msgid "Your system is configured to limit %1 to only %2 open files"
msgstr "Ihre Systemkonfiguration beschränkt %1 auf nur %2 offene Dateien"
#: globals.cc:214
#: globals.cc:215
msgid "Could not get system open files limit (%1)"
msgstr "Konnte die Grenze für offene Dateien nicht erhalten (%1)"
#: globals.cc:267
#: globals.cc:266
msgid "Loading configuration"
msgstr "Lade Konfiguration"
@@ -1063,7 +1063,7 @@ msgstr ""
msgid "incorrect XML mode passed to Locations::set_state"
msgstr "unkorrekter XML-Modus an Locations::set_state weitergereicht"
#: location.cc:842 session.cc:4355 session_state.cc:1114
#: location.cc:842 session.cc:4362 session_state.cc:1114
msgid "session"
msgstr "Projekt"
@@ -1149,25 +1149,25 @@ msgstr "MidiDiskstream: Wiedergabeliste \"%1\" ist keine MIDI-Wiedergabeliste"
msgid "MidiDiskstream %1: there is no existing playlist to make a copy of!"
msgstr "MidiDiskstream %1: es gibt keine Wiedergabeliste zum Kopieren!"
#: midi_diskstream.cc:685
#: midi_diskstream.cc:699
msgid "MidiDiskstream %1: cannot read %2 from playlist at frame %3"
msgstr ""
"MidiDiskstream %1: kann %2 nicht von Wiedergabeliste bei Frame %3 lesen"
#: midi_diskstream.cc:820
#: midi_diskstream.cc:834
msgid "MidiDiskstream %1: cannot write to disk"
msgstr "MidiDiskstream %1: kann nicht auf Disk schreiben"
#: midi_diskstream.cc:854
#: midi_diskstream.cc:868
msgid "MidiDiskstream \"%1\": cannot flush captured data to disk!"
msgstr ""
"MidiDiskstream \"%1\": kann aufgenommene Daten nicht auf Disk schreiben!"
#: midi_diskstream.cc:941
#: midi_diskstream.cc:955
msgid "%1: could not create region for complete midi file"
msgstr "%1: konnte Region für die komplette MIDI-Datei nicht erzeugen"
#: midi_diskstream.cc:978
#: midi_diskstream.cc:992
msgid "MidiDiskstream: could not create region for captured midi!"
msgstr "MidiDiskstream: konnte Region für aufgenommenes MIDI nicht erzeugen"
@@ -1384,23 +1384,23 @@ msgstr ""
"Das Speichern von Pluginpresets werden in diesem %1-Binärpaket nicht "
"unterstützt. Erwägen Sie, für die Vollversion zu bezahlen"
#: plugin_insert.cc:599
#: plugin_insert.cc:598
msgid "programming error: "
msgstr "Programmierfehler:"
#: plugin_insert.cc:914
#: plugin_insert.cc:926
msgid "XML node describing plugin is missing the `type' field"
msgstr "Dem XML-Knoten zur Beschreibung des Plugins fehlt das \"type\"-Feld"
#: plugin_insert.cc:929
#: plugin_insert.cc:941
msgid "unknown plugin type %1 in plugin insert state"
msgstr "Unbekannter Plugintyp %1 im Einfüge-Status des Plugins"
#: plugin_insert.cc:957
#: plugin_insert.cc:969
msgid "Plugin has no unique ID field"
msgstr "Das Plugin hat kein Feld für die eindeutige ID"
#: plugin_insert.cc:966
#: plugin_insert.cc:978
msgid ""
"Found a reference to a plugin (\"%1\") that is unknown.\n"
"Perhaps it was removed or moved since it was last used."
@@ -1408,15 +1408,15 @@ msgstr ""
"Referenz auf ein unbekanntes Plugin (\"%1\") gefunden.\n"
"Vielleicht wurde es seit der letzten Verwendung entfernt oder verschoben."
#: plugin_insert.cc:1082
#: plugin_insert.cc:1094
msgid "PluginInsert: Auto: no ladspa port number"
msgstr "PluginInsert: Auto: keine LADSPA Portnummer"
#: plugin_insert.cc:1089
#: plugin_insert.cc:1101
msgid "PluginInsert: Auto: port id out of range"
msgstr "PluginInsert: Auto: Port-ID Bereichsüberschreitung"
#: plugin_insert.cc:1125
#: plugin_insert.cc:1137
msgid "PluginInsert: automatable control %1 not found - ignored"
msgstr ""
"PluginInsert: automatisierbares Kontrollelement %1 nicht gefunden - ignoriert"
@@ -1566,23 +1566,23 @@ msgstr "Import: Fehler in src_new() : %1"
msgid "return %1"
msgstr "Rückgabewert: %1"
#: route.cc:1101 route.cc:2557
#: route.cc:1105 route.cc:2581
msgid "unknown Processor type \"%1\"; ignored"
msgstr "unbekannter Prozessortyp \"%1\"; ignoriert"
#: route.cc:1113
#: route.cc:1117
msgid "processor could not be created. Ignored."
msgstr "Prozessor konnte nicht erzeugt werden. Ignoriert."
#: route.cc:1986 route.cc:2210
#: route.cc:2007 route.cc:2234
msgid "Bad node sent to Route::set_state() [%1]"
msgstr "Schlechter Knoten an Route::set_state() gesendet [%1]"
#: route.cc:2045
#: route.cc:2067
msgid "Pannable state found for route (%1) without a panner!"
msgstr "Pannerziel-Status für Route (%1) ohne Panner gefunden!"
#: route.cc:2113 route.cc:2117 route.cc:2324 route.cc:2328
#: route.cc:2137 route.cc:2141 route.cc:2348 route.cc:2352
msgid "badly formed order key string in state file! [%1] ... ignored."
msgstr ""
"schlecht geformte Zeichenkette für den Schlüssel der Sortierreihenfolge in "
@@ -1853,7 +1853,7 @@ msgstr "%1: kann für Export nicht Dateiposition %2 aufsuchen"
msgid "Export ended unexpectedly: %1"
msgstr "Export endet unerwartet: %1"
#: session_ltc.cc:220
#: session_ltc.cc:222
msgid ""
"LTC encoder: invalid framerate - LTC encoding is disabled for the remainder "
"of this session."
@@ -1861,11 +1861,11 @@ msgstr ""
"LTC-Kodierer: ungültige Framerate - das Kodieren von LTC wird für den "
"restlichen Teil dieses Projekts ausgesetzt."
#: session_midi.cc:427
#: session_midi.cc:428
msgid "Session: could not send full MIDI time code"
msgstr "Session: konnte vollständigen MIDI-Timecode nicht senden"
#: session_midi.cc:519
#: session_midi.cc:520
msgid "Session: cannot send quarter-frame MTC message (%1)"
msgstr "Session: kann quarter-frame MTC-Nachricht nicht senden (%1)"
@@ -2262,7 +2262,7 @@ msgstr "Unbekannter JACK-Transportstatus im Sync-Callback"
msgid "Cannot loop - no loop range defined"
msgstr "Kann nicht loopen - kein Schleifenbereich definieert"
#: session_transport.cc:727
#: session_transport.cc:728
msgid ""
"Seamless looping cannot be supported while %1 is using JACK transport.\n"
"Recommend changing the configured options"
@@ -2271,7 +2271,7 @@ msgstr ""
"benutzt.\n"
"Ändern Sie die Konfigurationsoption"
#: session_transport.cc:1092
#: session_transport.cc:1094
msgid ""
"Global varispeed cannot be supported while %1 is connected to JACK transport "
"control"

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: libardour 0.664.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-06-11 08:49-0400\n"
"POT-Creation-Date: 2013-09-03 07:59-0400\n"
"PO-Revision-Date: 2007-04-16 00:38+0200\n"
"Last-Translator: Klearchos Gourgourinis <muadib@in.gr>\n"
"Language-Team: Hellenic(Greek)\n"
@@ -29,59 +29,59 @@ msgid "AudioDiskstream %1: there is no existing playlist to make a copy of!"
msgstr ""
"AudioDiskstream %1: δεν υπάρχει λίστα αναπαρ/γής για να γίνει αντιγραφή!"
#: audio_diskstream.cc:823 audio_diskstream.cc:833
#: audio_diskstream.cc:848 audio_diskstream.cc:858
msgid ""
"AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3"
msgstr ""
"AudioDiskstream %1: κατα την αναγόμωση, δεν μπόρεσα να διαβάσω %2 από τη "
"λίστα αναπαρ/γής στο frame %3"
#: audio_diskstream.cc:989
#: audio_diskstream.cc:1014
msgid "AudioDiskstream %1: cannot read %2 from playlist at frame %3"
msgstr ""
"AudioDiskstream %1: δεν μπόρεσα να διαβάσω %2 από τη λίστα αναπαρ/γής στο "
"frame %3"
#: audio_diskstream.cc:1358 audio_diskstream.cc:1375
#: audio_diskstream.cc:1383 audio_diskstream.cc:1400
msgid "AudioDiskstream %1: cannot write to disk"
msgstr "AudioDiskstream %1: δεν μπορώ να γράψω στο δίσκο"
#: audio_diskstream.cc:1418
#: audio_diskstream.cc:1443
msgid "AudioDiskstream \"%1\": cannot flush captured data to disk!"
msgstr ""
"AudioDiskstream \"%1\": αδύνατη η εκκαθάριση δειγματοληπτικών δεδομένων στο "
"δίσκο!"
#: audio_diskstream.cc:1512
#: audio_diskstream.cc:1537
msgid "%1: could not create region for complete audio file"
msgstr "%1: δεν μπόρεσα να δημιουργήσω περιοχή για ολόκληρο audio file"
#: audio_diskstream.cc:1546
#: audio_diskstream.cc:1571
msgid "AudioDiskstream: could not create region for captured audio!"
msgstr ""
"AudioDiskstream: δεν μπόρεσα να δημιουργήσω περιοχή για δειγματοληψίες!"
#: audio_diskstream.cc:1654
#: audio_diskstream.cc:1679
msgid "programmer error: %1"
msgstr "σφάλμα προγραμματιστή: %1"
#: audio_diskstream.cc:1880
#: audio_diskstream.cc:1905
msgid "AudioDiskstream: channel %1 out of range"
msgstr "AudioDiskstream: κανάλι %1 εκτός διαστήματος"
#: audio_diskstream.cc:1894 midi_diskstream.cc:1196
#: audio_diskstream.cc:1919 midi_diskstream.cc:1210
msgid "%1:%2 new capture file not initialized correctly"
msgstr "%1:%2 νέα δειγματοληψία δεν εκκινήθη σωστά"
#: audio_diskstream.cc:2175
#: audio_diskstream.cc:2200
msgid "%1: cannot restore pending capture source file %2"
msgstr "%1: δεν μπορώ να ανοίξω το αρχείο %2 από την απαιτούμενη πηγή"
#: audio_diskstream.cc:2197
#: audio_diskstream.cc:2222
msgid "%1: incorrect number of pending sources listed - ignoring them all"
msgstr "%1: ετυπώθη λανθασμένος αριθμός απαιτούμενων πηγών - αγνοήθηκαν όλες"
#: audio_diskstream.cc:2221
#: audio_diskstream.cc:2246
msgid "%1: cannot create whole-file region from pending capture sources"
msgstr ""
"%1: αδύνατη η δημιουργία ακέραιας περιοχής από τις απαιτούμενες πηγές "
@@ -131,7 +131,7 @@ msgstr ""
#: audio_playlist_source.cc:171 audiosource.cc:913 file_source.cc:529
#: midi_playlist_source.cc:144 midi_playlist_source.cc:152
#: midi_playlist_source.cc:159 midi_source.cc:371 plugin_insert.cc:644
#: midi_playlist_source.cc:159 midi_source.cc:371 plugin_insert.cc:643
#: rb_effect.cc:332 session.cc:2465 session.cc:2498 session.cc:3643
#: session_handle.cc:87 sndfilesource.cc:121
msgid "programming error: %1"
@@ -212,49 +212,49 @@ msgstr ""
msgid "Connect session to engine"
msgstr ""
#: audioengine.cc:844
#: audioengine.cc:843
msgid ""
"a port with the name \"%1\" already exists: check for duplicated track/bus "
"names"
msgstr ""
#: audioengine.cc:846 session.cc:1698
#: audioengine.cc:845 session.cc:1698
msgid ""
"No more JACK ports are available. You will need to stop %1 and restart JACK "
"with more ports if you need this many tracks."
msgstr ""
#: audioengine.cc:849
#: audioengine.cc:848
#, fuzzy
msgid "AudioEngine: cannot register port \"%1\": %2"
msgstr "IO: δεν μπορεί να καταχώρηθεί η θύρα εισόδου %1"
#: audioengine.cc:879
#: audioengine.cc:878
msgid "unable to create port: %1"
msgstr ""
#: audioengine.cc:933
#: audioengine.cc:932
msgid "connect called before engine was started"
msgstr "η σύνδεση εκλήθη πριν να εκκινηθεί η engine"
#: audioengine.cc:959
#: audioengine.cc:958
msgid "AudioEngine: cannot connect %1 (%2) to %3 (%4)"
msgstr "AudioEngine: αδύνατη η σύνδεση %1 (%2) σε %3 (%4)"
#: audioengine.cc:974 audioengine.cc:1005
#: audioengine.cc:973 audioengine.cc:1004
msgid "disconnect called before engine was started"
msgstr "η αποσύνδεση εκλήθη πριν να εκκινηθεί η engine"
#: audioengine.cc:1053
#: audioengine.cc:1052
#, fuzzy
msgid "get_port_by_name() called before engine was started"
msgstr "η ρουτίνα get_port_by_name() εκλήθη πριν να εκκινηθεί η engine"
#: audioengine.cc:1105
#: audioengine.cc:1104
msgid "get_ports called before engine was started"
msgstr "η ρουτίνα get_ports εκλήθη πριν να εκκινηθεί η engine"
#: audioengine.cc:1428
#: audioengine.cc:1427
msgid "failed to connect to JACK"
msgstr "Αποτυχία συνδέσεως με τον JACK"
@@ -540,7 +540,7 @@ msgstr ""
msgid "Lossless compression"
msgstr ""
#: export_format_manager.cc:207 export_format_specification.cc:579
#: export_format_manager.cc:218 export_format_specification.cc:579
msgid "Session rate"
msgstr ""
@@ -574,7 +574,7 @@ msgstr ""
msgid "Rectangular"
msgstr ""
#: export_formats.cc:52 session.cc:4854 session.cc:4870
#: export_formats.cc:52 session.cc:4861 session.cc:4877
msgid "None"
msgstr ""
@@ -796,25 +796,25 @@ msgstr "δεν μπορώ να καθορίσω τον τρέχοντα ενερ
msgid "unknown file type for session %1"
msgstr "άγνωστος τύπος αρχείου για την συνεδρία %1"
#: globals.cc:204
#: globals.cc:205
msgid "Could not set system open files limit to \"unlimited\""
msgstr ""
#: globals.cc:206
#: globals.cc:207
#, fuzzy
msgid "Could not set system open files limit to %1"
msgstr "αδύνατη η επαναφορά του state file από backup %1"
#: globals.cc:210
#: globals.cc:211
msgid "Your system is configured to limit %1 to only %2 open files"
msgstr ""
#: globals.cc:214
#: globals.cc:215
#, fuzzy
msgid "Could not get system open files limit (%1)"
msgstr "%1: δεν μπόρεσα να γράψω δεδομένα του αρχείου peak (%2)"
#: globals.cc:267
#: globals.cc:266
#, fuzzy
msgid "Loading configuration"
msgstr "Ανάκληση αρχείου ρυθμίσεων χρήστη %1"
@@ -975,21 +975,21 @@ msgstr ""
msgid "%d"
msgstr ""
#: ladspa_plugin.cc:87
#: ladspa_plugin.cc:88
msgid "LADSPA: module has no descriptor function."
msgstr "LADSPA: το module δεν έχει ενδεικτική λειτουργία."
#: ladspa_plugin.cc:92
#: ladspa_plugin.cc:93
msgid "LADSPA: plugin has gone away since discovery!"
msgstr "LADSPA: το plugin την 'κοπάνισε' μετά την ανακάλυψη του!"
#: ladspa_plugin.cc:99
#: ladspa_plugin.cc:100
msgid "LADSPA: \"%1\" cannot be used, since it cannot do inplace processing"
msgstr ""
"LADSPA: \"%1\" δεν μπορεί να χρησιμοποιηθεί, εφ'όσον δεν μπορεί να κάνει επι "
"τόπου επεξεργασία"
#: ladspa_plugin.cc:296
#: ladspa_plugin.cc:297
#, fuzzy
msgid ""
"illegal parameter number used with plugin \"%1\". This may indicate a change "
@@ -999,36 +999,36 @@ msgstr ""
"ενδείκνυται αλλαγή στο σχεδιασμό του plugin, και οι ρυθμίσεις ίσως να είναι "
"άκυρες"
#: ladspa_plugin.cc:373 ladspa_plugin.cc:418
#: ladspa_plugin.cc:376 ladspa_plugin.cc:426
msgid "Bad node sent to LadspaPlugin::set_state"
msgstr "Κακός κόμβος εστάλη στο LadspaPlugin::set_state"
#: ladspa_plugin.cc:386 ladspa_plugin.cc:431
#: ladspa_plugin.cc:391 ladspa_plugin.cc:440
msgid "LADSPA: no ladspa port number"
msgstr "LADSPA: κανείς αριθμός θύρας ladspa"
#: ladspa_plugin.cc:392 ladspa_plugin.cc:437
#: ladspa_plugin.cc:397 ladspa_plugin.cc:446
msgid "LADSPA: no ladspa port data"
msgstr "LADSPA: κανένα δεδομένο θύρας ladspa"
#: ladspa_plugin.cc:707
#: ladspa_plugin.cc:717
msgid "LADSPA: cannot load module from \"%1\""
msgstr "LADSPA: δεν μπορώ να φορτώσω module από \"%1\""
#: ladspa_plugin.cc:817
#: ladspa_plugin.cc:827
#, fuzzy
msgid "Could not locate HOME. Preset not removed."
msgstr "Δεν μπόρεσα να βρώ το HOME. Προ-ρύθμιση δεν αποθηκεύθηκε."
#: ladspa_plugin.cc:854 ladspa_plugin.cc:860
#: ladspa_plugin.cc:864 ladspa_plugin.cc:870
msgid "Could not create %1. Preset not saved. (%2)"
msgstr "Δεν μπόρεσα να δημιουργήσω το %1. Προ-ρύθμιση δεν αποθηκεύθηκε. (%2)"
#: ladspa_plugin.cc:867
#: ladspa_plugin.cc:877
msgid "Error saving presets file %1."
msgstr "Σφάλμα στην αποθήκευση αρχείου προ-ρυθμίσεων %1."
#: ladspa_plugin.cc:905
#: ladspa_plugin.cc:915
msgid "Could not locate HOME. Preset not saved."
msgstr "Δεν μπόρεσα να βρώ το HOME. Προ-ρύθμιση δεν αποθηκεύθηκε."
@@ -1071,7 +1071,7 @@ msgstr ""
msgid "incorrect XML mode passed to Locations::set_state"
msgstr "λανθασμένο XML mode πέρασε στις Τοποθεσίες::set_state"
#: location.cc:842 session.cc:4355 session_state.cc:1114
#: location.cc:842 session.cc:4362 session_state.cc:1114
msgid "session"
msgstr ""
@@ -1146,31 +1146,31 @@ msgid "MidiDiskstream %1: there is no existing playlist to make a copy of!"
msgstr ""
"AudioDiskstream %1: δεν υπάρχει λίστα αναπαρ/γής για να γίνει αντιγραφή!"
#: midi_diskstream.cc:685
#: midi_diskstream.cc:699
#, fuzzy
msgid "MidiDiskstream %1: cannot read %2 from playlist at frame %3"
msgstr ""
"AudioDiskstream %1: δεν μπόρεσα να διαβάσω %2 από τη λίστα αναπαρ/γής στο "
"frame %3"
#: midi_diskstream.cc:820
#: midi_diskstream.cc:834
#, fuzzy
msgid "MidiDiskstream %1: cannot write to disk"
msgstr "AudioDiskstream %1: δεν μπορώ να γράψω στο δίσκο"
#: midi_diskstream.cc:854
#: midi_diskstream.cc:868
#, fuzzy
msgid "MidiDiskstream \"%1\": cannot flush captured data to disk!"
msgstr ""
"AudioDiskstream \"%1\": αδύνατη η εκκαθάριση δειγματοληπτικών δεδομένων στο "
"δίσκο!"
#: midi_diskstream.cc:941
#: midi_diskstream.cc:955
#, fuzzy
msgid "%1: could not create region for complete midi file"
msgstr "%1: δεν μπόρεσα να δημιουργήσω περιοχή για ολόκληρο audio file"
#: midi_diskstream.cc:978
#: midi_diskstream.cc:992
#, fuzzy
msgid "MidiDiskstream: could not create region for captured midi!"
msgstr ""
@@ -1385,24 +1385,36 @@ msgstr ""
msgid "Could not construct playlist for PlaylistSource from session data!"
msgstr ""
#: plugin_insert.cc:599
#: plugin.cc:324
msgid ""
"Plugin presets are not supported in this build of %1. Consider paying for a "
"full version"
msgstr ""
#: plugin.cc:398
msgid ""
"Saving plugin settings is not supported in this build of %1. Consider paying "
"for the full version"
msgstr ""
#: plugin_insert.cc:598
msgid "programming error: "
msgstr "σφάλμα προγραμματισμού: "
#: plugin_insert.cc:908
#: plugin_insert.cc:926
#, fuzzy
msgid "XML node describing plugin is missing the `type' field"
msgstr "Στον κόμβο XML που περιγράφει το insert λείπει το πεδίο `type'"
#: plugin_insert.cc:923
#: plugin_insert.cc:941
msgid "unknown plugin type %1 in plugin insert state"
msgstr "άγνωστος τύπος plugin %1 στην κατάσταση εισαχθέντων plugins"
#: plugin_insert.cc:951
#: plugin_insert.cc:969
msgid "Plugin has no unique ID field"
msgstr ""
#: plugin_insert.cc:960
#: plugin_insert.cc:978
msgid ""
"Found a reference to a plugin (\"%1\") that is unknown.\n"
"Perhaps it was removed or moved since it was last used."
@@ -1410,15 +1422,15 @@ msgstr ""
"Ευρέθη μια αναφορά σε plugin (\"%1\") που είναι άγνωστο.\n"
"Ίσως έχει διαγραφεί ή μετακινηθεί από την τελευταία του χρήση."
#: plugin_insert.cc:1076
#: plugin_insert.cc:1094
msgid "PluginInsert: Auto: no ladspa port number"
msgstr "PluginInsert: Auto: χωρίς αριθμό θύρας ladspa"
#: plugin_insert.cc:1083
#: plugin_insert.cc:1101
msgid "PluginInsert: Auto: port id out of range"
msgstr "PluginInsert: Auto: το id θύρας είναι εκτός πεδίου"
#: plugin_insert.cc:1119
#: plugin_insert.cc:1137
#, fuzzy
msgid "PluginInsert: automatable control %1 not found - ignored"
msgstr "αβέβαιο συμβάν αυτοματισμού ευρέθηκε (και αγνοήθηκε)"
@@ -1577,25 +1589,25 @@ msgstr "Εισαγωγή: src_new() απέτυχε : %1"
msgid "return %1"
msgstr ""
#: route.cc:1100 route.cc:2550
#: route.cc:1105 route.cc:2581
#, fuzzy
msgid "unknown Processor type \"%1\"; ignored"
msgstr "άγνωστος τύπος Λήψης(Insert) \"%1\"... αγνοήθηκε"
#: route.cc:1112
#: route.cc:1117
#, fuzzy
msgid "processor could not be created. Ignored."
msgstr "εισαγωγή δεν μπόρεσε να δημιουργηθεί. Αγνοήθηκε."
#: route.cc:1983 route.cc:2203
#: route.cc:2007 route.cc:2234
msgid "Bad node sent to Route::set_state() [%1]"
msgstr "Κακός κόμβος εστάλη στο Route::set_state() [%1]"
#: route.cc:2042
#: route.cc:2067
msgid "Pannable state found for route (%1) without a panner!"
msgstr ""
#: route.cc:2106 route.cc:2110 route.cc:2317 route.cc:2321
#: route.cc:2137 route.cc:2141 route.cc:2348 route.cc:2352
msgid "badly formed order key string in state file! [%1] ... ignored."
msgstr ""
"δύσμορφη γραμμή κλειδιού ταξινομήσεως στο αρχείο καταστάσεως ! [%1] ... "
@@ -1865,17 +1877,17 @@ msgstr "%1: δεν μπορώ να αναζητήσω στο %2 για εξαγ
msgid "Export ended unexpectedly: %1"
msgstr ""
#: session_ltc.cc:220
#: session_ltc.cc:222
msgid ""
"LTC encoder: invalid framerate - LTC encoding is disabled for the remainder "
"of this session."
msgstr ""
#: session_midi.cc:427
#: session_midi.cc:428
msgid "Session: could not send full MIDI time code"
msgstr "Συνεδρία: δεν μπόρεσα να στείλω ολόκληρο MIDI time code"
#: session_midi.cc:519
#: session_midi.cc:520
msgid "Session: cannot send quarter-frame MTC message (%1)"
msgstr "Συνεδρία: δεν μπορώ να στείλω τέταρτο-frame MTC μήνυμα (%1)"
@@ -1883,11 +1895,11 @@ msgstr "Συνεδρία: δεν μπορώ να στείλω τέταρτο-fra
msgid "Session: cannot create Playlist from XML description."
msgstr "Συνεδρία: δεν μπορώ να δημιουργήσω την Playlist από την XML περιγραφή."
#: session_process.cc:135
#: session_process.cc:133
msgid "Session: error in no roll for %1"
msgstr "Συνεδρία: σφάλμα στο no roll για %1"
#: session_process.cc:1160
#: session_process.cc:1158
msgid "Programming error: illegal event type in process_event (%1)"
msgstr ""
"Σφάλμα προγραμματισμού: παράνομος τύπος συμβάντος στο process_event (%1)"
@@ -2303,7 +2315,7 @@ msgstr "Άγνωστη κατάσταση του JACK transport %1 στην αν
msgid "Cannot loop - no loop range defined"
msgstr "Δεν γίνεται loop - κανένα διάστημα loop δεν προσδιορίστηκε"
#: session_transport.cc:727
#: session_transport.cc:728
#, fuzzy
msgid ""
"Seamless looping cannot be supported while %1 is using JACK transport.\n"
@@ -2313,7 +2325,7 @@ msgstr ""
"transport.\n"
"Συνιστούμε την αλλαγή των διαμορφωμένων ρυθμίσεων"
#: session_transport.cc:1092
#: session_transport.cc:1094
#, fuzzy
msgid ""
"Global varispeed cannot be supported while %1 is connected to JACK transport "
@@ -2468,7 +2480,7 @@ msgstr "SndFileSource: δεν μπορούσα να αναζητήσω στο fr
msgid "attempt to write a non-writable audio file source (%1)"
msgstr ""
#: sndfilesource.cc:396 utils.cc:497 utils.cc:521 utils.cc:535 utils.cc:554
#: sndfilesource.cc:396 utils.cc:507 utils.cc:531 utils.cc:545 utils.cc:564
msgid "programming error: %1 %2"
msgstr "σφάλμα προγραμματισμού: %1 %2"
@@ -2730,12 +2742,12 @@ msgstr ""
msgid "LTC"
msgstr ""
#: utils.cc:589
#: utils.cc:599
#, fuzzy
msgid "programming error: unknown native header format: %1"
msgstr "σφάλμα προγραμματισμού: άγνωστος τύπος Redirect εδημιουργήθη!"
#: utils.cc:604
#: utils.cc:614
#, fuzzy
msgid "cannot open directory %1 (%2)"
msgstr "δεν μπορώ να ανοίξω το πρόσφατο αρχείο συνεδρίας %1 (%2)"

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: libardour\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-06-11 08:49-0400\n"
"POT-Creation-Date: 2013-09-03 07:59-0400\n"
"PO-Revision-Date: \n"
"Last-Translator: Pablo Fernández <pablo.fbus@gmail.com>\n"
"Language-Team: Grupo de Traducción al Español <traductores@teklibre.com>\n"
@@ -32,57 +32,57 @@ msgstr ""
msgid "AudioDiskstream %1: there is no existing playlist to make a copy of!"
msgstr "AudioDiskstream %1: ¡No hay ninguna lista de reproducción para copiar!"
#: audio_diskstream.cc:823 audio_diskstream.cc:833
#: audio_diskstream.cc:848 audio_diskstream.cc:858
msgid ""
"AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3"
msgstr ""
"AudioDiskstream %1: al rellenar, no se puede leer %2 de la lista de "
"reproducción en el cuadro %3."
#: audio_diskstream.cc:989
#: audio_diskstream.cc:1014
msgid "AudioDiskstream %1: cannot read %2 from playlist at frame %3"
msgstr ""
"AudioDiskstream %1: no se puede leer %2 de la lista de reproducción en el "
"cuadro %3."
#: audio_diskstream.cc:1358 audio_diskstream.cc:1375
#: audio_diskstream.cc:1383 audio_diskstream.cc:1400
msgid "AudioDiskstream %1: cannot write to disk"
msgstr "AudioDiskstream %1: no se puede escribir en el disco."
#: audio_diskstream.cc:1418
#: audio_diskstream.cc:1443
msgid "AudioDiskstream \"%1\": cannot flush captured data to disk!"
msgstr ""
#: audio_diskstream.cc:1512
#: audio_diskstream.cc:1537
msgid "%1: could not create region for complete audio file"
msgstr "%1: no se pudo crear la región para el archivo de audio completo"
#: audio_diskstream.cc:1546
#: audio_diskstream.cc:1571
msgid "AudioDiskstream: could not create region for captured audio!"
msgstr "AudioDiskstream: ¡No se pudo crear región para el audio capturado!"
#: audio_diskstream.cc:1654
#: audio_diskstream.cc:1679
msgid "programmer error: %1"
msgstr "error de programador: %1"
#: audio_diskstream.cc:1880
#: audio_diskstream.cc:1905
msgid "AudioDiskstream: channel %1 out of range"
msgstr "AudioDiskstream: canal %1 fuera de rango"
#: audio_diskstream.cc:1894 midi_diskstream.cc:1196
#: audio_diskstream.cc:1919 midi_diskstream.cc:1210
msgid "%1:%2 new capture file not initialized correctly"
msgstr "%1:%2 archivo de captura nuevo no inicializado correctamente"
#: audio_diskstream.cc:2175
#: audio_diskstream.cc:2200
msgid "%1: cannot restore pending capture source file %2"
msgstr "%1: no se puede restaurar el archivo de captura pendiente %2"
#: audio_diskstream.cc:2197
#: audio_diskstream.cc:2222
msgid "%1: incorrect number of pending sources listed - ignoring them all"
msgstr ""
"%1: cantidad listada de fuentes pendientes incorrecta - se ignorarán todas"
#: audio_diskstream.cc:2221
#: audio_diskstream.cc:2246
msgid "%1: cannot create whole-file region from pending capture sources"
msgstr ""
"%1: no se puede crear la región del archivo entero desde las fuentes de "
@@ -130,7 +130,7 @@ msgstr ""
#: audio_playlist_source.cc:171 audiosource.cc:913 file_source.cc:529
#: midi_playlist_source.cc:144 midi_playlist_source.cc:152
#: midi_playlist_source.cc:159 midi_source.cc:371 plugin_insert.cc:644
#: midi_playlist_source.cc:159 midi_source.cc:371 plugin_insert.cc:643
#: rb_effect.cc:332 session.cc:2465 session.cc:2498 session.cc:3643
#: session_handle.cc:87 sndfilesource.cc:121
msgid "programming error: %1"
@@ -210,7 +210,7 @@ msgstr ""
msgid "Connect session to engine"
msgstr "Conectar sesión al motor"
#: audioengine.cc:844
#: audioengine.cc:843
msgid ""
"a port with the name \"%1\" already exists: check for duplicated track/bus "
"names"
@@ -218,7 +218,7 @@ msgstr ""
"ya existe un puerto con el nombre \"%1\": compruebe si hay nombres de pistas/"
"buses duplicados"
#: audioengine.cc:846 session.cc:1698
#: audioengine.cc:845 session.cc:1698
msgid ""
"No more JACK ports are available. You will need to stop %1 and restart JACK "
"with more ports if you need this many tracks."
@@ -226,35 +226,35 @@ msgstr ""
"JACK no dispone de más puertos. Debes salir de %1 y reiniciar JACK con más "
"puertos si necesitas tantas pistas."
#: audioengine.cc:849
#: audioengine.cc:848
msgid "AudioEngine: cannot register port \"%1\": %2"
msgstr "AudioEngine: no se puede registrar el puerto \"%1\": %2"
#: audioengine.cc:879
#: audioengine.cc:878
msgid "unable to create port: %1"
msgstr "Incapaz de crear puerto: %1"
#: audioengine.cc:933
#: audioengine.cc:932
msgid "connect called before engine was started"
msgstr "conexión invocada antes de que se inicie el motor"
#: audioengine.cc:959
#: audioengine.cc:958
msgid "AudioEngine: cannot connect %1 (%2) to %3 (%4)"
msgstr "AudioEngine: no se puede conectar %1 (%2) a %3 (%4)"
#: audioengine.cc:974 audioengine.cc:1005
#: audioengine.cc:973 audioengine.cc:1004
msgid "disconnect called before engine was started"
msgstr "desconexión invocada antes de que se inicie el motor"
#: audioengine.cc:1053
#: audioengine.cc:1052
msgid "get_port_by_name() called before engine was started"
msgstr "get_port_by_name() invocada antes de que se inicie el motor"
#: audioengine.cc:1105
#: audioengine.cc:1104
msgid "get_ports called before engine was started"
msgstr "get_ports invocada antes de que se inicie el motor"
#: audioengine.cc:1428
#: audioengine.cc:1427
msgid "failed to connect to JACK"
msgstr "falló la conexión a JACK"
@@ -536,7 +536,7 @@ msgstr ""
msgid "Lossless compression"
msgstr ""
#: export_format_manager.cc:207 export_format_specification.cc:579
#: export_format_manager.cc:218 export_format_specification.cc:579
msgid "Session rate"
msgstr ""
@@ -568,7 +568,7 @@ msgstr ""
msgid "Rectangular"
msgstr ""
#: export_formats.cc:52 session.cc:4854 session.cc:4870
#: export_formats.cc:52 session.cc:4861 session.cc:4877
msgid "None"
msgstr ""
@@ -776,23 +776,23 @@ msgstr ""
msgid "unknown file type for session %1"
msgstr "tipo de archivo desconocido para la sesión %1"
#: globals.cc:204
#: globals.cc:205
msgid "Could not set system open files limit to \"unlimited\""
msgstr "No se pudo establecer el límite de archivos abiertos a \"unlimited\""
#: globals.cc:206
#: globals.cc:207
msgid "Could not set system open files limit to %1"
msgstr "No se pudo establecer el límite de archivos abiertos a \"unlimited\""
#: globals.cc:210
#: globals.cc:211
msgid "Your system is configured to limit %1 to only %2 open files"
msgstr ""
#: globals.cc:214
#: globals.cc:215
msgid "Could not get system open files limit (%1)"
msgstr "No se pudo obtener el límite de archivos abiertos del sistema (%1) "
#: globals.cc:267
#: globals.cc:266
msgid "Loading configuration"
msgstr "Cargando configuración"
@@ -944,53 +944,53 @@ msgstr ""
msgid "%d"
msgstr ""
#: ladspa_plugin.cc:87
#: ladspa_plugin.cc:88
msgid "LADSPA: module has no descriptor function."
msgstr ""
#: ladspa_plugin.cc:92
#: ladspa_plugin.cc:93
msgid "LADSPA: plugin has gone away since discovery!"
msgstr ""
#: ladspa_plugin.cc:99
#: ladspa_plugin.cc:100
msgid "LADSPA: \"%1\" cannot be used, since it cannot do inplace processing"
msgstr ""
#: ladspa_plugin.cc:296
#: ladspa_plugin.cc:297
msgid ""
"illegal parameter number used with plugin \"%1\". This may indicate a change "
"in the plugin design, and presets may be invalid"
msgstr ""
#: ladspa_plugin.cc:373 ladspa_plugin.cc:418
#: ladspa_plugin.cc:376 ladspa_plugin.cc:426
msgid "Bad node sent to LadspaPlugin::set_state"
msgstr ""
#: ladspa_plugin.cc:386 ladspa_plugin.cc:431
#: ladspa_plugin.cc:391 ladspa_plugin.cc:440
msgid "LADSPA: no ladspa port number"
msgstr ""
#: ladspa_plugin.cc:392 ladspa_plugin.cc:437
#: ladspa_plugin.cc:397 ladspa_plugin.cc:446
msgid "LADSPA: no ladspa port data"
msgstr ""
#: ladspa_plugin.cc:707
#: ladspa_plugin.cc:717
msgid "LADSPA: cannot load module from \"%1\""
msgstr ""
#: ladspa_plugin.cc:817
#: ladspa_plugin.cc:827
msgid "Could not locate HOME. Preset not removed."
msgstr ""
#: ladspa_plugin.cc:854 ladspa_plugin.cc:860
#: ladspa_plugin.cc:864 ladspa_plugin.cc:870
msgid "Could not create %1. Preset not saved. (%2)"
msgstr "No se pudo crear %1. El preset no se guardó. (%2)"
#: ladspa_plugin.cc:867
#: ladspa_plugin.cc:877
msgid "Error saving presets file %1."
msgstr "Error al guardar el archivo de preset %1."
#: ladspa_plugin.cc:905
#: ladspa_plugin.cc:915
msgid "Could not locate HOME. Preset not saved."
msgstr ""
@@ -1030,7 +1030,7 @@ msgstr ""
msgid "incorrect XML mode passed to Locations::set_state"
msgstr ""
#: location.cc:842 session.cc:4355 session_state.cc:1114
#: location.cc:842 session.cc:4362 session_state.cc:1114
msgid "session"
msgstr "sesión"
@@ -1107,23 +1107,23 @@ msgstr ""
msgid "MidiDiskstream %1: there is no existing playlist to make a copy of!"
msgstr ""
#: midi_diskstream.cc:685
#: midi_diskstream.cc:699
msgid "MidiDiskstream %1: cannot read %2 from playlist at frame %3"
msgstr ""
#: midi_diskstream.cc:820
#: midi_diskstream.cc:834
msgid "MidiDiskstream %1: cannot write to disk"
msgstr ""
#: midi_diskstream.cc:854
#: midi_diskstream.cc:868
msgid "MidiDiskstream \"%1\": cannot flush captured data to disk!"
msgstr ""
#: midi_diskstream.cc:941
#: midi_diskstream.cc:955
msgid "%1: could not create region for complete midi file"
msgstr ""
#: midi_diskstream.cc:978
#: midi_diskstream.cc:992
msgid "MidiDiskstream: could not create region for captured midi!"
msgstr ""
@@ -1317,23 +1317,35 @@ msgstr ""
msgid "Could not construct playlist for PlaylistSource from session data!"
msgstr ""
#: plugin_insert.cc:599
#: plugin.cc:324
msgid ""
"Plugin presets are not supported in this build of %1. Consider paying for a "
"full version"
msgstr ""
#: plugin.cc:398
msgid ""
"Saving plugin settings is not supported in this build of %1. Consider paying "
"for the full version"
msgstr ""
#: plugin_insert.cc:598
msgid "programming error: "
msgstr "error de programación:"
#: plugin_insert.cc:908
#: plugin_insert.cc:926
msgid "XML node describing plugin is missing the `type' field"
msgstr ""
#: plugin_insert.cc:923
#: plugin_insert.cc:941
msgid "unknown plugin type %1 in plugin insert state"
msgstr "Tipo de plugin desconocido %1 en estado de inserción de plugins"
#: plugin_insert.cc:951
#: plugin_insert.cc:969
msgid "Plugin has no unique ID field"
msgstr "El plugin no tiene un campo de ID único."
#: plugin_insert.cc:960
#: plugin_insert.cc:978
msgid ""
"Found a reference to a plugin (\"%1\") that is unknown.\n"
"Perhaps it was removed or moved since it was last used."
@@ -1341,15 +1353,15 @@ msgstr ""
"Se encontró una referencia a un plugin (\"%1\") que no se conoce.\n"
"Quizás se suprimió o se movió desde la última vez que fue usado."
#: plugin_insert.cc:1076
#: plugin_insert.cc:1094
msgid "PluginInsert: Auto: no ladspa port number"
msgstr ""
#: plugin_insert.cc:1083
#: plugin_insert.cc:1101
msgid "PluginInsert: Auto: port id out of range"
msgstr ""
#: plugin_insert.cc:1119
#: plugin_insert.cc:1137
msgid "PluginInsert: automatable control %1 not found - ignored"
msgstr ""
@@ -1494,23 +1506,23 @@ msgstr ""
msgid "return %1"
msgstr "retorno %1"
#: route.cc:1100 route.cc:2550
#: route.cc:1105 route.cc:2581
msgid "unknown Processor type \"%1\"; ignored"
msgstr ""
#: route.cc:1112
#: route.cc:1117
msgid "processor could not be created. Ignored."
msgstr ""
#: route.cc:1983 route.cc:2203
#: route.cc:2007 route.cc:2234
msgid "Bad node sent to Route::set_state() [%1]"
msgstr ""
#: route.cc:2042
#: route.cc:2067
msgid "Pannable state found for route (%1) without a panner!"
msgstr ""
#: route.cc:2106 route.cc:2110 route.cc:2317 route.cc:2321
#: route.cc:2137 route.cc:2141 route.cc:2348 route.cc:2352
msgid "badly formed order key string in state file! [%1] ... ignored."
msgstr ""
@@ -1763,17 +1775,17 @@ msgstr ""
msgid "Export ended unexpectedly: %1"
msgstr ""
#: session_ltc.cc:220
#: session_ltc.cc:222
msgid ""
"LTC encoder: invalid framerate - LTC encoding is disabled for the remainder "
"of this session."
msgstr ""
#: session_midi.cc:427
#: session_midi.cc:428
msgid "Session: could not send full MIDI time code"
msgstr ""
#: session_midi.cc:519
#: session_midi.cc:520
msgid "Session: cannot send quarter-frame MTC message (%1)"
msgstr ""
@@ -1781,11 +1793,11 @@ msgstr ""
msgid "Session: cannot create Playlist from XML description."
msgstr ""
#: session_process.cc:135
#: session_process.cc:133
msgid "Session: error in no roll for %1"
msgstr ""
#: session_process.cc:1160
#: session_process.cc:1158
msgid "Programming error: illegal event type in process_event (%1)"
msgstr ""
@@ -2141,13 +2153,13 @@ msgstr ""
msgid "Cannot loop - no loop range defined"
msgstr "No se puede reproducir en bucle - no se definió un rango de bucle."
#: session_transport.cc:727
#: session_transport.cc:728
msgid ""
"Seamless looping cannot be supported while %1 is using JACK transport.\n"
"Recommend changing the configured options"
msgstr ""
#: session_transport.cc:1092
#: session_transport.cc:1094
msgid ""
"Global varispeed cannot be supported while %1 is connected to JACK transport "
"control"
@@ -2290,7 +2302,7 @@ msgstr ""
msgid "attempt to write a non-writable audio file source (%1)"
msgstr ""
#: sndfilesource.cc:396 utils.cc:497 utils.cc:521 utils.cc:535 utils.cc:554
#: sndfilesource.cc:396 utils.cc:507 utils.cc:531 utils.cc:545 utils.cc:564
msgid "programming error: %1 %2"
msgstr "error de programación: %1 %2"
@@ -2536,11 +2548,11 @@ msgstr ""
msgid "LTC"
msgstr "LTC"
#: utils.cc:589
#: utils.cc:599
msgid "programming error: unknown native header format: %1"
msgstr ""
#: utils.cc:604
#: utils.cc:614
msgid "cannot open directory %1 (%2)"
msgstr ""

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: libardour 0.664.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-06-11 08:49-0400\n"
"POT-Creation-Date: 2013-09-03 07:59-0400\n"
"PO-Revision-Date: 2003-05-21 12:50+0500\n"
"Last-Translator: Filippo Pappalardo <filippo@email.it>\n"
"Language-Team: Italian\n"
@@ -29,60 +29,60 @@ msgstr ""
msgid "AudioDiskstream %1: there is no existing playlist to make a copy of!"
msgstr "DiskStream %1: non esiste alcuna playlist di cui fare una copia!"
#: audio_diskstream.cc:823 audio_diskstream.cc:833
#: audio_diskstream.cc:848 audio_diskstream.cc:858
#, fuzzy
msgid ""
"AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3"
msgstr "DiskStream %1: impossibile leggere %2 dalla playlista al frame %3"
#: audio_diskstream.cc:989
#: audio_diskstream.cc:1014
#, fuzzy
msgid "AudioDiskstream %1: cannot read %2 from playlist at frame %3"
msgstr "DiskStream %1: impossibile leggere %2 dalla playlista al frame %3"
#: audio_diskstream.cc:1358 audio_diskstream.cc:1375
#: audio_diskstream.cc:1383 audio_diskstream.cc:1400
#, fuzzy
msgid "AudioDiskstream %1: cannot write to disk"
msgstr "DiskStream %1: impossibile scrivere sul disco"
#: audio_diskstream.cc:1418
#: audio_diskstream.cc:1443
#, fuzzy
msgid "AudioDiskstream \"%1\": cannot flush captured data to disk!"
msgstr "DiskStream \"%1\": impossibile scaricare i dati acquisiti sul disco!"
#: audio_diskstream.cc:1512
#: audio_diskstream.cc:1537
msgid "%1: could not create region for complete audio file"
msgstr "%1: impossibile creare una regione per il file audio completo"
#: audio_diskstream.cc:1546
#: audio_diskstream.cc:1571
#, fuzzy
msgid "AudioDiskstream: could not create region for captured audio!"
msgstr "DiskStream: impossibile creare una regione per l'audio registrato!"
#: audio_diskstream.cc:1654
#: audio_diskstream.cc:1679
#, fuzzy
msgid "programmer error: %1"
msgstr "errore di programmazione: %1"
#: audio_diskstream.cc:1880
#: audio_diskstream.cc:1905
#, fuzzy
msgid "AudioDiskstream: channel %1 out of range"
msgstr "DiskStream: canale fuori margine"
#: audio_diskstream.cc:1894 midi_diskstream.cc:1196
#: audio_diskstream.cc:1919 midi_diskstream.cc:1210
msgid "%1:%2 new capture file not initialized correctly"
msgstr "%1:%2 nuovo file di registrazione non è stato avviato correttamente"
#: audio_diskstream.cc:2175
#: audio_diskstream.cc:2200
#, fuzzy
msgid "%1: cannot restore pending capture source file %2"
msgstr "Import: impossibile aprire il file audio di input \"%1\""
#: audio_diskstream.cc:2197
#: audio_diskstream.cc:2222
msgid "%1: incorrect number of pending sources listed - ignoring them all"
msgstr ""
#: audio_diskstream.cc:2221
#: audio_diskstream.cc:2246
#, fuzzy
msgid "%1: cannot create whole-file region from pending capture sources"
msgstr "Playlist: impossibile creare la Regione dal file di stato"
@@ -131,7 +131,7 @@ msgstr ""
#: audio_playlist_source.cc:171 audiosource.cc:913 file_source.cc:529
#: midi_playlist_source.cc:144 midi_playlist_source.cc:152
#: midi_playlist_source.cc:159 midi_source.cc:371 plugin_insert.cc:644
#: midi_playlist_source.cc:159 midi_source.cc:371 plugin_insert.cc:643
#: rb_effect.cc:332 session.cc:2465 session.cc:2498 session.cc:3643
#: session_handle.cc:87 sndfilesource.cc:121
msgid "programming error: %1"
@@ -209,51 +209,51 @@ msgstr ""
msgid "Connect session to engine"
msgstr ""
#: audioengine.cc:844
#: audioengine.cc:843
msgid ""
"a port with the name \"%1\" already exists: check for duplicated track/bus "
"names"
msgstr ""
#: audioengine.cc:846 session.cc:1698
#: audioengine.cc:845 session.cc:1698
msgid ""
"No more JACK ports are available. You will need to stop %1 and restart JACK "
"with more ports if you need this many tracks."
msgstr ""
#: audioengine.cc:849
#: audioengine.cc:848
#, fuzzy
msgid "AudioEngine: cannot register port \"%1\": %2"
msgstr "IO: impossibile registrare la porta %1"
#: audioengine.cc:879
#: audioengine.cc:878
msgid "unable to create port: %1"
msgstr ""
#: audioengine.cc:933
#: audioengine.cc:932
msgid "connect called before engine was started"
msgstr "richiesta di connessione avvenuta prima dell'avvio dell'applicazione"
#: audioengine.cc:959
#: audioengine.cc:958
msgid "AudioEngine: cannot connect %1 (%2) to %3 (%4)"
msgstr ""
#: audioengine.cc:974 audioengine.cc:1005
#: audioengine.cc:973 audioengine.cc:1004
msgid "disconnect called before engine was started"
msgstr ""
"richiesta di disconnessione avvenuta prima dell'avvio dell'applicazione"
#: audioengine.cc:1053
#: audioengine.cc:1052
#, fuzzy
msgid "get_port_by_name() called before engine was started"
msgstr ""
"richiesta get_port_by_name() avvenuta prima dell'avvio dell'applicazione"
#: audioengine.cc:1105
#: audioengine.cc:1104
msgid "get_ports called before engine was started"
msgstr "richiesta di get_ports avvenuta prima dell'avvio dell'applicazione"
#: audioengine.cc:1428
#: audioengine.cc:1427
msgid "failed to connect to JACK"
msgstr ""
@@ -538,7 +538,7 @@ msgstr ""
msgid "Lossless compression"
msgstr ""
#: export_format_manager.cc:207 export_format_specification.cc:579
#: export_format_manager.cc:218 export_format_specification.cc:579
msgid "Session rate"
msgstr ""
@@ -572,7 +572,7 @@ msgstr ""
msgid "Rectangular"
msgstr ""
#: export_formats.cc:52 session.cc:4854 session.cc:4870
#: export_formats.cc:52 session.cc:4861 session.cc:4877
msgid "None"
msgstr ""
@@ -797,25 +797,25 @@ msgstr "impossibile determinare la cartella di lavoro corrente (%1)"
msgid "unknown file type for session %1"
msgstr "tipo di fle sconosciuto per la sessione %1"
#: globals.cc:204
#: globals.cc:205
msgid "Could not set system open files limit to \"unlimited\""
msgstr ""
#: globals.cc:206
#: globals.cc:207
#, fuzzy
msgid "Could not set system open files limit to %1"
msgstr "Esportazione: impossibile scrivere dati sul file di output (%1)"
#: globals.cc:210
#: globals.cc:211
msgid "Your system is configured to limit %1 to only %2 open files"
msgstr ""
#: globals.cc:214
#: globals.cc:215
#, fuzzy
msgid "Could not get system open files limit (%1)"
msgstr "IO: impossibile registrare la porta %1"
#: globals.cc:267
#: globals.cc:266
#, fuzzy
msgid "Loading configuration"
msgstr "Ardour: impossibile la lettura del file di configurazione \"%1\""
@@ -972,54 +972,54 @@ msgstr ""
msgid "%d"
msgstr ""
#: ladspa_plugin.cc:87
#: ladspa_plugin.cc:88
msgid "LADSPA: module has no descriptor function."
msgstr "LADSPA: il modulo non ha alcuna funzione descriptor."
#: ladspa_plugin.cc:92
#: ladspa_plugin.cc:93
msgid "LADSPA: plugin has gone away since discovery!"
msgstr "LADSPA: il plugin è stato rimosso"
#: ladspa_plugin.cc:99
#: ladspa_plugin.cc:100
msgid "LADSPA: \"%1\" cannot be used, since it cannot do inplace processing"
msgstr ""
#: ladspa_plugin.cc:296
#: ladspa_plugin.cc:297
msgid ""
"illegal parameter number used with plugin \"%1\". This may indicate a change "
"in the plugin design, and presets may be invalid"
msgstr ""
#: ladspa_plugin.cc:373 ladspa_plugin.cc:418
#: ladspa_plugin.cc:376 ladspa_plugin.cc:426
msgid "Bad node sent to LadspaPlugin::set_state"
msgstr ""
#: ladspa_plugin.cc:386 ladspa_plugin.cc:431
#: ladspa_plugin.cc:391 ladspa_plugin.cc:440
msgid "LADSPA: no ladspa port number"
msgstr ""
#: ladspa_plugin.cc:392 ladspa_plugin.cc:437
#: ladspa_plugin.cc:397 ladspa_plugin.cc:446
msgid "LADSPA: no ladspa port data"
msgstr ""
#: ladspa_plugin.cc:707
#: ladspa_plugin.cc:717
msgid "LADSPA: cannot load module from \"%1\""
msgstr "LADPSA: impossibile caricare il modulo da \"%1\""
#: ladspa_plugin.cc:817
#: ladspa_plugin.cc:827
#, fuzzy
msgid "Could not locate HOME. Preset not removed."
msgstr "impossibile localizzare HOME. Preset non salvato."
#: ladspa_plugin.cc:854 ladspa_plugin.cc:860
#: ladspa_plugin.cc:864 ladspa_plugin.cc:870
msgid "Could not create %1. Preset not saved. (%2)"
msgstr "Impossibile creare %1 . Preset non salvato. (%2)"
#: ladspa_plugin.cc:867
#: ladspa_plugin.cc:877
msgid "Error saving presets file %1."
msgstr "Errore nel salvare il file di preset %1."
#: ladspa_plugin.cc:905
#: ladspa_plugin.cc:915
msgid "Could not locate HOME. Preset not saved."
msgstr "impossibile localizzare HOME. Preset non salvato."
@@ -1060,7 +1060,7 @@ msgstr ""
msgid "incorrect XML mode passed to Locations::set_state"
msgstr ""
#: location.cc:842 session.cc:4355 session_state.cc:1114
#: location.cc:842 session.cc:4362 session_state.cc:1114
msgid "session"
msgstr ""
@@ -1134,27 +1134,27 @@ msgstr "DiskStream %1: impossibile leggere %2 dalla playlista al frame %3"
msgid "MidiDiskstream %1: there is no existing playlist to make a copy of!"
msgstr "DiskStream %1: non esiste alcuna playlist di cui fare una copia!"
#: midi_diskstream.cc:685
#: midi_diskstream.cc:699
#, fuzzy
msgid "MidiDiskstream %1: cannot read %2 from playlist at frame %3"
msgstr "DiskStream %1: impossibile leggere %2 dalla playlista al frame %3"
#: midi_diskstream.cc:820
#: midi_diskstream.cc:834
#, fuzzy
msgid "MidiDiskstream %1: cannot write to disk"
msgstr "DiskStream %1: impossibile scrivere sul disco"
#: midi_diskstream.cc:854
#: midi_diskstream.cc:868
#, fuzzy
msgid "MidiDiskstream \"%1\": cannot flush captured data to disk!"
msgstr "DiskStream \"%1\": impossibile scaricare i dati acquisiti sul disco!"
#: midi_diskstream.cc:941
#: midi_diskstream.cc:955
#, fuzzy
msgid "%1: could not create region for complete midi file"
msgstr "%1: impossibile creare una regione per il file audio completo"
#: midi_diskstream.cc:978
#: midi_diskstream.cc:992
#, fuzzy
msgid "MidiDiskstream: could not create region for captured midi!"
msgstr "DiskStream: impossibile creare una regione per l'audio registrato!"
@@ -1360,24 +1360,36 @@ msgstr ""
msgid "Could not construct playlist for PlaylistSource from session data!"
msgstr ""
#: plugin_insert.cc:599
#: plugin.cc:324
msgid ""
"Plugin presets are not supported in this build of %1. Consider paying for a "
"full version"
msgstr ""
#: plugin.cc:398
msgid ""
"Saving plugin settings is not supported in this build of %1. Consider paying "
"for the full version"
msgstr ""
#: plugin_insert.cc:598
msgid "programming error: "
msgstr "errore di programmazione: "
#: plugin_insert.cc:908
#: plugin_insert.cc:926
#, fuzzy
msgid "XML node describing plugin is missing the `type' field"
msgstr "Il nodo XML descrivente l'insert manca del campo `type'"
#: plugin_insert.cc:923
#: plugin_insert.cc:941
msgid "unknown plugin type %1 in plugin insert state"
msgstr ""
#: plugin_insert.cc:951
#: plugin_insert.cc:969
msgid "Plugin has no unique ID field"
msgstr ""
#: plugin_insert.cc:960
#: plugin_insert.cc:978
msgid ""
"Found a reference to a plugin (\"%1\") that is unknown.\n"
"Perhaps it was removed or moved since it was last used."
@@ -1385,15 +1397,15 @@ msgstr ""
"Trovato un riferimento ad un plugin (\"%1\") sconosciuto.\n"
"Forse stato rimosso o spostato dall'ultima volta che lo si e' usato"
#: plugin_insert.cc:1076
#: plugin_insert.cc:1094
msgid "PluginInsert: Auto: no ladspa port number"
msgstr ""
#: plugin_insert.cc:1083
#: plugin_insert.cc:1101
msgid "PluginInsert: Auto: port id out of range"
msgstr ""
#: plugin_insert.cc:1119
#: plugin_insert.cc:1137
msgid "PluginInsert: automatable control %1 not found - ignored"
msgstr ""
@@ -1551,25 +1563,25 @@ msgstr ""
msgid "return %1"
msgstr ""
#: route.cc:1100 route.cc:2550
#: route.cc:1105 route.cc:2581
#, fuzzy
msgid "unknown Processor type \"%1\"; ignored"
msgstr "impossibile creare la cartella per la sessione %1; ignorato"
#: route.cc:1112
#: route.cc:1117
#, fuzzy
msgid "processor could not be created. Ignored."
msgstr "Sessione: impossibile creare un nuovo route"
#: route.cc:1983 route.cc:2203
#: route.cc:2007 route.cc:2234
msgid "Bad node sent to Route::set_state() [%1]"
msgstr ""
#: route.cc:2042
#: route.cc:2067
msgid "Pannable state found for route (%1) without a panner!"
msgstr ""
#: route.cc:2106 route.cc:2110 route.cc:2317 route.cc:2321
#: route.cc:2137 route.cc:2141 route.cc:2348 route.cc:2352
msgid "badly formed order key string in state file! [%1] ... ignored."
msgstr ""
@@ -1834,17 +1846,17 @@ msgstr ""
msgid "Export ended unexpectedly: %1"
msgstr ""
#: session_ltc.cc:220
#: session_ltc.cc:222
msgid ""
"LTC encoder: invalid framerate - LTC encoding is disabled for the remainder "
"of this session."
msgstr ""
#: session_midi.cc:427
#: session_midi.cc:428
msgid "Session: could not send full MIDI time code"
msgstr ""
#: session_midi.cc:519
#: session_midi.cc:520
msgid "Session: cannot send quarter-frame MTC message (%1)"
msgstr ""
@@ -1852,11 +1864,11 @@ msgstr ""
msgid "Session: cannot create Playlist from XML description."
msgstr "Sessione: impossibile creare Playlist dalla descrizione XML"
#: session_process.cc:135
#: session_process.cc:133
msgid "Session: error in no roll for %1"
msgstr ""
#: session_process.cc:1160
#: session_process.cc:1158
msgid "Programming error: illegal event type in process_event (%1)"
msgstr ""
@@ -2271,13 +2283,13 @@ msgstr ""
msgid "Cannot loop - no loop range defined"
msgstr ""
#: session_transport.cc:727
#: session_transport.cc:728
msgid ""
"Seamless looping cannot be supported while %1 is using JACK transport.\n"
"Recommend changing the configured options"
msgstr ""
#: session_transport.cc:1092
#: session_transport.cc:1094
msgid ""
"Global varispeed cannot be supported while %1 is connected to JACK transport "
"control"
@@ -2426,7 +2438,7 @@ msgstr "FileSource: impossibile aprire \"%1\": (%2)"
msgid "attempt to write a non-writable audio file source (%1)"
msgstr ""
#: sndfilesource.cc:396 utils.cc:497 utils.cc:521 utils.cc:535 utils.cc:554
#: sndfilesource.cc:396 utils.cc:507 utils.cc:531 utils.cc:545 utils.cc:564
#, fuzzy
msgid "programming error: %1 %2"
msgstr "errore di programmazione: %1"
@@ -2681,11 +2693,11 @@ msgstr ""
msgid "LTC"
msgstr ""
#: utils.cc:589
#: utils.cc:599
msgid "programming error: unknown native header format: %1"
msgstr ""
#: utils.cc:604
#: utils.cc:614
#, fuzzy
msgid "cannot open directory %1 (%2)"
msgstr "impossibile accedere al file di sessione recente %1 (%2)"

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: libardour\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-06-11 08:49-0400\n"
"POT-Creation-Date: 2013-09-03 07:59-0400\n"
"PO-Revision-Date: 2011-09-13 22:43+0100\n"
"Last-Translator: Eivind Ødegård <meinmycell-lists@yahoo.no>\n"
"Language-Team: Nynorsk <i18n-nn@lister.ping.uio.no>\n"
@@ -32,54 +32,54 @@ msgstr "Lyd-diskstraum: Spelelista \"%1\" er ikkje ei lydspeleliste"
msgid "AudioDiskstream %1: there is no existing playlist to make a copy of!"
msgstr "Lyd-diskstraum %1: det finst inga speleliste å kopiera!"
#: audio_diskstream.cc:823 audio_diskstream.cc:833
#: audio_diskstream.cc:848 audio_diskstream.cc:858
msgid ""
"AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3"
msgstr ""
"Lyd-diskstraum %1: greidde ikkje lesa %2 frå spelelista, ramme %3, ved "
"attfylling"
#: audio_diskstream.cc:989
#: audio_diskstream.cc:1014
msgid "AudioDiskstream %1: cannot read %2 from playlist at frame %3"
msgstr "Lyd-diskstraum %1: greidde ikkje lesa %2 frå spelelista, ramme %3"
#: audio_diskstream.cc:1358 audio_diskstream.cc:1375
#: audio_diskstream.cc:1383 audio_diskstream.cc:1400
msgid "AudioDiskstream %1: cannot write to disk"
msgstr "Lyd-diskstraum %1: greidde ikkje skriva til disk"
#: audio_diskstream.cc:1418
#: audio_diskstream.cc:1443
msgid "AudioDiskstream \"%1\": cannot flush captured data to disk!"
msgstr "Lyd-diskstraum \"%1\": greier ikkje skriva opptaket til disken!"
#: audio_diskstream.cc:1512
#: audio_diskstream.cc:1537
msgid "%1: could not create region for complete audio file"
msgstr "%1: greidde ikkje laga bolk for heil lydfil"
#: audio_diskstream.cc:1546
#: audio_diskstream.cc:1571
msgid "AudioDiskstream: could not create region for captured audio!"
msgstr "Lyd-diskstraum: greidde ikkje laga bolk frå opptaket!"
#: audio_diskstream.cc:1654
#: audio_diskstream.cc:1679
msgid "programmer error: %1"
msgstr "Programmerarfeil: %1"
#: audio_diskstream.cc:1880
#: audio_diskstream.cc:1905
msgid "AudioDiskstream: channel %1 out of range"
msgstr "Lyd-diskstraum: kanal %1 utanfor rekkjevidd"
#: audio_diskstream.cc:1894 midi_diskstream.cc:1196
#: audio_diskstream.cc:1919 midi_diskstream.cc:1210
msgid "%1:%2 new capture file not initialized correctly"
msgstr "%1: ny opptaksfil %2 vart ikkje påbyrja rett"
#: audio_diskstream.cc:2175
#: audio_diskstream.cc:2200
msgid "%1: cannot restore pending capture source file %2"
msgstr "%1: greidde ikkje henta fram att den ventande opptakskjeldefila %2"
#: audio_diskstream.cc:2197
#: audio_diskstream.cc:2222
msgid "%1: incorrect number of pending sources listed - ignoring them all"
msgstr "%1: feil tal på ventande kjelder på lista - ser bort frå alle"
#: audio_diskstream.cc:2221
#: audio_diskstream.cc:2246
msgid "%1: cannot create whole-file region from pending capture sources"
msgstr "%1: greidde ikkje laga heilfilbolk frå ventande opptakskjelder"
@@ -125,7 +125,7 @@ msgstr "Lydspelelister (ubrukte)"
#: audio_playlist_source.cc:171 audiosource.cc:913 file_source.cc:529
#: midi_playlist_source.cc:144 midi_playlist_source.cc:152
#: midi_playlist_source.cc:159 midi_source.cc:371 plugin_insert.cc:644
#: midi_playlist_source.cc:159 midi_source.cc:371 plugin_insert.cc:643
#: rb_effect.cc:332 session.cc:2465 session.cc:2498 session.cc:3643
#: session_handle.cc:87 sndfilesource.cc:121
msgid "programming error: %1"
@@ -207,7 +207,7 @@ msgstr ""
msgid "Connect session to engine"
msgstr "Kople økta til maskin"
#: audioengine.cc:844
#: audioengine.cc:843
msgid ""
"a port with the name \"%1\" already exists: check for duplicated track/bus "
"names"
@@ -215,7 +215,7 @@ msgstr ""
"ein port med namnet \"%1\" finst frå før: sjekk opp dublettar i namn på spor "
"eller bussar"
#: audioengine.cc:846 session.cc:1698
#: audioengine.cc:845 session.cc:1698
#, fuzzy
msgid ""
"No more JACK ports are available. You will need to stop %1 and restart JACK "
@@ -224,35 +224,35 @@ msgstr ""
"Det finst ikkje fleire JACK-portar. Du må stoppa %1 og starta JACK på nytt "
"med nok portar viss du treng så mange spor."
#: audioengine.cc:849
#: audioengine.cc:848
msgid "AudioEngine: cannot register port \"%1\": %2"
msgstr "AudioEngine: greier ikkje registrera porten \"%1\": %2"
#: audioengine.cc:879
#: audioengine.cc:878
msgid "unable to create port: %1"
msgstr "greidde ikkje laga port: %1"
#: audioengine.cc:933
#: audioengine.cc:932
msgid "connect called before engine was started"
msgstr "tilkoplinga vart oppkalla frø tenaren starta"
#: audioengine.cc:959
#: audioengine.cc:958
msgid "AudioEngine: cannot connect %1 (%2) to %3 (%4)"
msgstr "Lydmaskineri: Klarte ikkje kopla %1 (%2) til %3 (%4)."
#: audioengine.cc:974 audioengine.cc:1005
#: audioengine.cc:973 audioengine.cc:1004
msgid "disconnect called before engine was started"
msgstr "fråkoplinga vart oppkalla før tenaren starta"
#: audioengine.cc:1053
#: audioengine.cc:1052
msgid "get_port_by_name() called before engine was started"
msgstr "get_port_by_name() vart oppkalla før tenaren starta"
#: audioengine.cc:1105
#: audioengine.cc:1104
msgid "get_ports called before engine was started"
msgstr "get_ports vart oppkalla før tenaren starta"
#: audioengine.cc:1428
#: audioengine.cc:1427
msgid "failed to connect to JACK"
msgstr "greidde ikkje kopla til JACK"
@@ -541,7 +541,7 @@ msgstr "Komprimering med tap"
msgid "Lossless compression"
msgstr "Tapsfri komprimering"
#: export_format_manager.cc:207 export_format_specification.cc:579
#: export_format_manager.cc:218 export_format_specification.cc:579
msgid "Session rate"
msgstr "Øktrate"
@@ -577,7 +577,7 @@ msgstr "Trekant"
msgid "Rectangular"
msgstr "Firkant"
#: export_formats.cc:52 session.cc:4854 session.cc:4870
#: export_formats.cc:52 session.cc:4861 session.cc:4877
msgid "None"
msgstr "Ingen"
@@ -795,23 +795,23 @@ msgstr "greier ikkje avgjera kva som er arbeidsmappa no (%1)"
msgid "unknown file type for session %1"
msgstr "ukjend filtype for økta %1"
#: globals.cc:204
#: globals.cc:205
msgid "Could not set system open files limit to \"unlimited\""
msgstr "Greidde ikkje setja systemgrensa for opne filer til \"uavgrensa\""
#: globals.cc:206
#: globals.cc:207
msgid "Could not set system open files limit to %1"
msgstr "Greidde ikkje setja grensa for opne systemfiler til %1"
#: globals.cc:210
#: globals.cc:211
msgid "Your system is configured to limit %1 to only %2 open files"
msgstr ""
#: globals.cc:214
#: globals.cc:215
msgid "Could not get system open files limit (%1)"
msgstr "Greidde ikkje få tak i grensa for opne systemfiler (%1)"
#: globals.cc:267
#: globals.cc:266
msgid "Loading configuration"
msgstr "Lastar oppsettet"
@@ -966,20 +966,20 @@ msgstr "H"
msgid "%d"
msgstr "%d"
#: ladspa_plugin.cc:87
#: ladspa_plugin.cc:88
msgid "LADSPA: module has no descriptor function."
msgstr "LADSPA: modulen har ingen skildringsfunksjon"
#: ladspa_plugin.cc:92
#: ladspa_plugin.cc:93
msgid "LADSPA: plugin has gone away since discovery!"
msgstr "LADSPA: tilleggsprogrammet har vorte borte sidan det vart oppdaga!"
#: ladspa_plugin.cc:99
#: ladspa_plugin.cc:100
msgid "LADSPA: \"%1\" cannot be used, since it cannot do inplace processing"
msgstr ""
"LADSPA: kan ikkje bruka \"%1\", sidan han ikkje kan prosessera på staden"
#: ladspa_plugin.cc:296
#: ladspa_plugin.cc:297
#, fuzzy
msgid ""
"illegal parameter number used with plugin \"%1\". This may indicate a change "
@@ -989,35 +989,35 @@ msgstr ""
"tyda på feil i korleis tilleggsprogrammet er utforma, og at eventuelle "
"ferdigprogram kan vera ugyldige."
#: ladspa_plugin.cc:373 ladspa_plugin.cc:418
#: ladspa_plugin.cc:376 ladspa_plugin.cc:426
msgid "Bad node sent to LadspaPlugin::set_state"
msgstr "Feil punkt sendt til LadspaPlugin::set_state"
#: ladspa_plugin.cc:386 ladspa_plugin.cc:431
#: ladspa_plugin.cc:391 ladspa_plugin.cc:440
msgid "LADSPA: no ladspa port number"
msgstr "LADSPA: ikkje noko Ladspa-portnummer"
#: ladspa_plugin.cc:392 ladspa_plugin.cc:437
#: ladspa_plugin.cc:397 ladspa_plugin.cc:446
msgid "LADSPA: no ladspa port data"
msgstr "LADSPA: ingen portdata"
#: ladspa_plugin.cc:707
#: ladspa_plugin.cc:717
msgid "LADSPA: cannot load module from \"%1\""
msgstr "LADSPA: greier ikkje lasta modul frå \"%1\""
#: ladspa_plugin.cc:817
#: ladspa_plugin.cc:827
msgid "Could not locate HOME. Preset not removed."
msgstr "Greidde ikkje finna heimemappa. Har ikkje fjera ferdigoppsett."
#: ladspa_plugin.cc:854 ladspa_plugin.cc:860
#: ladspa_plugin.cc:864 ladspa_plugin.cc:870
msgid "Could not create %1. Preset not saved. (%2)"
msgstr "Greidde ikkje laga %1. Har ikkje lagra ferdigoppsett. (%2)"
#: ladspa_plugin.cc:867
#: ladspa_plugin.cc:877
msgid "Error saving presets file %1."
msgstr "Feil med å lagra ferdigoppsettfila %1."
#: ladspa_plugin.cc:905
#: ladspa_plugin.cc:915
msgid "Could not locate HOME. Preset not saved."
msgstr "Greidde ikkje finna heimemappa. Har ikkje lagra ferdigoppsett."
@@ -1057,7 +1057,7 @@ msgstr "Stader: forsøk på å bruka ukjend stad som vald stad"
msgid "incorrect XML mode passed to Locations::set_state"
msgstr "feil XML-modus send til Locations::set_state"
#: location.cc:842 session.cc:4355 session_state.cc:1114
#: location.cc:842 session.cc:4362 session_state.cc:1114
msgid "session"
msgstr "økt"
@@ -1140,23 +1140,23 @@ msgstr "MIDI-diskstraum: Spelelista \"%1\" er ikkje ei midispeleliste"
msgid "MidiDiskstream %1: there is no existing playlist to make a copy of!"
msgstr "MIDI-diskstraum %1: det finst inga speleliste å kopiera!"
#: midi_diskstream.cc:685
#: midi_diskstream.cc:699
msgid "MidiDiskstream %1: cannot read %2 from playlist at frame %3"
msgstr "MIDI-diskstraum %1: greidde ikkje lesa %2 frå spelelista, ramme %3"
#: midi_diskstream.cc:820
#: midi_diskstream.cc:834
msgid "MidiDiskstream %1: cannot write to disk"
msgstr "MIDI-diskstraum %1: greidde ikkje skriva til disk"
#: midi_diskstream.cc:854
#: midi_diskstream.cc:868
msgid "MidiDiskstream \"%1\": cannot flush captured data to disk!"
msgstr "MIDI-diskstraum \"%1\": greier ikkje skriva opptaket til disken!"
#: midi_diskstream.cc:941
#: midi_diskstream.cc:955
msgid "%1: could not create region for complete midi file"
msgstr "%1: greidde ikkje laga bolk for heil midifil"
#: midi_diskstream.cc:978
#: midi_diskstream.cc:992
msgid "MidiDiskstream: could not create region for captured midi!"
msgstr "MIDI-diskstraum: greidde ikkje laga bolk frå midi-opptaket!"
@@ -1355,23 +1355,41 @@ msgstr "Fann ingen speleliste-ID i PlaylistSource-XML!"
msgid "Could not construct playlist for PlaylistSource from session data!"
msgstr "Greidde ikkje byggja speleliste for PlaylistSource frå øktdata!"
#: plugin_insert.cc:599
#: plugin.cc:324
#, fuzzy
msgid ""
"Plugin presets are not supported in this build of %1. Consider paying for a "
"full version"
msgstr ""
"Du kan ikkje lagra førehandsoppsett for AudioUnit i denne versjonen av "
"Ardour. Du bør vurdera å betala for ein nyare verjson"
#: plugin.cc:398
#, fuzzy
msgid ""
"Saving plugin settings is not supported in this build of %1. Consider paying "
"for the full version"
msgstr ""
"Du kan ikkje lagra AudioUnit-innstillingar i denne versjonen av Ardour. Du "
"bør vurdera å betala for ein nyare verjson"
#: plugin_insert.cc:598
msgid "programming error: "
msgstr "programmeringsfeil: "
#: plugin_insert.cc:908
#: plugin_insert.cc:926
msgid "XML node describing plugin is missing the `type' field"
msgstr "XML-punktet som skildrar utvidinga manglar 'type'-feltet"
#: plugin_insert.cc:923
#: plugin_insert.cc:941
msgid "unknown plugin type %1 in plugin insert state"
msgstr "ukjent programtilleggstype %1 i innpluggingstilstanden"
#: plugin_insert.cc:951
#: plugin_insert.cc:969
msgid "Plugin has no unique ID field"
msgstr "Innstikket har ikkje noko eige ID-felt"
#: plugin_insert.cc:960
#: plugin_insert.cc:978
msgid ""
"Found a reference to a plugin (\"%1\") that is unknown.\n"
"Perhaps it was removed or moved since it was last used."
@@ -1379,15 +1397,15 @@ msgstr ""
"Fann ein referanse til det ukjende tilleggsprogrammet \"%1\".\n"
"Kanskje det har vorte fjerna eller flytt sidan sist det vart brukt."
#: plugin_insert.cc:1076
#: plugin_insert.cc:1094
msgid "PluginInsert: Auto: no ladspa port number"
msgstr "PluginInsert:Auto: ikkje noko ladspa-portnummer"
#: plugin_insert.cc:1083
#: plugin_insert.cc:1101
msgid "PluginInsert: Auto: port id out of range"
msgstr "PluginInsert: Auto: port-id utanfor rekkjevidd"
#: plugin_insert.cc:1119
#: plugin_insert.cc:1137
msgid "PluginInsert: automatable control %1 not found - ignored"
msgstr ""
"PluginInsert: fann ikkje den automasjonsferdige kontrollen %1, såg bort frå "
@@ -1541,23 +1559,23 @@ msgstr "Import: src_new()-funkjsonen lukkast ikkje: %1"
msgid "return %1"
msgstr "retur %1"
#: route.cc:1100 route.cc:2550
#: route.cc:1105 route.cc:2581
msgid "unknown Processor type \"%1\"; ignored"
msgstr "\"%1\" er ein ukjend prosesseringstype, hoppa over"
#: route.cc:1112
#: route.cc:1117
msgid "processor could not be created. Ignored."
msgstr "greidde ikkje laga prosessering. Hoppa over."
#: route.cc:1983 route.cc:2203
#: route.cc:2007 route.cc:2234
msgid "Bad node sent to Route::set_state() [%1]"
msgstr "Feil punkt sendt til Route::set_state()-funksjonen [%1]"
#: route.cc:2042
#: route.cc:2067
msgid "Pannable state found for route (%1) without a panner!"
msgstr "Fann panoreringsstatus for ruta (%1) utan panorering!"
#: route.cc:2106 route.cc:2110 route.cc:2317 route.cc:2321
#: route.cc:2137 route.cc:2141 route.cc:2348 route.cc:2352
msgid "badly formed order key string in state file! [%1] ... ignored."
msgstr "feilforma tingingsnykjelstreng i tilstandsfil! [%1] ... hoppa over."
@@ -1821,17 +1839,17 @@ msgstr "%1: greier ikkje finna %2 for eksportering"
msgid "Export ended unexpectedly: %1"
msgstr ""
#: session_ltc.cc:220
#: session_ltc.cc:222
msgid ""
"LTC encoder: invalid framerate - LTC encoding is disabled for the remainder "
"of this session."
msgstr ""
#: session_midi.cc:427
#: session_midi.cc:428
msgid "Session: could not send full MIDI time code"
msgstr "Økt: greidde ikke senda full MIDI-tidskode"
#: session_midi.cc:519
#: session_midi.cc:520
msgid "Session: cannot send quarter-frame MTC message (%1)"
msgstr "Økt: greidde ikkje senda kvartramme-MTC-melding (%1)"
@@ -1839,11 +1857,11 @@ msgstr "Økt: greidde ikkje senda kvartramme-MTC-melding (%1)"
msgid "Session: cannot create Playlist from XML description."
msgstr "Økt: greier ikkje laga speleliste ut frå XML-skildringa."
#: session_process.cc:135
#: session_process.cc:133
msgid "Session: error in no roll for %1"
msgstr "Økt: feil på ingen rull for %1"
#: session_process.cc:1160
#: session_process.cc:1158
msgid "Programming error: illegal event type in process_event (%1)"
msgstr "Programmeringsfeil: ulovleg handlingstype i process-event (%1)"
@@ -2225,7 +2243,7 @@ msgstr "Ukjend JACK-transporttilstand %1 i synk-tilbakekallet"
msgid "Cannot loop - no loop range defined"
msgstr "Greidde ikkje spela i lykkje - du har ikkje gjeve noko lykkjeområde"
#: session_transport.cc:727
#: session_transport.cc:728
msgid ""
"Seamless looping cannot be supported while %1 is using JACK transport.\n"
"Recommend changing the configured options"
@@ -2233,7 +2251,7 @@ msgstr ""
"Samanhengande lykkjespeling er ikkje støtta når %1 bruker JACK-transporten.\n"
"Me rår til at du endrar innstillingane."
#: session_transport.cc:1092
#: session_transport.cc:1094
msgid ""
"Global varispeed cannot be supported while %1 is connected to JACK transport "
"control"
@@ -2384,7 +2402,7 @@ msgstr "SndFileSource: @ %1 greidde ikkje lesa %2 i %3 (%4) (len = %5)"
msgid "attempt to write a non-writable audio file source (%1)"
msgstr "prøvde å skriva til ei ikkje-skrivbar lydkjeldefil (%1)"
#: sndfilesource.cc:396 utils.cc:497 utils.cc:521 utils.cc:535 utils.cc:554
#: sndfilesource.cc:396 utils.cc:507 utils.cc:531 utils.cc:545 utils.cc:564
msgid "programming error: %1 %2"
msgstr "programmeringsfeil: %1 %2"
@@ -2650,11 +2668,11 @@ msgstr "MIDI-klokke"
msgid "LTC"
msgstr "MTC"
#: utils.cc:589
#: utils.cc:599
msgid "programming error: unknown native header format: %1"
msgstr "programmeringsfeil: ukjent opphavleg hovudformat: \"%1\""
#: utils.cc:604
#: utils.cc:614
msgid "cannot open directory %1 (%2)"
msgstr "greier ikkje opna mappa %1 (%2)"
@@ -3267,13 +3285,6 @@ msgstr "greier ikkje opna mappa %1 (%2)"
#~ msgid "AUPlugin: render callback called illegally!"
#~ msgstr "AUPlugin: oppteiknings-tilbakekall påkalla ulovleg!"
#~ msgid ""
#~ "Saving AudioUnit settings is not supported in this build of Ardour. "
#~ "Consider paying for a newer version"
#~ msgstr ""
#~ "Du kan ikkje lagra AudioUnit-innstillingar i denne versjonen av Ardour. "
#~ "Du bør vurdera å betala for ein nyare verjson"
#~ msgid "Bad node sent to AUPlugin::set_state"
#~ msgstr "Feil punkt sendt til AUPlugin::set_state"
@@ -3297,13 +3308,6 @@ msgstr "greier ikkje opna mappa %1 (%2)"
#~ msgid "Saving plugin state to %1 failed"
#~ msgstr "Greidde ikkje lagra innstikkstatus til %1"
#~ msgid ""
#~ "Saving AudioUnit presets is not supported in this build of Ardour. "
#~ "Consider paying for a newer version"
#~ msgstr ""
#~ "Du kan ikkje lagra førehandsoppsett for AudioUnit i denne versjonen av "
#~ "Ardour. Du bør vurdera å betala for ein nyare verjson"
#~ msgid "Discovering AudioUnit plugins (could take some time ...)"
#~ msgstr "Finn AudioUnit-innstikk (dette kan ta litt tid...)"

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: libardour3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-06-11 08:49-0400\n"
"POT-Creation-Date: 2013-09-03 07:59-0400\n"
"PO-Revision-Date: 2008-04-10 10:51+0100\n"
"Last-Translator: Piotr Zaryk <pzaryk@gmail.com>\n"
"Language-Team: Polish <pl@li.org>\n"
@@ -28,52 +28,52 @@ msgstr ""
msgid "AudioDiskstream %1: there is no existing playlist to make a copy of!"
msgstr ""
#: audio_diskstream.cc:823 audio_diskstream.cc:833
#: audio_diskstream.cc:848 audio_diskstream.cc:858
msgid ""
"AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3"
msgstr ""
#: audio_diskstream.cc:989
#: audio_diskstream.cc:1014
msgid "AudioDiskstream %1: cannot read %2 from playlist at frame %3"
msgstr ""
#: audio_diskstream.cc:1358 audio_diskstream.cc:1375
#: audio_diskstream.cc:1383 audio_diskstream.cc:1400
msgid "AudioDiskstream %1: cannot write to disk"
msgstr ""
#: audio_diskstream.cc:1418
#: audio_diskstream.cc:1443
msgid "AudioDiskstream \"%1\": cannot flush captured data to disk!"
msgstr ""
#: audio_diskstream.cc:1512
#: audio_diskstream.cc:1537
msgid "%1: could not create region for complete audio file"
msgstr ""
#: audio_diskstream.cc:1546
#: audio_diskstream.cc:1571
msgid "AudioDiskstream: could not create region for captured audio!"
msgstr ""
#: audio_diskstream.cc:1654
#: audio_diskstream.cc:1679
msgid "programmer error: %1"
msgstr "błąd programisty: %1"
#: audio_diskstream.cc:1880
#: audio_diskstream.cc:1905
msgid "AudioDiskstream: channel %1 out of range"
msgstr ""
#: audio_diskstream.cc:1894 midi_diskstream.cc:1196
#: audio_diskstream.cc:1919 midi_diskstream.cc:1210
msgid "%1:%2 new capture file not initialized correctly"
msgstr ""
#: audio_diskstream.cc:2175
#: audio_diskstream.cc:2200
msgid "%1: cannot restore pending capture source file %2"
msgstr ""
#: audio_diskstream.cc:2197
#: audio_diskstream.cc:2222
msgid "%1: incorrect number of pending sources listed - ignoring them all"
msgstr ""
#: audio_diskstream.cc:2221
#: audio_diskstream.cc:2246
msgid "%1: cannot create whole-file region from pending capture sources"
msgstr ""
@@ -119,7 +119,7 @@ msgstr ""
#: audio_playlist_source.cc:171 audiosource.cc:913 file_source.cc:529
#: midi_playlist_source.cc:144 midi_playlist_source.cc:152
#: midi_playlist_source.cc:159 midi_source.cc:371 plugin_insert.cc:644
#: midi_playlist_source.cc:159 midi_source.cc:371 plugin_insert.cc:643
#: rb_effect.cc:332 session.cc:2465 session.cc:2498 session.cc:3643
#: session_handle.cc:87 sndfilesource.cc:121
msgid "programming error: %1"
@@ -195,47 +195,47 @@ msgstr ""
msgid "Connect session to engine"
msgstr ""
#: audioengine.cc:844
#: audioengine.cc:843
msgid ""
"a port with the name \"%1\" already exists: check for duplicated track/bus "
"names"
msgstr ""
#: audioengine.cc:846 session.cc:1698
#: audioengine.cc:845 session.cc:1698
msgid ""
"No more JACK ports are available. You will need to stop %1 and restart JACK "
"with more ports if you need this many tracks."
msgstr ""
#: audioengine.cc:849
#: audioengine.cc:848
msgid "AudioEngine: cannot register port \"%1\": %2"
msgstr ""
#: audioengine.cc:879
#: audioengine.cc:878
msgid "unable to create port: %1"
msgstr ""
#: audioengine.cc:933
#: audioengine.cc:932
msgid "connect called before engine was started"
msgstr ""
#: audioengine.cc:959
#: audioengine.cc:958
msgid "AudioEngine: cannot connect %1 (%2) to %3 (%4)"
msgstr ""
#: audioengine.cc:974 audioengine.cc:1005
#: audioengine.cc:973 audioengine.cc:1004
msgid "disconnect called before engine was started"
msgstr ""
#: audioengine.cc:1053
#: audioengine.cc:1052
msgid "get_port_by_name() called before engine was started"
msgstr ""
#: audioengine.cc:1105
#: audioengine.cc:1104
msgid "get_ports called before engine was started"
msgstr ""
#: audioengine.cc:1428
#: audioengine.cc:1427
msgid "failed to connect to JACK"
msgstr "nie udało się połączyć z JACK"
@@ -499,7 +499,7 @@ msgstr ""
msgid "Lossless compression"
msgstr ""
#: export_format_manager.cc:207 export_format_specification.cc:579
#: export_format_manager.cc:218 export_format_specification.cc:579
msgid "Session rate"
msgstr ""
@@ -532,7 +532,7 @@ msgstr ""
msgid "Rectangular"
msgstr ""
#: export_formats.cc:52 session.cc:4854 session.cc:4870
#: export_formats.cc:52 session.cc:4861 session.cc:4877
msgid "None"
msgstr ""
@@ -739,23 +739,23 @@ msgstr ""
msgid "unknown file type for session %1"
msgstr ""
#: globals.cc:204
#: globals.cc:205
msgid "Could not set system open files limit to \"unlimited\""
msgstr ""
#: globals.cc:206
#: globals.cc:207
msgid "Could not set system open files limit to %1"
msgstr ""
#: globals.cc:210
#: globals.cc:211
msgid "Your system is configured to limit %1 to only %2 open files"
msgstr ""
#: globals.cc:214
#: globals.cc:215
msgid "Could not get system open files limit (%1)"
msgstr ""
#: globals.cc:267
#: globals.cc:266
msgid "Loading configuration"
msgstr ""
@@ -907,53 +907,53 @@ msgstr ""
msgid "%d"
msgstr ""
#: ladspa_plugin.cc:87
#: ladspa_plugin.cc:88
msgid "LADSPA: module has no descriptor function."
msgstr ""
#: ladspa_plugin.cc:92
#: ladspa_plugin.cc:93
msgid "LADSPA: plugin has gone away since discovery!"
msgstr ""
#: ladspa_plugin.cc:99
#: ladspa_plugin.cc:100
msgid "LADSPA: \"%1\" cannot be used, since it cannot do inplace processing"
msgstr ""
#: ladspa_plugin.cc:296
#: ladspa_plugin.cc:297
msgid ""
"illegal parameter number used with plugin \"%1\". This may indicate a change "
"in the plugin design, and presets may be invalid"
msgstr ""
#: ladspa_plugin.cc:373 ladspa_plugin.cc:418
#: ladspa_plugin.cc:376 ladspa_plugin.cc:426
msgid "Bad node sent to LadspaPlugin::set_state"
msgstr ""
#: ladspa_plugin.cc:386 ladspa_plugin.cc:431
#: ladspa_plugin.cc:391 ladspa_plugin.cc:440
msgid "LADSPA: no ladspa port number"
msgstr ""
#: ladspa_plugin.cc:392 ladspa_plugin.cc:437
#: ladspa_plugin.cc:397 ladspa_plugin.cc:446
msgid "LADSPA: no ladspa port data"
msgstr ""
#: ladspa_plugin.cc:707
#: ladspa_plugin.cc:717
msgid "LADSPA: cannot load module from \"%1\""
msgstr ""
#: ladspa_plugin.cc:817
#: ladspa_plugin.cc:827
msgid "Could not locate HOME. Preset not removed."
msgstr ""
#: ladspa_plugin.cc:854 ladspa_plugin.cc:860
#: ladspa_plugin.cc:864 ladspa_plugin.cc:870
msgid "Could not create %1. Preset not saved. (%2)"
msgstr ""
#: ladspa_plugin.cc:867
#: ladspa_plugin.cc:877
msgid "Error saving presets file %1."
msgstr ""
#: ladspa_plugin.cc:905
#: ladspa_plugin.cc:915
msgid "Could not locate HOME. Preset not saved."
msgstr ""
@@ -993,7 +993,7 @@ msgstr ""
msgid "incorrect XML mode passed to Locations::set_state"
msgstr ""
#: location.cc:842 session.cc:4355 session_state.cc:1114
#: location.cc:842 session.cc:4362 session_state.cc:1114
msgid "session"
msgstr ""
@@ -1065,23 +1065,23 @@ msgstr ""
msgid "MidiDiskstream %1: there is no existing playlist to make a copy of!"
msgstr ""
#: midi_diskstream.cc:685
#: midi_diskstream.cc:699
msgid "MidiDiskstream %1: cannot read %2 from playlist at frame %3"
msgstr ""
#: midi_diskstream.cc:820
#: midi_diskstream.cc:834
msgid "MidiDiskstream %1: cannot write to disk"
msgstr ""
#: midi_diskstream.cc:854
#: midi_diskstream.cc:868
msgid "MidiDiskstream \"%1\": cannot flush captured data to disk!"
msgstr ""
#: midi_diskstream.cc:941
#: midi_diskstream.cc:955
msgid "%1: could not create region for complete midi file"
msgstr ""
#: midi_diskstream.cc:978
#: midi_diskstream.cc:992
msgid "MidiDiskstream: could not create region for captured midi!"
msgstr ""
@@ -1280,37 +1280,49 @@ msgstr ""
msgid "Could not construct playlist for PlaylistSource from session data!"
msgstr ""
#: plugin_insert.cc:599
#: plugin.cc:324
msgid ""
"Plugin presets are not supported in this build of %1. Consider paying for a "
"full version"
msgstr ""
#: plugin.cc:398
msgid ""
"Saving plugin settings is not supported in this build of %1. Consider paying "
"for the full version"
msgstr ""
#: plugin_insert.cc:598
msgid "programming error: "
msgstr ""
#: plugin_insert.cc:908
#: plugin_insert.cc:926
msgid "XML node describing plugin is missing the `type' field"
msgstr ""
#: plugin_insert.cc:923
#: plugin_insert.cc:941
msgid "unknown plugin type %1 in plugin insert state"
msgstr ""
#: plugin_insert.cc:951
#: plugin_insert.cc:969
msgid "Plugin has no unique ID field"
msgstr ""
#: plugin_insert.cc:960
#: plugin_insert.cc:978
msgid ""
"Found a reference to a plugin (\"%1\") that is unknown.\n"
"Perhaps it was removed or moved since it was last used."
msgstr ""
#: plugin_insert.cc:1076
#: plugin_insert.cc:1094
msgid "PluginInsert: Auto: no ladspa port number"
msgstr ""
#: plugin_insert.cc:1083
#: plugin_insert.cc:1101
msgid "PluginInsert: Auto: port id out of range"
msgstr ""
#: plugin_insert.cc:1119
#: plugin_insert.cc:1137
msgid "PluginInsert: automatable control %1 not found - ignored"
msgstr ""
@@ -1450,23 +1462,23 @@ msgstr ""
msgid "return %1"
msgstr ""
#: route.cc:1100 route.cc:2550
#: route.cc:1105 route.cc:2581
msgid "unknown Processor type \"%1\"; ignored"
msgstr ""
#: route.cc:1112
#: route.cc:1117
msgid "processor could not be created. Ignored."
msgstr ""
#: route.cc:1983 route.cc:2203
#: route.cc:2007 route.cc:2234
msgid "Bad node sent to Route::set_state() [%1]"
msgstr ""
#: route.cc:2042
#: route.cc:2067
msgid "Pannable state found for route (%1) without a panner!"
msgstr ""
#: route.cc:2106 route.cc:2110 route.cc:2317 route.cc:2321
#: route.cc:2137 route.cc:2141 route.cc:2348 route.cc:2352
msgid "badly formed order key string in state file! [%1] ... ignored."
msgstr ""
@@ -1720,17 +1732,17 @@ msgstr ""
msgid "Export ended unexpectedly: %1"
msgstr ""
#: session_ltc.cc:220
#: session_ltc.cc:222
msgid ""
"LTC encoder: invalid framerate - LTC encoding is disabled for the remainder "
"of this session."
msgstr ""
#: session_midi.cc:427
#: session_midi.cc:428
msgid "Session: could not send full MIDI time code"
msgstr ""
#: session_midi.cc:519
#: session_midi.cc:520
msgid "Session: cannot send quarter-frame MTC message (%1)"
msgstr ""
@@ -1738,11 +1750,11 @@ msgstr ""
msgid "Session: cannot create Playlist from XML description."
msgstr ""
#: session_process.cc:135
#: session_process.cc:133
msgid "Session: error in no roll for %1"
msgstr ""
#: session_process.cc:1160
#: session_process.cc:1158
msgid "Programming error: illegal event type in process_event (%1)"
msgstr ""
@@ -2110,13 +2122,13 @@ msgstr ""
msgid "Cannot loop - no loop range defined"
msgstr ""
#: session_transport.cc:727
#: session_transport.cc:728
msgid ""
"Seamless looping cannot be supported while %1 is using JACK transport.\n"
"Recommend changing the configured options"
msgstr ""
#: session_transport.cc:1092
#: session_transport.cc:1094
msgid ""
"Global varispeed cannot be supported while %1 is connected to JACK transport "
"control"
@@ -2262,7 +2274,7 @@ msgstr ""
msgid "attempt to write a non-writable audio file source (%1)"
msgstr ""
#: sndfilesource.cc:396 utils.cc:497 utils.cc:521 utils.cc:535 utils.cc:554
#: sndfilesource.cc:396 utils.cc:507 utils.cc:531 utils.cc:545 utils.cc:564
msgid "programming error: %1 %2"
msgstr ""
@@ -2512,11 +2524,11 @@ msgstr ""
msgid "LTC"
msgstr "MTC"
#: utils.cc:589
#: utils.cc:599
msgid "programming error: unknown native header format: %1"
msgstr ""
#: utils.cc:604
#: utils.cc:614
#, fuzzy
msgid "cannot open directory %1 (%2)"
msgstr "nie można otworzyć pliku dźwiękowego metronomu %1 (%2)"

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: libardour 3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-06-14 03:23+0400\n"
"POT-Creation-Date: 2013-09-03 07:59-0400\n"
"PO-Revision-Date: 2013-06-14 02:14+0300\n"
"Last-Translator: Александр Прокудин <alexandre.prokoudine@gmail.com>\n"
"Language-Team: русский <>\n"
@@ -32,52 +32,52 @@ msgstr ""
msgid "AudioDiskstream %1: there is no existing playlist to make a copy of!"
msgstr ""
#: audio_diskstream.cc:823 audio_diskstream.cc:833
#: audio_diskstream.cc:848 audio_diskstream.cc:858
msgid ""
"AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3"
msgstr ""
#: audio_diskstream.cc:989
#: audio_diskstream.cc:1014
msgid "AudioDiskstream %1: cannot read %2 from playlist at frame %3"
msgstr ""
#: audio_diskstream.cc:1358 audio_diskstream.cc:1375
#: audio_diskstream.cc:1383 audio_diskstream.cc:1400
msgid "AudioDiskstream %1: cannot write to disk"
msgstr ""
#: audio_diskstream.cc:1418
#: audio_diskstream.cc:1443
msgid "AudioDiskstream \"%1\": cannot flush captured data to disk!"
msgstr ""
#: audio_diskstream.cc:1512
#: audio_diskstream.cc:1537
msgid "%1: could not create region for complete audio file"
msgstr ""
#: audio_diskstream.cc:1546
#: audio_diskstream.cc:1571
msgid "AudioDiskstream: could not create region for captured audio!"
msgstr ""
#: audio_diskstream.cc:1654
#: audio_diskstream.cc:1679
msgid "programmer error: %1"
msgstr ""
#: audio_diskstream.cc:1880
#: audio_diskstream.cc:1905
msgid "AudioDiskstream: channel %1 out of range"
msgstr ""
#: audio_diskstream.cc:1894 midi_diskstream.cc:1196
#: audio_diskstream.cc:1919 midi_diskstream.cc:1210
msgid "%1:%2 new capture file not initialized correctly"
msgstr ""
#: audio_diskstream.cc:2175
#: audio_diskstream.cc:2200
msgid "%1: cannot restore pending capture source file %2"
msgstr ""
#: audio_diskstream.cc:2197
#: audio_diskstream.cc:2222
msgid "%1: incorrect number of pending sources listed - ignoring them all"
msgstr ""
#: audio_diskstream.cc:2221
#: audio_diskstream.cc:2246
msgid "%1: cannot create whole-file region from pending capture sources"
msgstr ""
@@ -123,7 +123,7 @@ msgstr ""
#: audio_playlist_source.cc:171 audiosource.cc:913 file_source.cc:529
#: midi_playlist_source.cc:144 midi_playlist_source.cc:152
#: midi_playlist_source.cc:159 midi_source.cc:371 plugin_insert.cc:644
#: midi_playlist_source.cc:159 midi_source.cc:371 plugin_insert.cc:643
#: rb_effect.cc:332 session.cc:2465 session.cc:2498 session.cc:3643
#: session_handle.cc:87 sndfilesource.cc:121
msgid "programming error: %1"
@@ -203,47 +203,47 @@ msgstr ""
msgid "Connect session to engine"
msgstr ""
#: audioengine.cc:844
#: audioengine.cc:843
msgid ""
"a port with the name \"%1\" already exists: check for duplicated track/bus "
"names"
msgstr ""
#: audioengine.cc:846 session.cc:1698
#: audioengine.cc:845 session.cc:1698
msgid ""
"No more JACK ports are available. You will need to stop %1 and restart JACK "
"with more ports if you need this many tracks."
msgstr ""
#: audioengine.cc:849
#: audioengine.cc:848
msgid "AudioEngine: cannot register port \"%1\": %2"
msgstr "AudioEngine: cannot register port \"%1\": %2"
#: audioengine.cc:879
#: audioengine.cc:878
msgid "unable to create port: %1"
msgstr ""
#: audioengine.cc:933
#: audioengine.cc:932
msgid "connect called before engine was started"
msgstr ""
#: audioengine.cc:959
#: audioengine.cc:958
msgid "AudioEngine: cannot connect %1 (%2) to %3 (%4)"
msgstr ""
#: audioengine.cc:974 audioengine.cc:1005
#: audioengine.cc:973 audioengine.cc:1004
msgid "disconnect called before engine was started"
msgstr ""
#: audioengine.cc:1053
#: audioengine.cc:1052
msgid "get_port_by_name() called before engine was started"
msgstr ""
#: audioengine.cc:1105
#: audioengine.cc:1104
msgid "get_ports called before engine was started"
msgstr ""
#: audioengine.cc:1428
#: audioengine.cc:1427
msgid "failed to connect to JACK"
msgstr ""
@@ -509,7 +509,7 @@ msgstr "Сжатие с потерями"
msgid "Lossless compression"
msgstr "Сжатие без потерь"
#: export_format_manager.cc:207 export_format_specification.cc:579
#: export_format_manager.cc:218 export_format_specification.cc:579
msgid "Session rate"
msgstr "Частота сеанса"
@@ -541,7 +541,7 @@ msgstr "Треугольное"
msgid "Rectangular"
msgstr "Прямоугольное"
#: export_formats.cc:52 session.cc:4854 session.cc:4870
#: export_formats.cc:52 session.cc:4861 session.cc:4877
msgid "None"
msgstr "Нет"
@@ -746,23 +746,23 @@ msgstr ""
msgid "unknown file type for session %1"
msgstr ""
#: globals.cc:204
#: globals.cc:205
msgid "Could not set system open files limit to \"unlimited\""
msgstr ""
#: globals.cc:206
#: globals.cc:207
msgid "Could not set system open files limit to %1"
msgstr ""
#: globals.cc:210
#: globals.cc:211
msgid "Your system is configured to limit %1 to only %2 open files"
msgstr ""
#: globals.cc:214
#: globals.cc:215
msgid "Could not get system open files limit (%1)"
msgstr ""
#: globals.cc:267
#: globals.cc:266
msgid "Loading configuration"
msgstr ""
@@ -914,53 +914,53 @@ msgstr ""
msgid "%d"
msgstr ""
#: ladspa_plugin.cc:87
#: ladspa_plugin.cc:88
msgid "LADSPA: module has no descriptor function."
msgstr ""
#: ladspa_plugin.cc:92
#: ladspa_plugin.cc:93
msgid "LADSPA: plugin has gone away since discovery!"
msgstr ""
#: ladspa_plugin.cc:99
#: ladspa_plugin.cc:100
msgid "LADSPA: \"%1\" cannot be used, since it cannot do inplace processing"
msgstr ""
#: ladspa_plugin.cc:296
#: ladspa_plugin.cc:297
msgid ""
"illegal parameter number used with plugin \"%1\". This may indicate a change "
"in the plugin design, and presets may be invalid"
msgstr ""
#: ladspa_plugin.cc:373 ladspa_plugin.cc:418
#: ladspa_plugin.cc:376 ladspa_plugin.cc:426
msgid "Bad node sent to LadspaPlugin::set_state"
msgstr ""
#: ladspa_plugin.cc:386 ladspa_plugin.cc:431
#: ladspa_plugin.cc:391 ladspa_plugin.cc:440
msgid "LADSPA: no ladspa port number"
msgstr ""
#: ladspa_plugin.cc:392 ladspa_plugin.cc:437
#: ladspa_plugin.cc:397 ladspa_plugin.cc:446
msgid "LADSPA: no ladspa port data"
msgstr ""
#: ladspa_plugin.cc:707
#: ladspa_plugin.cc:717
msgid "LADSPA: cannot load module from \"%1\""
msgstr ""
#: ladspa_plugin.cc:817
#: ladspa_plugin.cc:827
msgid "Could not locate HOME. Preset not removed."
msgstr ""
#: ladspa_plugin.cc:854 ladspa_plugin.cc:860
#: ladspa_plugin.cc:864 ladspa_plugin.cc:870
msgid "Could not create %1. Preset not saved. (%2)"
msgstr ""
#: ladspa_plugin.cc:867
#: ladspa_plugin.cc:877
msgid "Error saving presets file %1."
msgstr ""
#: ladspa_plugin.cc:905
#: ladspa_plugin.cc:915
msgid "Could not locate HOME. Preset not saved."
msgstr ""
@@ -1000,7 +1000,7 @@ msgstr ""
msgid "incorrect XML mode passed to Locations::set_state"
msgstr ""
#: location.cc:842 session.cc:4355 session_state.cc:1114
#: location.cc:842 session.cc:4362 session_state.cc:1114
msgid "session"
msgstr ""
@@ -1076,23 +1076,23 @@ msgstr ""
msgid "MidiDiskstream %1: there is no existing playlist to make a copy of!"
msgstr ""
#: midi_diskstream.cc:685
#: midi_diskstream.cc:699
msgid "MidiDiskstream %1: cannot read %2 from playlist at frame %3"
msgstr ""
#: midi_diskstream.cc:820
#: midi_diskstream.cc:834
msgid "MidiDiskstream %1: cannot write to disk"
msgstr ""
#: midi_diskstream.cc:854
#: midi_diskstream.cc:868
msgid "MidiDiskstream \"%1\": cannot flush captured data to disk!"
msgstr ""
#: midi_diskstream.cc:941
#: midi_diskstream.cc:955
msgid "%1: could not create region for complete midi file"
msgstr ""
#: midi_diskstream.cc:978
#: midi_diskstream.cc:992
msgid "MidiDiskstream: could not create region for captured midi!"
msgstr ""
@@ -1286,37 +1286,49 @@ msgstr ""
msgid "Could not construct playlist for PlaylistSource from session data!"
msgstr ""
#: plugin_insert.cc:599
#: plugin.cc:324
msgid ""
"Plugin presets are not supported in this build of %1. Consider paying for a "
"full version"
msgstr ""
#: plugin.cc:398
msgid ""
"Saving plugin settings is not supported in this build of %1. Consider paying "
"for the full version"
msgstr ""
#: plugin_insert.cc:598
msgid "programming error: "
msgstr "ошибка программы: "
#: plugin_insert.cc:908
#: plugin_insert.cc:926
msgid "XML node describing plugin is missing the `type' field"
msgstr ""
#: plugin_insert.cc:923
#: plugin_insert.cc:941
msgid "unknown plugin type %1 in plugin insert state"
msgstr ""
#: plugin_insert.cc:951
#: plugin_insert.cc:969
msgid "Plugin has no unique ID field"
msgstr ""
#: plugin_insert.cc:960
#: plugin_insert.cc:978
msgid ""
"Found a reference to a plugin (\"%1\") that is unknown.\n"
"Perhaps it was removed or moved since it was last used."
msgstr ""
#: plugin_insert.cc:1076
#: plugin_insert.cc:1094
msgid "PluginInsert: Auto: no ladspa port number"
msgstr ""
#: plugin_insert.cc:1083
#: plugin_insert.cc:1101
msgid "PluginInsert: Auto: port id out of range"
msgstr ""
#: plugin_insert.cc:1119
#: plugin_insert.cc:1137
msgid "PluginInsert: automatable control %1 not found - ignored"
msgstr ""
@@ -1459,23 +1471,23 @@ msgstr ""
msgid "return %1"
msgstr ""
#: route.cc:1100 route.cc:2550
#: route.cc:1105 route.cc:2581
msgid "unknown Processor type \"%1\"; ignored"
msgstr ""
#: route.cc:1112
#: route.cc:1117
msgid "processor could not be created. Ignored."
msgstr ""
#: route.cc:1983 route.cc:2203
#: route.cc:2007 route.cc:2234
msgid "Bad node sent to Route::set_state() [%1]"
msgstr ""
#: route.cc:2042
#: route.cc:2067
msgid "Pannable state found for route (%1) without a panner!"
msgstr ""
#: route.cc:2106 route.cc:2110 route.cc:2317 route.cc:2321
#: route.cc:2137 route.cc:2141 route.cc:2348 route.cc:2352
msgid "badly formed order key string in state file! [%1] ... ignored."
msgstr ""
@@ -1728,17 +1740,17 @@ msgstr ""
msgid "Export ended unexpectedly: %1"
msgstr ""
#: session_ltc.cc:220
#: session_ltc.cc:222
msgid ""
"LTC encoder: invalid framerate - LTC encoding is disabled for the remainder "
"of this session."
msgstr ""
#: session_midi.cc:427
#: session_midi.cc:428
msgid "Session: could not send full MIDI time code"
msgstr ""
#: session_midi.cc:519
#: session_midi.cc:520
msgid "Session: cannot send quarter-frame MTC message (%1)"
msgstr ""
@@ -1746,11 +1758,11 @@ msgstr ""
msgid "Session: cannot create Playlist from XML description."
msgstr ""
#: session_process.cc:135
#: session_process.cc:133
msgid "Session: error in no roll for %1"
msgstr ""
#: session_process.cc:1160
#: session_process.cc:1158
msgid "Programming error: illegal event type in process_event (%1)"
msgstr ""
@@ -2103,13 +2115,13 @@ msgstr ""
msgid "Cannot loop - no loop range defined"
msgstr ""
#: session_transport.cc:727
#: session_transport.cc:728
msgid ""
"Seamless looping cannot be supported while %1 is using JACK transport.\n"
"Recommend changing the configured options"
msgstr ""
#: session_transport.cc:1092
#: session_transport.cc:1094
msgid ""
"Global varispeed cannot be supported while %1 is connected to JACK transport "
"control"
@@ -2253,7 +2265,7 @@ msgstr ""
msgid "attempt to write a non-writable audio file source (%1)"
msgstr ""
#: sndfilesource.cc:396 utils.cc:497 utils.cc:521 utils.cc:535 utils.cc:554
#: sndfilesource.cc:396 utils.cc:507 utils.cc:531 utils.cc:545 utils.cc:564
msgid "programming error: %1 %2"
msgstr "programming error: %1 %2"
@@ -2499,11 +2511,11 @@ msgstr ""
msgid "LTC"
msgstr "LTC"
#: utils.cc:589
#: utils.cc:599
msgid "programming error: unknown native header format: %1"
msgstr "programming error: unknown native header format: %1"
#: utils.cc:604
#: utils.cc:614
msgid "cannot open directory %1 (%2)"
msgstr "cannot open directory %1 (%2)"

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: ardour\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-06-11 08:49-0400\n"
"POT-Creation-Date: 2013-09-03 07:59-0400\n"
"PO-Revision-Date: 2006-10-03 01:09+GMT+1\n"
"Last-Translator: Petter Sundlöf <petter.sundlof@findus.dhs.org>\n"
"Language-Team: Swedish <sv@li.org>\n"
@@ -28,52 +28,52 @@ msgstr ""
msgid "AudioDiskstream %1: there is no existing playlist to make a copy of!"
msgstr ""
#: audio_diskstream.cc:823 audio_diskstream.cc:833
#: audio_diskstream.cc:848 audio_diskstream.cc:858
msgid ""
"AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3"
msgstr ""
#: audio_diskstream.cc:989
#: audio_diskstream.cc:1014
msgid "AudioDiskstream %1: cannot read %2 from playlist at frame %3"
msgstr ""
#: audio_diskstream.cc:1358 audio_diskstream.cc:1375
#: audio_diskstream.cc:1383 audio_diskstream.cc:1400
msgid "AudioDiskstream %1: cannot write to disk"
msgstr ""
#: audio_diskstream.cc:1418
#: audio_diskstream.cc:1443
msgid "AudioDiskstream \"%1\": cannot flush captured data to disk!"
msgstr ""
#: audio_diskstream.cc:1512
#: audio_diskstream.cc:1537
msgid "%1: could not create region for complete audio file"
msgstr ""
#: audio_diskstream.cc:1546
#: audio_diskstream.cc:1571
msgid "AudioDiskstream: could not create region for captured audio!"
msgstr ""
#: audio_diskstream.cc:1654
#: audio_diskstream.cc:1679
msgid "programmer error: %1"
msgstr ""
#: audio_diskstream.cc:1880
#: audio_diskstream.cc:1905
msgid "AudioDiskstream: channel %1 out of range"
msgstr ""
#: audio_diskstream.cc:1894 midi_diskstream.cc:1196
#: audio_diskstream.cc:1919 midi_diskstream.cc:1210
msgid "%1:%2 new capture file not initialized correctly"
msgstr ""
#: audio_diskstream.cc:2175
#: audio_diskstream.cc:2200
msgid "%1: cannot restore pending capture source file %2"
msgstr ""
#: audio_diskstream.cc:2197
#: audio_diskstream.cc:2222
msgid "%1: incorrect number of pending sources listed - ignoring them all"
msgstr ""
#: audio_diskstream.cc:2221
#: audio_diskstream.cc:2246
msgid "%1: cannot create whole-file region from pending capture sources"
msgstr ""
@@ -119,7 +119,7 @@ msgstr ""
#: audio_playlist_source.cc:171 audiosource.cc:913 file_source.cc:529
#: midi_playlist_source.cc:144 midi_playlist_source.cc:152
#: midi_playlist_source.cc:159 midi_source.cc:371 plugin_insert.cc:644
#: midi_playlist_source.cc:159 midi_source.cc:371 plugin_insert.cc:643
#: rb_effect.cc:332 session.cc:2465 session.cc:2498 session.cc:3643
#: session_handle.cc:87 sndfilesource.cc:121
msgid "programming error: %1"
@@ -198,48 +198,48 @@ msgstr ""
msgid "Connect session to engine"
msgstr "Ansluter till ljudmotorn"
#: audioengine.cc:844
#: audioengine.cc:843
msgid ""
"a port with the name \"%1\" already exists: check for duplicated track/bus "
"names"
msgstr ""
#: audioengine.cc:846 session.cc:1698
#: audioengine.cc:845 session.cc:1698
msgid ""
"No more JACK ports are available. You will need to stop %1 and restart JACK "
"with more ports if you need this many tracks."
msgstr ""
#: audioengine.cc:849
#: audioengine.cc:848
#, fuzzy
msgid "AudioEngine: cannot register port \"%1\": %2"
msgstr "AudioEngine: kan inte ansluta %1 (%2) till %3 (%4)"
#: audioengine.cc:879
#: audioengine.cc:878
msgid "unable to create port: %1"
msgstr ""
#: audioengine.cc:933
#: audioengine.cc:932
msgid "connect called before engine was started"
msgstr ""
#: audioengine.cc:959
#: audioengine.cc:958
msgid "AudioEngine: cannot connect %1 (%2) to %3 (%4)"
msgstr "AudioEngine: kan inte ansluta %1 (%2) till %3 (%4)"
#: audioengine.cc:974 audioengine.cc:1005
#: audioengine.cc:973 audioengine.cc:1004
msgid "disconnect called before engine was started"
msgstr ""
#: audioengine.cc:1053
#: audioengine.cc:1052
msgid "get_port_by_name() called before engine was started"
msgstr ""
#: audioengine.cc:1105
#: audioengine.cc:1104
msgid "get_ports called before engine was started"
msgstr ""
#: audioengine.cc:1428
#: audioengine.cc:1427
msgid "failed to connect to JACK"
msgstr ""
@@ -505,7 +505,7 @@ msgstr ""
msgid "Lossless compression"
msgstr ""
#: export_format_manager.cc:207 export_format_specification.cc:579
#: export_format_manager.cc:218 export_format_specification.cc:579
msgid "Session rate"
msgstr ""
@@ -537,7 +537,7 @@ msgstr ""
msgid "Rectangular"
msgstr ""
#: export_formats.cc:52 session.cc:4854 session.cc:4870
#: export_formats.cc:52 session.cc:4861 session.cc:4877
msgid "None"
msgstr ""
@@ -744,23 +744,23 @@ msgstr ""
msgid "unknown file type for session %1"
msgstr ""
#: globals.cc:204
#: globals.cc:205
msgid "Could not set system open files limit to \"unlimited\""
msgstr ""
#: globals.cc:206
#: globals.cc:207
msgid "Could not set system open files limit to %1"
msgstr ""
#: globals.cc:210
#: globals.cc:211
msgid "Your system is configured to limit %1 to only %2 open files"
msgstr ""
#: globals.cc:214
#: globals.cc:215
msgid "Could not get system open files limit (%1)"
msgstr ""
#: globals.cc:267
#: globals.cc:266
msgid "Loading configuration"
msgstr ""
@@ -915,53 +915,53 @@ msgstr ""
msgid "%d"
msgstr ""
#: ladspa_plugin.cc:87
#: ladspa_plugin.cc:88
msgid "LADSPA: module has no descriptor function."
msgstr ""
#: ladspa_plugin.cc:92
#: ladspa_plugin.cc:93
msgid "LADSPA: plugin has gone away since discovery!"
msgstr ""
#: ladspa_plugin.cc:99
#: ladspa_plugin.cc:100
msgid "LADSPA: \"%1\" cannot be used, since it cannot do inplace processing"
msgstr ""
#: ladspa_plugin.cc:296
#: ladspa_plugin.cc:297
msgid ""
"illegal parameter number used with plugin \"%1\". This may indicate a change "
"in the plugin design, and presets may be invalid"
msgstr ""
#: ladspa_plugin.cc:373 ladspa_plugin.cc:418
#: ladspa_plugin.cc:376 ladspa_plugin.cc:426
msgid "Bad node sent to LadspaPlugin::set_state"
msgstr ""
#: ladspa_plugin.cc:386 ladspa_plugin.cc:431
#: ladspa_plugin.cc:391 ladspa_plugin.cc:440
msgid "LADSPA: no ladspa port number"
msgstr ""
#: ladspa_plugin.cc:392 ladspa_plugin.cc:437
#: ladspa_plugin.cc:397 ladspa_plugin.cc:446
msgid "LADSPA: no ladspa port data"
msgstr ""
#: ladspa_plugin.cc:707
#: ladspa_plugin.cc:717
msgid "LADSPA: cannot load module from \"%1\""
msgstr ""
#: ladspa_plugin.cc:817
#: ladspa_plugin.cc:827
msgid "Could not locate HOME. Preset not removed."
msgstr ""
#: ladspa_plugin.cc:854 ladspa_plugin.cc:860
#: ladspa_plugin.cc:864 ladspa_plugin.cc:870
msgid "Could not create %1. Preset not saved. (%2)"
msgstr ""
#: ladspa_plugin.cc:867
#: ladspa_plugin.cc:877
msgid "Error saving presets file %1."
msgstr ""
#: ladspa_plugin.cc:905
#: ladspa_plugin.cc:915
msgid "Could not locate HOME. Preset not saved."
msgstr ""
@@ -1001,7 +1001,7 @@ msgstr ""
msgid "incorrect XML mode passed to Locations::set_state"
msgstr ""
#: location.cc:842 session.cc:4355 session_state.cc:1114
#: location.cc:842 session.cc:4362 session_state.cc:1114
msgid "session"
msgstr ""
@@ -1073,23 +1073,23 @@ msgstr ""
msgid "MidiDiskstream %1: there is no existing playlist to make a copy of!"
msgstr ""
#: midi_diskstream.cc:685
#: midi_diskstream.cc:699
msgid "MidiDiskstream %1: cannot read %2 from playlist at frame %3"
msgstr ""
#: midi_diskstream.cc:820
#: midi_diskstream.cc:834
msgid "MidiDiskstream %1: cannot write to disk"
msgstr ""
#: midi_diskstream.cc:854
#: midi_diskstream.cc:868
msgid "MidiDiskstream \"%1\": cannot flush captured data to disk!"
msgstr ""
#: midi_diskstream.cc:941
#: midi_diskstream.cc:955
msgid "%1: could not create region for complete midi file"
msgstr ""
#: midi_diskstream.cc:978
#: midi_diskstream.cc:992
msgid "MidiDiskstream: could not create region for captured midi!"
msgstr ""
@@ -1283,37 +1283,49 @@ msgstr ""
msgid "Could not construct playlist for PlaylistSource from session data!"
msgstr ""
#: plugin_insert.cc:599
#: plugin.cc:324
msgid ""
"Plugin presets are not supported in this build of %1. Consider paying for a "
"full version"
msgstr ""
#: plugin.cc:398
msgid ""
"Saving plugin settings is not supported in this build of %1. Consider paying "
"for the full version"
msgstr ""
#: plugin_insert.cc:598
msgid "programming error: "
msgstr ""
#: plugin_insert.cc:908
#: plugin_insert.cc:926
msgid "XML node describing plugin is missing the `type' field"
msgstr ""
#: plugin_insert.cc:923
#: plugin_insert.cc:941
msgid "unknown plugin type %1 in plugin insert state"
msgstr ""
#: plugin_insert.cc:951
#: plugin_insert.cc:969
msgid "Plugin has no unique ID field"
msgstr ""
#: plugin_insert.cc:960
#: plugin_insert.cc:978
msgid ""
"Found a reference to a plugin (\"%1\") that is unknown.\n"
"Perhaps it was removed or moved since it was last used."
msgstr ""
#: plugin_insert.cc:1076
#: plugin_insert.cc:1094
msgid "PluginInsert: Auto: no ladspa port number"
msgstr ""
#: plugin_insert.cc:1083
#: plugin_insert.cc:1101
msgid "PluginInsert: Auto: port id out of range"
msgstr ""
#: plugin_insert.cc:1119
#: plugin_insert.cc:1137
msgid "PluginInsert: automatable control %1 not found - ignored"
msgstr ""
@@ -1453,23 +1465,23 @@ msgstr ""
msgid "return %1"
msgstr ""
#: route.cc:1100 route.cc:2550
#: route.cc:1105 route.cc:2581
msgid "unknown Processor type \"%1\"; ignored"
msgstr ""
#: route.cc:1112
#: route.cc:1117
msgid "processor could not be created. Ignored."
msgstr ""
#: route.cc:1983 route.cc:2203
#: route.cc:2007 route.cc:2234
msgid "Bad node sent to Route::set_state() [%1]"
msgstr ""
#: route.cc:2042
#: route.cc:2067
msgid "Pannable state found for route (%1) without a panner!"
msgstr ""
#: route.cc:2106 route.cc:2110 route.cc:2317 route.cc:2321
#: route.cc:2137 route.cc:2141 route.cc:2348 route.cc:2352
msgid "badly formed order key string in state file! [%1] ... ignored."
msgstr ""
@@ -1722,17 +1734,17 @@ msgstr ""
msgid "Export ended unexpectedly: %1"
msgstr ""
#: session_ltc.cc:220
#: session_ltc.cc:222
msgid ""
"LTC encoder: invalid framerate - LTC encoding is disabled for the remainder "
"of this session."
msgstr ""
#: session_midi.cc:427
#: session_midi.cc:428
msgid "Session: could not send full MIDI time code"
msgstr ""
#: session_midi.cc:519
#: session_midi.cc:520
msgid "Session: cannot send quarter-frame MTC message (%1)"
msgstr ""
@@ -1740,11 +1752,11 @@ msgstr ""
msgid "Session: cannot create Playlist from XML description."
msgstr ""
#: session_process.cc:135
#: session_process.cc:133
msgid "Session: error in no roll for %1"
msgstr ""
#: session_process.cc:1160
#: session_process.cc:1158
msgid "Programming error: illegal event type in process_event (%1)"
msgstr ""
@@ -2095,13 +2107,13 @@ msgstr ""
msgid "Cannot loop - no loop range defined"
msgstr ""
#: session_transport.cc:727
#: session_transport.cc:728
msgid ""
"Seamless looping cannot be supported while %1 is using JACK transport.\n"
"Recommend changing the configured options"
msgstr ""
#: session_transport.cc:1092
#: session_transport.cc:1094
msgid ""
"Global varispeed cannot be supported while %1 is connected to JACK transport "
"control"
@@ -2244,7 +2256,7 @@ msgstr ""
msgid "attempt to write a non-writable audio file source (%1)"
msgstr ""
#: sndfilesource.cc:396 utils.cc:497 utils.cc:521 utils.cc:535 utils.cc:554
#: sndfilesource.cc:396 utils.cc:507 utils.cc:531 utils.cc:545 utils.cc:564
msgid "programming error: %1 %2"
msgstr ""
@@ -2490,11 +2502,11 @@ msgstr ""
msgid "LTC"
msgstr ""
#: utils.cc:589
#: utils.cc:599
msgid "programming error: unknown native header format: %1"
msgstr ""
#: utils.cc:604
#: utils.cc:614
msgid "cannot open directory %1 (%2)"
msgstr ""

View File

@@ -2,7 +2,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Ardour 3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-06-11 08:49-0400\n"
"POT-Creation-Date: 2013-09-03 07:59-0400\n"
"PO-Revision-Date: 2012-08-26 13:43+0800\n"
"Last-Translator: Rui-huai Zhang <zrhzrh>\n"
"Language-Team: zrhzrh <zrhzrh@mail.ustc.edu.cn>\n"
@@ -29,52 +29,52 @@ msgstr ""
msgid "AudioDiskstream %1: there is no existing playlist to make a copy of!"
msgstr ""
#: audio_diskstream.cc:823 audio_diskstream.cc:833
#: audio_diskstream.cc:848 audio_diskstream.cc:858
msgid ""
"AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3"
msgstr ""
#: audio_diskstream.cc:989
#: audio_diskstream.cc:1014
msgid "AudioDiskstream %1: cannot read %2 from playlist at frame %3"
msgstr ""
#: audio_diskstream.cc:1358 audio_diskstream.cc:1375
#: audio_diskstream.cc:1383 audio_diskstream.cc:1400
msgid "AudioDiskstream %1: cannot write to disk"
msgstr "音频磁盘流 %1: 无法吸入到硬盘"
#: audio_diskstream.cc:1418
#: audio_diskstream.cc:1443
msgid "AudioDiskstream \"%1\": cannot flush captured data to disk!"
msgstr ""
#: audio_diskstream.cc:1512
#: audio_diskstream.cc:1537
msgid "%1: could not create region for complete audio file"
msgstr ""
#: audio_diskstream.cc:1546
#: audio_diskstream.cc:1571
msgid "AudioDiskstream: could not create region for captured audio!"
msgstr ""
#: audio_diskstream.cc:1654
#: audio_diskstream.cc:1679
msgid "programmer error: %1"
msgstr "程序错误: %1"
#: audio_diskstream.cc:1880
#: audio_diskstream.cc:1905
msgid "AudioDiskstream: channel %1 out of range"
msgstr "音频磁盘流: 声道 %1 超出范围"
#: audio_diskstream.cc:1894 midi_diskstream.cc:1196
#: audio_diskstream.cc:1919 midi_diskstream.cc:1210
msgid "%1:%2 new capture file not initialized correctly"
msgstr ""
#: audio_diskstream.cc:2175
#: audio_diskstream.cc:2200
msgid "%1: cannot restore pending capture source file %2"
msgstr ""
#: audio_diskstream.cc:2197
#: audio_diskstream.cc:2222
msgid "%1: incorrect number of pending sources listed - ignoring them all"
msgstr ""
#: audio_diskstream.cc:2221
#: audio_diskstream.cc:2246
msgid "%1: cannot create whole-file region from pending capture sources"
msgstr ""
@@ -120,7 +120,7 @@ msgstr "音频播放列表(未使用)"
#: audio_playlist_source.cc:171 audiosource.cc:913 file_source.cc:529
#: midi_playlist_source.cc:144 midi_playlist_source.cc:152
#: midi_playlist_source.cc:159 midi_source.cc:371 plugin_insert.cc:644
#: midi_playlist_source.cc:159 midi_source.cc:371 plugin_insert.cc:643
#: rb_effect.cc:332 session.cc:2465 session.cc:2498 session.cc:3643
#: session_handle.cc:87 sndfilesource.cc:121
msgid "programming error: %1"
@@ -200,47 +200,47 @@ msgstr ""
msgid "Connect session to engine"
msgstr "连接会话到引擎"
#: audioengine.cc:844
#: audioengine.cc:843
msgid ""
"a port with the name \"%1\" already exists: check for duplicated track/bus "
"names"
msgstr ""
#: audioengine.cc:846 session.cc:1698
#: audioengine.cc:845 session.cc:1698
msgid ""
"No more JACK ports are available. You will need to stop %1 and restart JACK "
"with more ports if you need this many tracks."
msgstr ""
#: audioengine.cc:849
#: audioengine.cc:848
msgid "AudioEngine: cannot register port \"%1\": %2"
msgstr ""
#: audioengine.cc:879
#: audioengine.cc:878
msgid "unable to create port: %1"
msgstr "无法创建端口: %1"
#: audioengine.cc:933
#: audioengine.cc:932
msgid "connect called before engine was started"
msgstr ""
#: audioengine.cc:959
#: audioengine.cc:958
msgid "AudioEngine: cannot connect %1 (%2) to %3 (%4)"
msgstr "音频引擎: 无法连接 %1 (%2) 到 %3 (%4)"
#: audioengine.cc:974 audioengine.cc:1005
#: audioengine.cc:973 audioengine.cc:1004
msgid "disconnect called before engine was started"
msgstr ""
#: audioengine.cc:1053
#: audioengine.cc:1052
msgid "get_port_by_name() called before engine was started"
msgstr ""
#: audioengine.cc:1105
#: audioengine.cc:1104
msgid "get_ports called before engine was started"
msgstr ""
#: audioengine.cc:1428
#: audioengine.cc:1427
msgid "failed to connect to JACK"
msgstr "连接JACK失败"
@@ -505,7 +505,7 @@ msgstr "有损压缩"
msgid "Lossless compression"
msgstr "无损压缩"
#: export_format_manager.cc:207 export_format_specification.cc:579
#: export_format_manager.cc:218 export_format_specification.cc:579
msgid "Session rate"
msgstr ""
@@ -537,7 +537,7 @@ msgstr "三角形"
msgid "Rectangular"
msgstr "长方形"
#: export_formats.cc:52 session.cc:4854 session.cc:4870
#: export_formats.cc:52 session.cc:4861 session.cc:4877
msgid "None"
msgstr ""
@@ -748,23 +748,23 @@ msgstr ""
msgid "unknown file type for session %1"
msgstr ""
#: globals.cc:204
#: globals.cc:205
msgid "Could not set system open files limit to \"unlimited\""
msgstr ""
#: globals.cc:206
#: globals.cc:207
msgid "Could not set system open files limit to %1"
msgstr ""
#: globals.cc:210
#: globals.cc:211
msgid "Your system is configured to limit %1 to only %2 open files"
msgstr ""
#: globals.cc:214
#: globals.cc:215
msgid "Could not get system open files limit (%1)"
msgstr ""
#: globals.cc:267
#: globals.cc:266
msgid "Loading configuration"
msgstr "载入配置"
@@ -917,19 +917,19 @@ msgstr ""
msgid "%d"
msgstr ""
#: ladspa_plugin.cc:87
#: ladspa_plugin.cc:88
msgid "LADSPA: module has no descriptor function."
msgstr "LADSPA: 模块没有描述符函数."
#: ladspa_plugin.cc:92
#: ladspa_plugin.cc:93
msgid "LADSPA: plugin has gone away since discovery!"
msgstr "LADSPA: 当发现插件时, 插件已经不见了."
#: ladspa_plugin.cc:99
#: ladspa_plugin.cc:100
msgid "LADSPA: \"%1\" cannot be used, since it cannot do inplace processing"
msgstr ""
#: ladspa_plugin.cc:296
#: ladspa_plugin.cc:297
#, fuzzy
msgid ""
"illegal parameter number used with plugin \"%1\". This may indicate a change "
@@ -937,35 +937,35 @@ msgid ""
msgstr ""
"插件\"%1\"使用非法参数数量. 这可能意味着插件的设计有所变动, 而且预设失效了."
#: ladspa_plugin.cc:373 ladspa_plugin.cc:418
#: ladspa_plugin.cc:376 ladspa_plugin.cc:426
msgid "Bad node sent to LadspaPlugin::set_state"
msgstr "坏的符号发送至 LadspaPlugin::set_state"
#: ladspa_plugin.cc:386 ladspa_plugin.cc:431
#: ladspa_plugin.cc:391 ladspa_plugin.cc:440
msgid "LADSPA: no ladspa port number"
msgstr "LADSPA: 没有 ladspa 端口数量"
#: ladspa_plugin.cc:392 ladspa_plugin.cc:437
#: ladspa_plugin.cc:397 ladspa_plugin.cc:446
msgid "LADSPA: no ladspa port data"
msgstr "LADSPA: 没有LADSPA端口数据"
#: ladspa_plugin.cc:707
#: ladspa_plugin.cc:717
msgid "LADSPA: cannot load module from \"%1\""
msgstr "LADSPA: 无法从 \"%1\" 载入模块"
#: ladspa_plugin.cc:817
#: ladspa_plugin.cc:827
msgid "Could not locate HOME. Preset not removed."
msgstr "无法定位HOME. 预设没被移除."
#: ladspa_plugin.cc:854 ladspa_plugin.cc:860
#: ladspa_plugin.cc:864 ladspa_plugin.cc:870
msgid "Could not create %1. Preset not saved. (%2)"
msgstr "不能创建 %1. 预设没保存. (%2)"
#: ladspa_plugin.cc:867
#: ladspa_plugin.cc:877
msgid "Error saving presets file %1."
msgstr ""
#: ladspa_plugin.cc:905
#: ladspa_plugin.cc:915
msgid "Could not locate HOME. Preset not saved."
msgstr "无法定位HOME. 预设没保存."
@@ -1005,7 +1005,7 @@ msgstr ""
msgid "incorrect XML mode passed to Locations::set_state"
msgstr ""
#: location.cc:842 session.cc:4355 session_state.cc:1114
#: location.cc:842 session.cc:4362 session_state.cc:1114
msgid "session"
msgstr "会话"
@@ -1077,23 +1077,23 @@ msgstr ""
msgid "MidiDiskstream %1: there is no existing playlist to make a copy of!"
msgstr ""
#: midi_diskstream.cc:685
#: midi_diskstream.cc:699
msgid "MidiDiskstream %1: cannot read %2 from playlist at frame %3"
msgstr ""
#: midi_diskstream.cc:820
#: midi_diskstream.cc:834
msgid "MidiDiskstream %1: cannot write to disk"
msgstr "MIDI磁盘流 %1: 无法写入硬盘"
#: midi_diskstream.cc:854
#: midi_diskstream.cc:868
msgid "MidiDiskstream \"%1\": cannot flush captured data to disk!"
msgstr ""
#: midi_diskstream.cc:941
#: midi_diskstream.cc:955
msgid "%1: could not create region for complete midi file"
msgstr ""
#: midi_diskstream.cc:978
#: midi_diskstream.cc:992
msgid "MidiDiskstream: could not create region for captured midi!"
msgstr ""
@@ -1287,37 +1287,49 @@ msgstr ""
msgid "Could not construct playlist for PlaylistSource from session data!"
msgstr ""
#: plugin_insert.cc:599
#: plugin.cc:324
msgid ""
"Plugin presets are not supported in this build of %1. Consider paying for a "
"full version"
msgstr ""
#: plugin.cc:398
msgid ""
"Saving plugin settings is not supported in this build of %1. Consider paying "
"for the full version"
msgstr ""
#: plugin_insert.cc:598
msgid "programming error: "
msgstr "程序错误:"
#: plugin_insert.cc:908
#: plugin_insert.cc:926
msgid "XML node describing plugin is missing the `type' field"
msgstr ""
#: plugin_insert.cc:923
#: plugin_insert.cc:941
msgid "unknown plugin type %1 in plugin insert state"
msgstr ""
#: plugin_insert.cc:951
#: plugin_insert.cc:969
msgid "Plugin has no unique ID field"
msgstr ""
#: plugin_insert.cc:960
#: plugin_insert.cc:978
msgid ""
"Found a reference to a plugin (\"%1\") that is unknown.\n"
"Perhaps it was removed or moved since it was last used."
msgstr ""
#: plugin_insert.cc:1076
#: plugin_insert.cc:1094
msgid "PluginInsert: Auto: no ladspa port number"
msgstr ""
#: plugin_insert.cc:1083
#: plugin_insert.cc:1101
msgid "PluginInsert: Auto: port id out of range"
msgstr ""
#: plugin_insert.cc:1119
#: plugin_insert.cc:1137
msgid "PluginInsert: automatable control %1 not found - ignored"
msgstr ""
@@ -1457,23 +1469,23 @@ msgstr "导入: src_new() 失败 : %1"
msgid "return %1"
msgstr "返回 %1"
#: route.cc:1100 route.cc:2550
#: route.cc:1105 route.cc:2581
msgid "unknown Processor type \"%1\"; ignored"
msgstr ""
#: route.cc:1112
#: route.cc:1117
msgid "processor could not be created. Ignored."
msgstr ""
#: route.cc:1983 route.cc:2203
#: route.cc:2007 route.cc:2234
msgid "Bad node sent to Route::set_state() [%1]"
msgstr "损坏的符号发送至 Route::set_state() [%1]"
#: route.cc:2042
#: route.cc:2067
msgid "Pannable state found for route (%1) without a panner!"
msgstr ""
#: route.cc:2106 route.cc:2110 route.cc:2317 route.cc:2321
#: route.cc:2137 route.cc:2141 route.cc:2348 route.cc:2352
msgid "badly formed order key string in state file! [%1] ... ignored."
msgstr ""
@@ -1727,17 +1739,17 @@ msgstr ""
msgid "Export ended unexpectedly: %1"
msgstr ""
#: session_ltc.cc:220
#: session_ltc.cc:222
msgid ""
"LTC encoder: invalid framerate - LTC encoding is disabled for the remainder "
"of this session."
msgstr ""
#: session_midi.cc:427
#: session_midi.cc:428
msgid "Session: could not send full MIDI time code"
msgstr ""
#: session_midi.cc:519
#: session_midi.cc:520
msgid "Session: cannot send quarter-frame MTC message (%1)"
msgstr ""
@@ -1745,11 +1757,11 @@ msgstr ""
msgid "Session: cannot create Playlist from XML description."
msgstr "会话: 无法从XML描述符创建播放列表."
#: session_process.cc:135
#: session_process.cc:133
msgid "Session: error in no roll for %1"
msgstr ""
#: session_process.cc:1160
#: session_process.cc:1158
msgid "Programming error: illegal event type in process_event (%1)"
msgstr ""
@@ -2112,13 +2124,13 @@ msgstr ""
msgid "Cannot loop - no loop range defined"
msgstr ""
#: session_transport.cc:727
#: session_transport.cc:728
msgid ""
"Seamless looping cannot be supported while %1 is using JACK transport.\n"
"Recommend changing the configured options"
msgstr ""
#: session_transport.cc:1092
#: session_transport.cc:1094
msgid ""
"Global varispeed cannot be supported while %1 is connected to JACK transport "
"control"
@@ -2261,7 +2273,7 @@ msgstr ""
msgid "attempt to write a non-writable audio file source (%1)"
msgstr ""
#: sndfilesource.cc:396 utils.cc:497 utils.cc:521 utils.cc:535 utils.cc:554
#: sndfilesource.cc:396 utils.cc:507 utils.cc:531 utils.cc:545 utils.cc:564
msgid "programming error: %1 %2"
msgstr "程序错误: %1 %2"
@@ -2511,11 +2523,11 @@ msgstr "MIDI时钟"
msgid "LTC"
msgstr "MTC"
#: utils.cc:589
#: utils.cc:599
msgid "programming error: unknown native header format: %1"
msgstr ""
#: utils.cc:604
#: utils.cc:614
msgid "cannot open directory %1 (%2)"
msgstr "无法打开目录 %1 (%2)"

View File

@@ -30,6 +30,7 @@
#include "ardour/audioengine.h"
#include "ardour/debug.h"
#include "ardour/port.h"
#include "ardour/port_engine.h"
#include "i18n.h"
@@ -40,13 +41,19 @@ using namespace PBD;
PBD::Signal2<void,boost::shared_ptr<Port>, boost::shared_ptr<Port> > Port::PostDisconnect;
PBD::Signal0<void> Port::PortDrop;
AudioEngine* Port::_engine = 0;
bool Port::_connecting_blocked = false;
pframes_t Port::_global_port_buffer_offset = 0;
pframes_t Port::_cycle_nframes = 0;
std::string Port::state_node_name = X_("Port");
/* a handy define to shorten what would otherwise be a needlessly verbose
* repeated phrase
*/
#define port_engine AudioEngine::instance()->port_engine()
#define port_manager AudioEngine::instance()
/** @param n Port short name */
Port::Port (std::string const & n, DataType t, Flags f)
Port::Port (std::string const & n, DataType t, PortFlags f)
: _port_buffer_offset (0)
, _name (n)
, _flags (f)
@@ -58,21 +65,17 @@ Port::Port (std::string const & n, DataType t, Flags f)
_private_capture_latency.max = 0;
/* Unfortunately we have to pass the DataType into this constructor so that
we can create the right kind of JACK port; aside from this we'll use the
we can create the right kind of port; aside from this we'll use the
virtual function type () to establish type.
*/
assert (_name.find_first_of (':') == std::string::npos);
if (!_engine->connected()) {
if ((_port_handle = port_engine.register_port (_name, t, _flags)) == 0) {
cerr << "Failed to register port \"" << _name << "\", reason is unknown from here\n";
throw failed_constructor ();
}
if ((_jack_port = jack_port_register (_engine->jack (), _name.c_str (), t.to_jack_type (), _flags, 0)) == 0) {
cerr << "Failed to register JACK port \"" << _name << "\", reason is unknown from here\n";
throw failed_constructor ();
}
PortDrop.connect_same_thread (drop_connection, boost::bind (&Port::drop, this));
}
@@ -85,11 +88,10 @@ Port::~Port ()
void
Port::drop ()
{
if (_jack_port) {
if (_engine->jack ()) {
jack_port_unregister (_engine->jack (), _jack_port);
}
_jack_port = 0;
if (_port_handle) {
DEBUG_TRACE (DEBUG::Ports, string_compose ("drop handle for port %1\n", name()));
port_engine.unregister_port (_port_handle);
_port_handle = 0;
}
}
@@ -97,18 +99,18 @@ Port::drop ()
bool
Port::connected () const
{
return (jack_port_connected (_jack_port) != 0);
return (port_engine.connected (_port_handle) != 0);
}
int
Port::disconnect_all ()
{
jack_port_disconnect (_engine->jack(), _jack_port);
port_engine.disconnect_all (_port_handle);
_connections.clear ();
/* a cheaper, less hacky way to do boost::shared_from_this() ...
*/
boost::shared_ptr<Port> pself = _engine->get_port_by_name (name());
boost::shared_ptr<Port> pself = port_manager->get_port_by_name (name());
PostDisconnect (pself, boost::shared_ptr<Port>()); // emit signal
return 0;
@@ -120,48 +122,29 @@ Port::disconnect_all ()
bool
Port::connected_to (std::string const & o) const
{
if (!_engine->connected()) {
/* in some senses, this answer isn't the right one all the time,
because we know about our connections and will re-establish
them when we reconnect to JACK.
*/
if (!port_engine.available()) {
return false;
}
return jack_port_connected_to (_jack_port,
_engine->make_port_name_non_relative(o).c_str ());
return port_engine.connected_to (_port_handle, AudioEngine::instance()->make_port_name_non_relative (o));
}
/** @param o Filled in with port full names of ports that we are connected to */
int
Port::get_connections (std::vector<std::string> & c) const
{
int n = 0;
if (_engine->connected()) {
const char** jc = jack_port_get_connections (_jack_port);
if (jc) {
for (int i = 0; jc[i]; ++i) {
c.push_back (jc[i]);
++n;
}
if (jack_free) {
jack_free (jc);
} else {
free (jc);
}
}
if (!port_engine.available()) {
c.insert (c.end(), _connections.begin(), _connections.end());
return c.size();
}
return n;
return port_engine.get_connections (_port_handle, c);
}
int
Port::connect (std::string const & other)
{
std::string const other_shrt = _engine->make_port_name_non_relative (other);
std::string const this_shrt = _engine->make_port_name_non_relative (_name);
std::string const other_name = AudioEngine::instance()->make_port_name_non_relative (other);
std::string const our_name = AudioEngine::instance()->make_port_name_non_relative (_name);
int r = 0;
@@ -170,9 +153,11 @@ Port::connect (std::string const & other)
}
if (sends_output ()) {
r = jack_connect (_engine->jack (), this_shrt.c_str (), other_shrt.c_str ());
DEBUG_TRACE (DEBUG::Ports, string_compose ("Connect %1 to %2\n", our_name, other_name));
r = port_engine.connect (our_name, other_name);
} else {
r = jack_connect (_engine->jack (), other_shrt.c_str (), this_shrt.c_str());
DEBUG_TRACE (DEBUG::Ports, string_compose ("Connect %1 to %2\n", other_name, our_name));
r = port_engine.connect (other_name, our_name);
}
if (r == 0) {
@@ -185,15 +170,15 @@ Port::connect (std::string const & other)
int
Port::disconnect (std::string const & other)
{
std::string const other_fullname = _engine->make_port_name_non_relative (other);
std::string const this_fullname = _engine->make_port_name_non_relative (_name);
std::string const other_fullname = port_manager->make_port_name_non_relative (other);
std::string const this_fullname = port_manager->make_port_name_non_relative (_name);
int r = 0;
if (sends_output ()) {
r = jack_disconnect (_engine->jack (), this_fullname.c_str (), other_fullname.c_str ());
r = port_engine.disconnect (this_fullname, other_fullname);
} else {
r = jack_disconnect (_engine->jack (), other_fullname.c_str (), this_fullname.c_str ());
r = port_engine.disconnect (other_fullname, this_fullname);
}
if (r == 0) {
@@ -202,8 +187,8 @@ Port::disconnect (std::string const & other)
/* a cheaper, less hacky way to do boost::shared_from_this() ...
*/
boost::shared_ptr<Port> pself = _engine->get_port_by_name (name());
boost::shared_ptr<Port> pother = _engine->get_port_by_name (other);
boost::shared_ptr<Port> pself = AudioEngine::instance()->get_port_by_name (name());
boost::shared_ptr<Port> pother = AudioEngine::instance()->get_port_by_name (other);
if (pself && pother) {
/* Disconnecting from another Ardour port: need to allow
@@ -236,21 +221,22 @@ Port::disconnect (Port* o)
}
void
Port::set_engine (AudioEngine* e)
Port::request_input_monitoring (bool yn)
{
_engine = e;
port_engine.request_input_monitoring (_port_handle, yn);
}
void
Port::ensure_jack_monitors_input (bool yn)
Port::ensure_input_monitoring (bool yn)
{
jack_port_ensure_monitor (_jack_port, yn);
port_engine.ensure_input_monitoring (_port_handle, yn);
}
bool
Port::jack_monitoring_input () const
Port::monitoring_input () const
{
return jack_port_monitoring_input (_jack_port);
return port_engine.monitoring_input (_port_handle);
}
void
@@ -272,28 +258,23 @@ Port::increment_port_buffer_offset (pframes_t nframes)
}
void
Port::set_public_latency_range (jack_latency_range_t& range, bool playback) const
Port::set_public_latency_range (LatencyRange& range, bool playback) const
{
/* this sets the visible latency that the rest of JACK sees. because we do latency
compensation, all (most) of our visible port latency values are identical.
/* this sets the visible latency that the rest of the port system
sees. because we do latency compensation, all (most) of our visible
port latency values are identical.
*/
if (!jack_port_set_latency_range) {
return;
}
DEBUG_TRACE (DEBUG::Latency,
string_compose ("SET PORT %1 %4 PUBLIC latency now [%2 - %3]\n",
name(), range.min, range.max,
(playback ? "PLAYBACK" : "CAPTURE")));;
jack_port_set_latency_range (_jack_port,
(playback ? JackPlaybackLatency : JackCaptureLatency),
&range);
port_engine.set_latency_range (_port_handle, playback, range);
}
void
Port::set_private_latency_range (jack_latency_range_t& range, bool playback)
Port::set_private_latency_range (LatencyRange& range, bool playback)
{
if (playback) {
_private_playback_latency = range;
@@ -311,12 +292,12 @@ Port::set_private_latency_range (jack_latency_range_t& range, bool playback)
_private_capture_latency.max));
}
/* push to public (JACK) location so that everyone else can see it */
/* push to public (port system) location so that everyone else can see it */
set_public_latency_range (range, playback);
}
const jack_latency_range_t&
const LatencyRange&
Port::private_latency_range (bool playback) const
{
if (playback) {
@@ -336,14 +317,13 @@ Port::private_latency_range (bool playback) const
}
}
jack_latency_range_t
LatencyRange
Port::public_latency_range (bool /*playback*/) const
{
jack_latency_range_t r;
LatencyRange r;
r = port_engine.get_latency_range (_port_handle, sends_output() ? true : false);
jack_port_get_latency_range (_jack_port,
sends_output() ? JackPlaybackLatency : JackCaptureLatency,
&r);
DEBUG_TRACE (DEBUG::Latency, string_compose (
"GET PORT %1: %4 PUBLIC latency range %2 .. %3\n",
name(), r.min, r.max,
@@ -352,27 +332,15 @@ Port::public_latency_range (bool /*playback*/) const
}
void
Port::get_connected_latency_range (jack_latency_range_t& range, bool playback) const
Port::get_connected_latency_range (LatencyRange& range, bool playback) const
{
if (!jack_port_get_latency_range) {
return;
}
vector<string> connections;
jack_client_t* jack = _engine->jack();
if (!jack) {
range.min = 0;
range.max = 0;
PBD::warning << _("get_connected_latency_range() called while disconnected from JACK") << endmsg;
return;
}
get_connections (connections);
if (!connections.empty()) {
range.min = ~((jack_nframes_t) 0);
range.min = ~((pframes_t) 0);
range.max = 0;
DEBUG_TRACE (DEBUG::Latency, string_compose ("%1: %2 connections to check for latency range\n", name(), connections.size()));
@@ -380,21 +348,18 @@ Port::get_connected_latency_range (jack_latency_range_t& range, bool playback) c
for (vector<string>::const_iterator c = connections.begin();
c != connections.end(); ++c) {
jack_latency_range_t lr;
LatencyRange lr;
if (!AudioEngine::instance()->port_is_mine (*c)) {
/* port belongs to some other JACK client, use
* JACK to lookup its latency information.
/* port belongs to some other port-system client, use
* the port engine to lookup its latency information.
*/
jack_port_t* remote_port = jack_port_by_name (_engine->jack(), (*c).c_str());
PortEngine::PortHandle remote_port = port_engine.get_port_by_name (*c);
if (remote_port) {
jack_port_get_latency_range (
remote_port,
(playback ? JackPlaybackLatency : JackCaptureLatency),
&lr);
lr = port_engine.get_latency_range (remote_port, playback);
DEBUG_TRACE (DEBUG::Latency, string_compose (
"\t%1 <-> %2 : latter has latency range %3 .. %4\n",
@@ -438,15 +403,10 @@ Port::get_connected_latency_range (jack_latency_range_t& range, bool playback) c
int
Port::reestablish ()
{
jack_client_t* jack = _engine->jack();
DEBUG_TRACE (DEBUG::Ports, string_compose ("re-establish %1 port %2\n", type().to_string(), _name));
_port_handle = port_engine.register_port (_name, type(), _flags);
if (!jack) {
return -1;
}
_jack_port = jack_port_register (jack, _name.c_str(), type().to_jack_type(), _flags, 0);
if (_jack_port == 0) {
if (_port_handle == 0) {
PBD::error << string_compose (_("could not reregister %1"), _name) << endmsg;
return -1;
}
@@ -462,6 +422,8 @@ Port::reconnect ()
{
/* caller must hold process lock; intended to be used only after reestablish() */
DEBUG_TRACE (DEBUG::Ports, string_compose ("Connect %1 to %2 destinations\n",name(), _connections.size()));
for (std::set<string>::iterator i = _connections.begin(); i != _connections.end(); ++i) {
if (connect (*i)) {
return -1;
@@ -471,7 +433,7 @@ Port::reconnect ()
return 0;
}
/** @param n Short port name (no JACK client name) */
/** @param n Short port name (no port-system client name) */
int
Port::set_name (std::string const & n)
{
@@ -479,10 +441,10 @@ Port::set_name (std::string const & n)
return 0;
}
int const r = jack_port_set_name (_jack_port, n.c_str());
int const r = port_engine.set_port_name (_port_handle, n);
if (r == 0) {
_engine->port_renamed (_name, n);
AudioEngine::instance()->port_renamed (_name, n);
_name = n;
}
@@ -490,38 +452,67 @@ Port::set_name (std::string const & n)
return r;
}
void
Port::request_jack_monitors_input (bool yn)
{
jack_port_request_monitor (_jack_port, yn);
}
bool
Port::physically_connected () const
{
const char** jc = jack_port_get_connections (_jack_port);
if (jc) {
for (int i = 0; jc[i]; ++i) {
jack_port_t* port = jack_port_by_name (_engine->jack(), jc[i]);
if (port && (jack_port_flags (port) & JackPortIsPhysical)) {
if (jack_free) {
jack_free (jc);
} else {
free (jc);
}
return true;
}
}
if (jack_free) {
jack_free (jc);
} else {
free (jc);
}
}
return false;
return port_engine.physically_connected (_port_handle);
}
XMLNode&
Port::get_state () const
{
XMLNode* root = new XMLNode (state_node_name);
root->add_property (X_("name"), AudioEngine::instance()->make_port_name_relative (name()));
if (receives_input()) {
root->add_property (X_("direction"), X_("input"));
} else {
root->add_property (X_("direction"), X_("output"));
}
vector<string> c;
get_connections (c);
for (vector<string>::const_iterator i = c.begin(); i != c.end(); ++i) {
XMLNode* child = new XMLNode (X_("Connection"));
child->add_property (X_("other"), *i);
root->add_child_nocopy (*child);
}
return *root;
}
int
Port::set_state (const XMLNode& node, int)
{
const XMLProperty* prop;
if (node.name() != state_node_name) {
return -1;
}
if ((prop = node.property (X_("name"))) != 0) {
set_name (prop->value());
}
const XMLNodeList& children (node.children());
_connections.clear ();
for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
if ((*c)->name() != X_("Connection")) {
continue;
}
if ((prop = (*c)->property (X_("other"))) == 0) {
continue;
}
_connections.insert (prop->value());
}
return 0;
}

View File

@@ -49,7 +49,7 @@ PortInsert::PortInsert (Session& s, boost::shared_ptr<Pannable> pannable, boost:
{
_mtdm = 0;
_latency_detect = false;
_latency_flush_frames = false;
_latency_flush_frames = 0;
_measured_latency = 0;
}
@@ -64,7 +64,7 @@ PortInsert::start_latency_detection ()
{
delete _mtdm;
_mtdm = new MTDM (_session.frame_rate());
_latency_flush_frames = false;
_latency_flush_frames = 0;
_latency_detect = true;
_measured_latency = 0;
}
@@ -72,7 +72,7 @@ PortInsert::start_latency_detection ()
void
PortInsert::stop_latency_detection ()
{
_latency_flush_frames = signal_latency() + _session.engine().frames_per_cycle();
_latency_flush_frames = signal_latency() + _session.engine().samples_per_cycle();
_latency_detect = false;
}
@@ -93,7 +93,7 @@ PortInsert::latency() const
*/
if (_measured_latency == 0) {
return _session.engine().frames_per_cycle() + _input->latency();
return _session.engine().samples_per_cycle() + _input->latency();
} else {
return _measured_latency;
}
@@ -240,7 +240,7 @@ PortInsert::signal_latency() const
*/
if (_measured_latency == 0) {
return _session.engine().frames_per_cycle() + _input->signal_latency();
return _session.engine().samples_per_cycle() + _input->signal_latency();
} else {
return _measured_latency;
}

667
libs/ardour/port_manager.cc Normal file
View File

@@ -0,0 +1,667 @@
/*
Copyright (C) 2013 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/async_midi_port.h"
#include "ardour/audio_backend.h"
#include "ardour/audio_port.h"
#include "ardour/debug.h"
#include "ardour/midi_port.h"
#include "ardour/midiport_manager.h"
#include "ardour/port_manager.h"
#include "i18n.h"
using namespace ARDOUR;
using namespace PBD;
using std::string;
using std::vector;
PortManager::PortManager ()
: ports (new Ports)
, _port_remove_in_progress (false)
{
}
void
PortManager::remove_all_ports ()
{
/* make sure that JACK callbacks that will be invoked as we cleanup
* ports know that they have nothing to do.
*/
_port_remove_in_progress = true;
/* process lock MUST be held by caller
*/
{
RCUWriter<Ports> writer (ports);
boost::shared_ptr<Ports> ps = writer.get_copy ();
ps->clear ();
}
/* clear dead wood list in RCU */
ports.flush ();
_port_remove_in_progress = false;
}
string
PortManager::make_port_name_relative (const string& portname) const
{
if (!_backend) {
return portname;
}
string::size_type len;
string::size_type n;
string self = _backend->my_name();
len = portname.length();
for (n = 0; n < len; ++n) {
if (portname[n] == ':') {
break;
}
}
if ((n != len) && (portname.substr (0, n) == self)) {
return portname.substr (n+1);
}
return portname;
}
string
PortManager::make_port_name_non_relative (const string& portname) const
{
string str;
if (portname.find_first_of (':') != string::npos) {
return portname;
}
str = _backend->my_name();
str += ':';
str += portname;
return str;
}
bool
PortManager::port_is_mine (const string& portname) const
{
if (!_backend) {
return true;
}
string self = _backend->my_name();
if (portname.find_first_of (':') != string::npos) {
if (portname.substr (0, self.length ()) != self) {
return false;
}
}
return true;
}
bool
PortManager::port_is_physical (const std::string& portname) const
{
if (!_backend) {
return false;
}
PortEngine::PortHandle ph = _backend->get_port_by_name (portname);
if (!ph) {
return false;
}
return _backend->port_is_physical (ph);
}
void
PortManager::get_physical_outputs (DataType type, std::vector<std::string>& s)
{
if (!_backend) {
return;
}
_backend->get_physical_outputs (type, s);
}
void
PortManager::get_physical_inputs (DataType type, std::vector<std::string>& s)
{
if (!_backend) {
return;
}
_backend->get_physical_inputs (type, s);
}
ChanCount
PortManager::n_physical_outputs () const
{
if (!_backend) {
return ChanCount::ZERO;
}
return _backend->n_physical_outputs ();
}
ChanCount
PortManager::n_physical_inputs () const
{
if (!_backend) {
return ChanCount::ZERO;
}
return _backend->n_physical_inputs ();
}
/** @param name Full or short name of port
* @return Corresponding Port or 0.
*/
boost::shared_ptr<Port>
PortManager::get_port_by_name (const string& portname)
{
if (!_backend) {
return boost::shared_ptr<Port>();
}
if (!port_is_mine (portname)) {
/* not an ardour port */
return boost::shared_ptr<Port> ();
}
boost::shared_ptr<Ports> pr = ports.reader();
std::string rel = make_port_name_relative (portname);
Ports::iterator x = pr->find (rel);
if (x != pr->end()) {
/* its possible that the port was renamed by some 3rd party and
we don't know about it. check for this (the check is quick
and cheap), and if so, rename the port (which will alter
the port map as a side effect).
*/
const std::string check = make_port_name_relative (_backend->get_port_name (x->second->port_handle()));
if (check != rel) {
x->second->set_name (check);
}
return x->second;
}
return boost::shared_ptr<Port> ();
}
void
PortManager::port_renamed (const std::string& old_relative_name, const std::string& new_relative_name)
{
RCUWriter<Ports> writer (ports);
boost::shared_ptr<Ports> p = writer.get_copy();
Ports::iterator x = p->find (old_relative_name);
if (x != p->end()) {
boost::shared_ptr<Port> port = x->second;
p->erase (x);
p->insert (make_pair (new_relative_name, port));
}
}
int
PortManager::get_ports (DataType type, PortList& pl)
{
boost::shared_ptr<Ports> plist = ports.reader();
for (Ports::iterator p = plist->begin(); p != plist->end(); ++p) {
if (p->second->type() == type) {
pl.push_back (p->second);
}
}
return pl.size();
}
int
PortManager::get_ports (const string& port_name_pattern, DataType type, PortFlags flags, vector<string>& s)
{
if (!_backend) {
return 0;
}
return _backend->get_ports (port_name_pattern, type, flags, s);
}
void
PortManager::port_registration_failure (const std::string& portname)
{
if (!_backend) {
return;
}
string full_portname = _backend->my_name();
full_portname += ':';
full_portname += portname;
PortEngine::PortHandle p = _backend->get_port_by_name (full_portname);
string reason;
if (p) {
reason = string_compose (_("a port with the name \"%1\" already exists: check for duplicated track/bus names"), portname);
} else {
reason = string_compose (_("No more ports are available. You will need to stop %1 and restart with more ports if you need this many tracks."), PROGRAM_NAME);
}
throw PortRegistrationFailure (string_compose (_("AudioEngine: cannot register port \"%1\": %2"), portname, reason).c_str());
}
boost::shared_ptr<Port>
PortManager::register_port (DataType dtype, const string& portname, bool input, bool async)
{
boost::shared_ptr<Port> newport;
try {
if (dtype == DataType::AUDIO) {
DEBUG_TRACE (DEBUG::Ports, string_compose ("registering AUDIO port %1, input %2\n",
portname, input));
newport.reset (new AudioPort (portname, (input ? IsInput : IsOutput)));
} else if (dtype == DataType::MIDI) {
if (async) {
DEBUG_TRACE (DEBUG::Ports, string_compose ("registering ASYNC MIDI port %1, input %2\n",
portname, input));
newport.reset (new AsyncMIDIPort (portname, (input ? IsInput : IsOutput)));
} else {
DEBUG_TRACE (DEBUG::Ports, string_compose ("registering MIDI port %1, input %2\n",
portname, input));
newport.reset (new MidiPort (portname, (input ? IsInput : IsOutput)));
}
} else {
throw PortRegistrationFailure("unable to create port (unknown type)");
}
RCUWriter<Ports> writer (ports);
boost::shared_ptr<Ports> ps = writer.get_copy ();
ps->insert (make_pair (make_port_name_relative (portname), newport));
/* writer goes out of scope, forces update */
}
catch (PortRegistrationFailure& err) {
throw err;
} catch (std::exception& e) {
throw PortRegistrationFailure(string_compose(
_("unable to create port: %1"), e.what()).c_str());
} catch (...) {
throw PortRegistrationFailure("unable to create port (unknown error)");
}
DEBUG_TRACE (DEBUG::Ports, string_compose ("\t%2 port registration success, ports now = %1\n", ports.reader()->size(), this));
return newport;
}
boost::shared_ptr<Port>
PortManager::register_input_port (DataType type, const string& portname, bool async)
{
return register_port (type, portname, true, async);
}
boost::shared_ptr<Port>
PortManager::register_output_port (DataType type, const string& portname, bool async)
{
return register_port (type, portname, false, async);
}
int
PortManager::unregister_port (boost::shared_ptr<Port> port)
{
/* caller must hold process lock */
{
RCUWriter<Ports> writer (ports);
boost::shared_ptr<Ports> ps = writer.get_copy ();
Ports::iterator x = ps->find (make_port_name_relative (port->name()));
if (x != ps->end()) {
ps->erase (x);
}
/* writer goes out of scope, forces update */
}
ports.flush ();
return 0;
}
bool
PortManager::connected (const string& port_name)
{
if (!_backend) {
return false;
}
PortEngine::PortHandle handle = _backend->get_port_by_name (port_name);
if (!handle) {
return false;
}
return _backend->connected (handle);
}
int
PortManager::connect (const string& source, const string& destination)
{
int ret;
string s = make_port_name_non_relative (source);
string d = make_port_name_non_relative (destination);
boost::shared_ptr<Port> src = get_port_by_name (s);
boost::shared_ptr<Port> dst = get_port_by_name (d);
if (src) {
ret = src->connect (d);
} else if (dst) {
ret = dst->connect (s);
} else {
/* neither port is known to us ...hand-off to the PortEngine
*/
if (_backend) {
ret = _backend->connect (s, d);
} else {
ret = -1;
}
}
if (ret > 0) {
/* already exists - no error, no warning */
} else if (ret < 0) {
error << string_compose(_("AudioEngine: cannot connect %1 (%2) to %3 (%4)"),
source, s, destination, d)
<< endmsg;
}
return ret;
}
int
PortManager::disconnect (const string& source, const string& destination)
{
int ret;
string s = make_port_name_non_relative (source);
string d = make_port_name_non_relative (destination);
boost::shared_ptr<Port> src = get_port_by_name (s);
boost::shared_ptr<Port> dst = get_port_by_name (d);
if (src) {
ret = src->disconnect (d);
} else if (dst) {
ret = dst->disconnect (s);
} else {
/* neither port is known to us ...hand-off to the PortEngine
*/
if (_backend) {
ret = _backend->disconnect (s, d);
} else {
ret = -1;
}
}
return ret;
}
int
PortManager::disconnect (boost::shared_ptr<Port> port)
{
return port->disconnect_all ();
}
int
PortManager::reestablish_ports ()
{
Ports::iterator i;
boost::shared_ptr<Ports> p = ports.reader ();
DEBUG_TRACE (DEBUG::Ports, string_compose ("reestablish %1 ports\n", p->size()));
for (i = p->begin(); i != p->end(); ++i) {
if (i->second->reestablish ()) {
error << string_compose (_("Re-establising port %1 failed"), i->second->name()) << endmsg;
cerr << string_compose (_("Re-establising port %1 failed"), i->second->name()) << endl;
break;
}
}
if (i != p->end()) {
/* failed */
remove_all_ports ();
return -1;
}
return 0;
}
int
PortManager::reconnect_ports ()
{
boost::shared_ptr<Ports> p = ports.reader ();
/* re-establish connections */
DEBUG_TRACE (DEBUG::Ports, string_compose ("reconnect %1 ports\n", p->size()));
for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
i->second->reconnect ();
}
return 0;
}
void
PortManager::connect_callback (const string& a, const string& b, bool conn)
{
boost::shared_ptr<Port> port_a;
boost::shared_ptr<Port> port_b;
Ports::iterator x;
boost::shared_ptr<Ports> pr = ports.reader ();
x = pr->find (make_port_name_relative (a));
if (x != pr->end()) {
port_a = x->second;
}
x = pr->find (make_port_name_relative (b));
if (x != pr->end()) {
port_b = x->second;
}
PortConnectedOrDisconnected (
port_a, a,
port_b, b,
conn
); /* EMIT SIGNAL */
}
void
PortManager::registration_callback ()
{
if (!_port_remove_in_progress) {
PortRegisteredOrUnregistered (); /* EMIT SIGNAL */
}
}
bool
PortManager::can_request_input_monitoring () const
{
if (!_backend) {
return false;
}
return _backend->can_monitor_input ();
}
void
PortManager::request_input_monitoring (const string& name, bool yn) const
{
if (!_backend) {
return;
}
PortEngine::PortHandle ph = _backend->get_port_by_name (name);
if (ph) {
_backend->request_input_monitoring (ph, yn);
}
}
void
PortManager::ensure_input_monitoring (const string& name, bool yn) const
{
if (!_backend) {
return;
}
PortEngine::PortHandle ph = _backend->get_port_by_name (name);
if (ph) {
_backend->ensure_input_monitoring (ph, yn);
}
}
uint32_t
PortManager::port_name_size() const
{
if (!_backend) {
return 0;
}
return _backend->port_name_size ();
}
string
PortManager::my_name() const
{
if (!_backend) {
return string();
}
return _backend->my_name();
}
int
PortManager::graph_order_callback ()
{
if (!_port_remove_in_progress) {
GraphReordered(); /* EMIT SIGNAL */
}
return 0;
}
void
PortManager::cycle_start (pframes_t nframes)
{
Port::set_global_port_buffer_offset (0);
Port::set_cycle_framecnt (nframes);
_cycle_ports = ports.reader ();
for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
p->second->cycle_start (nframes);
}
}
void
PortManager::cycle_end (pframes_t nframes)
{
for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
p->second->cycle_end (nframes);
}
for (Ports::iterator p = _cycle_ports->begin(); p != _cycle_ports->end(); ++p) {
p->second->flush_buffers (nframes);
}
_cycle_ports.reset ();
/* we are done */
}
void
PortManager::silence (pframes_t nframes)
{
for (Ports::iterator i = _cycle_ports->begin(); i != _cycle_ports->end(); ++i) {
if (i->second->sends_output()) {
i->second->get_buffer(nframes).silence(nframes);
}
}
}
void
PortManager::check_monitoring ()
{
for (Ports::iterator i = _cycle_ports->begin(); i != _cycle_ports->end(); ++i) {
bool x;
if (i->second->last_monitor() != (x = i->second->monitoring_input ())) {
i->second->set_last_monitor (x);
/* XXX I think this is dangerous, due to
a likely mutex in the signal handlers ...
*/
i->second->MonitorInputChanged (x); /* EMIT SIGNAL */
}
}
}
void
PortManager::fade_out (gain_t base_gain, gain_t gain_step, pframes_t nframes)
{
for (Ports::iterator i = _cycle_ports->begin(); i != _cycle_ports->end(); ++i) {
if (i->second->sends_output()) {
boost::shared_ptr<AudioPort> ap = boost::dynamic_pointer_cast<AudioPort> (i->second);
if (ap) {
Sample* s = ap->engine_get_whole_audio_buffer ();
gain_t g = base_gain;
for (pframes_t n = 0; n < nframes; ++n) {
*s++ *= g;
g -= gain_step;
}
}
}
}
}
PortEngine&
PortManager::port_engine()
{
assert (_backend);
return *_backend;
}

View File

@@ -27,11 +27,11 @@
#include "pbd/xml++.h"
#include "pbd/file_utils.h"
#include "midi++/manager.h"
#include "ardour/audioengine.h"
#include "ardour/control_protocol_manager.h"
#include "ardour/diskstream.h"
#include "ardour/filesystem_paths.h"
#include "ardour/port.h"
#include "ardour/rc_configuration.h"
#include "ardour/session_metadata.h"
@@ -63,13 +63,8 @@ RCConfiguration::RCConfiguration ()
{
}
RCConfiguration::~RCConfiguration ()
{
for (list<XMLNode*>::iterator i = _midi_port_states.begin(); i != _midi_port_states.end(); ++i) {
delete *i;
}
delete _control_protocol_state;
}
@@ -177,16 +172,6 @@ RCConfiguration::get_state ()
root = new XMLNode("Ardour");
MIDI::Manager* mm = MIDI::Manager::instance();
if (mm) {
boost::shared_ptr<const MIDI::Manager::PortList> ports = mm->get_midi_ports();
for (MIDI::Manager::PortList::const_iterator i = ports->begin(); i != ports->end(); ++i) {
root->add_child_nocopy((*i)->get_state());
}
}
root->add_child_nocopy (get_variables ());
root->add_child_nocopy (SessionMetadata::Metadata()->get_user_state());
@@ -232,12 +217,6 @@ RCConfiguration::set_state (const XMLNode& root, int version)
XMLNodeConstIterator niter;
XMLNode *node;
for (list<XMLNode*>::iterator i = _midi_port_states.begin(); i != _midi_port_states.end(); ++i) {
delete *i;
}
_midi_port_states.clear ();
Stateful::save_extra_xml (root);
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
@@ -250,8 +229,6 @@ RCConfiguration::set_state (const XMLNode& root, int version)
SessionMetadata::Metadata()->set_state (*node, version);
} else if (node->name() == ControlProtocolManager::state_node_name) {
_control_protocol_state = new XMLNode (*node);
} else if (node->name() == MIDI::Port::state_node_name) {
_midi_port_states.push_back (new XMLNode (*node));
}
}

View File

@@ -1490,6 +1490,20 @@ Region::uses_source (boost::shared_ptr<const Source> source) const
}
}
for (SourceList::const_iterator i = _master_sources.begin(); i != _master_sources.end(); ++i) {
if (*i == source) {
return true;
}
boost::shared_ptr<PlaylistSource> ps = boost::dynamic_pointer_cast<PlaylistSource> (*i);
if (ps) {
if (ps->playlist()->uses_source (source)) {
return true;
}
}
}
return false;
}

View File

@@ -971,7 +971,7 @@ Route::add_processor (boost::shared_ptr<Processor> processor, boost::shared_ptr<
DEBUG_TRACE (DEBUG::Processors, string_compose (
"%1 adding processor %2\n", name(), processor->name()));
if (!_session.engine().connected() || !processor) {
if (!AudioEngine::instance()->connected() || !processor) {
return 1;
}
@@ -3814,13 +3814,13 @@ Route::update_port_latencies (PortSet& from, PortSet& to, bool playback, framecn
universally true, but the alternative is way too corner-case to worry about.
*/
jack_latency_range_t all_connections;
LatencyRange all_connections;
if (from.empty()) {
all_connections.min = 0;
all_connections.max = 0;
} else {
all_connections.min = ~((jack_nframes_t) 0);
all_connections.min = ~((pframes_t) 0);
all_connections.max = 0;
/* iterate over all "from" ports and determine the latency range for all of their
@@ -3829,7 +3829,7 @@ Route::update_port_latencies (PortSet& from, PortSet& to, bool playback, framecn
for (PortSet::iterator p = from.begin(); p != from.end(); ++p) {
jack_latency_range_t range;
LatencyRange range;
p->get_connected_latency_range (range, playback);
@@ -3894,7 +3894,7 @@ Route::set_public_port_latencies (framecnt_t value, bool playback) const
latency compensation into account.
*/
jack_latency_range_t range;
LatencyRange range;
range.min = value;
range.max = value;

View File

@@ -49,6 +49,7 @@
#include "ardour/amp.h"
#include "ardour/analyser.h"
#include "ardour/async_midi_port.h"
#include "ardour/audio_buffer.h"
#include "ardour/audio_diskstream.h"
#include "ardour/audio_port.h"
@@ -66,6 +67,7 @@
#include "ardour/debug.h"
#include "ardour/filename_extensions.h"
#include "ardour/graph.h"
#include "ardour/midiport_manager.h"
#include "ardour/midi_track.h"
#include "ardour/midi_ui.h"
#include "ardour/operations.h"
@@ -85,12 +87,11 @@
#include "ardour/session_playlists.h"
#include "ardour/smf_source.h"
#include "ardour/source_factory.h"
#include "ardour/speakers.h"
#include "ardour/utils.h"
#include "midi++/port.h"
#include "midi++/jack_midi_port.h"
#include "midi++/mmc.h"
#include "midi++/manager.h"
#include "i18n.h"
@@ -106,6 +107,7 @@ using namespace PBD;
bool Session::_disable_all_loaded_plugins = false;
PBD::Signal1<int,uint32_t> Session::AudioEngineSetupRequired;
PBD::Signal1<void,std::string> Session::Dialog;
PBD::Signal0<int> Session::AskAboutPendingState;
PBD::Signal2<int, framecnt_t, framecnt_t> Session::AskAboutSampleRateMismatch;
@@ -130,70 +132,171 @@ Session::Session (AudioEngine &eng,
const string& snapshot_name,
BusProfile* bus_profile,
string mix_template)
: _engine (eng)
: playlists (new SessionPlaylists)
, _engine (eng)
, process_function (&Session::process_with_events)
, waiting_for_sync_offset (false)
, _base_frame_rate (0)
, _current_frame_rate (0)
, _nominal_frame_rate (0)
, transport_sub_state (0)
, _record_status (Disabled)
, _transport_frame (0)
, _session_range_location (0)
, _slave (0)
, _silent (false)
, _transport_speed (0)
, _default_transport_speed (1.0)
, _last_transport_speed (0)
, _target_transport_speed (0.0)
, auto_play_legal (false)
, _last_slave_transport_frame (0)
, maximum_output_latency (0)
, _requested_return_frame (-1)
, current_block_size (0)
, _worst_output_latency (0)
, _worst_input_latency (0)
, _worst_track_latency (0)
, _have_captured (false)
, _meter_hold (0)
, _meter_falloff (0)
, _non_soloed_outs_muted (false)
, _listen_cnt (0)
, _solo_isolated_cnt (0)
, _writable (false)
, _was_seamless (Config->get_seamless_loop ())
, _under_nsm_control (false)
, _session_dir (new SessionDirectory(fullpath))
, delta_accumulator_cnt (0)
, average_slave_delta (1800) // !!! why 1800 ???
, average_dir (0)
, have_first_delta_accumulator (false)
, _slave_state (Stopped)
, post_export_sync (false)
, post_export_position (0)
, _exporting (false)
, _export_started (false)
, _export_rolling (false)
, _pre_export_mmc_enabled (false)
, _name (snapshot_name)
, _is_new (true)
, _send_qf_mtc (false)
, _pframes_since_last_mtc (0)
, session_midi_feedback (0)
, play_loop (false)
, loop_changing (false)
, last_loopend (0)
, _session_dir (new SessionDirectory (fullpath))
, _current_snapshot_name (snapshot_name)
, state_tree (0)
, _state_of_the_state (Clean)
, state_was_pending (false)
, _state_of_the_state (StateOfTheState(CannotSave|InitialConnecting|Loading))
, _last_roll_location (0)
, _last_roll_or_reversal_location (0)
, _last_record_location (0)
, pending_locate_roll (false)
, pending_locate_frame (0)
, pending_locate_flush (false)
, pending_abort (false)
, pending_auto_loop (false)
, _butler (new Butler (*this))
, _post_transport_work (0)
, cumulative_rf_motion (0)
, rf_scale (1.0)
, _locations (new Locations (*this))
, step_speed (0)
, outbound_mtc_timecode_frame (0)
, next_quarter_frame_to_send (-1)
, _frames_per_timecode_frame (0)
, _frames_per_hour (0)
, _timecode_frames_per_hour (0)
, last_timecode_valid (false)
, last_timecode_when (0)
, _send_timecode_update (false)
, ltc_encoder (0)
, ltc_enc_buf(0)
, ltc_buf_off (0)
, ltc_buf_len (0)
, ltc_speed (0)
, ltc_enc_byte (0)
, ltc_enc_pos (0)
, ltc_enc_cnt (0)
, ltc_enc_off (0)
, restarting (false)
, ltc_prev_cycle (0)
, ltc_timecode_offset (0)
, ltc_timecode_negative_offset (false)
, midi_control_ui (0)
, _tempo_map (0)
, _all_route_group (new RouteGroup (*this, "all"))
, routes (new RouteList)
, _adding_routes_in_progress (false)
, destructive_index (0)
, solo_update_disabled (false)
, default_fade_steepness (0)
, default_fade_msecs (0)
, _total_free_4k_blocks (0)
, _total_free_4k_blocks_uncertain (false)
, no_questions_about_missing_files (false)
, _playback_load (0)
, _capture_load (0)
, _bundles (new BundleList)
, _bundle_xml_node (0)
, _current_trans (0)
, _clicking (false)
, click_data (0)
, click_emphasis_data (0)
, click_length (0)
, click_emphasis_length (0)
, _clicks_cleared (0)
, _play_range (false)
, main_outs (0)
, first_file_data_format_reset (true)
, first_file_header_format_reset (true)
, have_looped (false)
, _have_rec_enabled_track (false)
, _step_editors (0)
, _suspend_timecode_transmission (0)
, _speakers (new Speakers)
, ignore_route_processor_changes (false)
{
_locations = new Locations (*this);
ltc_encoder = NULL;
if (how_many_dsp_threads () > 1) {
/* For now, only create the graph if we are using >1 DSP threads, as
it is a bit slower than the old code with 1 thread.
*/
_process_graph.reset (new Graph (*this));
}
playlists.reset (new SessionPlaylists);
_all_route_group->set_active (true, this);
interpolation.add_channel_to (0, 0);
if (!eng.connected()) {
throw failed_constructor();
}
n_physical_outputs = _engine.n_physical_outputs ();
n_physical_inputs = _engine.n_physical_inputs ();
first_stage_init (fullpath, snapshot_name);
_is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
uint32_t sr = 0;
pre_engine_init (fullpath);
if (_is_new) {
if (create (mix_template, bus_profile)) {
destroy ();
throw failed_constructor ();
}
} else {
if (load_state (_current_snapshot_name)) {
throw failed_constructor ();
}
/* try to get sample rate from XML state so that we
* can influence the SR if we set up the audio
* engine.
*/
if (state_tree) {
const XMLProperty* prop;
if ((prop = state_tree->root()->property (X_("sample-rate"))) != 0) {
sr = atoi (prop->value());
}
}
}
if (second_stage_init ()) {
if (ensure_engine (sr)) {
destroy ();
throw failed_constructor ();
}
store_recent_sessions(_name, _path);
if (post_engine_init ()) {
destroy ();
throw failed_constructor ();
}
store_recent_sessions (_name, _path);
bool was_dirty = dirty();
@@ -210,6 +313,16 @@ Session::Session (AudioEngine &eng,
EndTimeChanged.connect_same_thread (*this, boost::bind (&Session::end_time_changed, this, _1));
_is_new = false;
/* hook us up to the engine since we are now completely constructed */
BootMessage (_("Connect to engine"));
_engine.set_session (this);
_engine.reset_timebase ();
BootMessage (_("Session loading complete"));
}
Session::~Session ()
@@ -220,6 +333,37 @@ Session::~Session ()
destroy ();
}
int
Session::ensure_engine (uint32_t desired_sample_rate)
{
if (_engine.current_backend() == 0) {
/* backend is unknown ... */
boost::optional<int> r = AudioEngineSetupRequired (desired_sample_rate);
if (r.get_value_or (-1) != 0) {
return -1;
}
} else if (_engine.setup_required()) {
/* backend is known, but setup is needed */
boost::optional<int> r = AudioEngineSetupRequired (desired_sample_rate);
if (r.get_value_or (-1) != 0) {
return -1;
}
} else if (!_engine.running()) {
if (_engine.start()) {
return -1;
}
}
/* at this point the engine should be running
*/
if (!_engine.running()) {
return -1;
}
return 0;
}
void
Session::destroy ()
{
@@ -330,6 +474,8 @@ Session::destroy ()
/* not strictly necessary, but doing it here allows the shared_ptr debugging to work */
playlists.reset ();
delete _mmc;
delete _midi_ports;
delete _locations;
DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
@@ -340,135 +486,103 @@ Session::destroy ()
}
void
Session::when_engine_running ()
Session::setup_ltc ()
{
string first_physical_output;
BootMessage (_("Set block size and sample rate"));
set_block_size (_engine.frames_per_cycle());
set_frame_rate (_engine.frame_rate());
BootMessage (_("Using configuration"));
boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
Config->map_parameters (ff);
config.map_parameters (ft);
/* every time we reconnect, recompute worst case output latencies */
_engine.Running.connect_same_thread (*this, boost::bind (&Session::initialize_latencies, this));
if (synced_to_jack()) {
_engine.transport_stop ();
XMLNode* child = 0;
_ltc_input.reset (new IO (*this, _("LTC In"), IO::Input));
_ltc_output.reset (new IO (*this, _("LTC Out"), IO::Output));
if (state_tree && (child = find_named_node (*state_tree->root(), "LTC-In")) != 0) {
_ltc_input->set_state (*(child->children().front()), Stateful::loading_state_version);
} else {
{
Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
_ltc_input->ensure_io (ChanCount (DataType::AUDIO, 1), true, this);
}
reconnect_ltc_input ();
}
if (config.get_jack_time_master()) {
_engine.transport_locate (_transport_frame);
if (state_tree && (child = find_named_node (*state_tree->root(), "LTC-Out")) != 0) {
_ltc_output->set_state (*(child->children().front()), Stateful::loading_state_version);
} else {
{
Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
_ltc_output->ensure_io (ChanCount (DataType::AUDIO, 1), true, this);
}
reconnect_ltc_output ();
}
/* fix up names of LTC ports because we don't want the normal
* IO style of NAME/TYPE-{in,out}N
*/
_ltc_input->nth (0)->set_name (_("LTC-in"));
_ltc_output->nth (0)->set_name (_("LTC-out"));
}
void
Session::setup_click ()
{
XMLNode* child = 0;
_clicking = false;
try {
XMLNode* child = 0;
_click_io.reset (new ClickIO (*this, "click"));
_click_gain.reset (new Amp (*this));
_click_gain->activate ();
if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
_ltc_input.reset (new IO (*this, _("LTC In"), IO::Input));
_ltc_output.reset (new IO (*this, _("LTC Out"), IO::Output));
/* existing state for Click */
int c = 0;
if (state_tree && (child = find_named_node (*state_tree->root(), "LTC-In")) != 0) {
_ltc_input->set_state (*(child->children().front()), Stateful::loading_state_version);
if (Stateful::loading_state_version < 3000) {
c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
} else {
{
Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
_ltc_input->ensure_io (ChanCount (DataType::AUDIO, 1), true, this);
}
reconnect_ltc_input ();
}
if (state_tree && (child = find_named_node (*state_tree->root(), "LTC-Out")) != 0) {
_ltc_output->set_state (*(child->children().front()), Stateful::loading_state_version);
} else {
{
Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
_ltc_output->ensure_io (ChanCount (DataType::AUDIO, 1), true, this);
}
reconnect_ltc_output ();
}
/* fix up names of LTC ports because we don't want the normal
* IO style of NAME/TYPE-{in,out}N
*/
_ltc_input->nth (0)->set_name (_("LTC-in"));
_ltc_output->nth (0)->set_name (_("LTC-out"));
_click_io.reset (new ClickIO (*this, "click"));
_click_gain.reset (new Amp (*this));
_click_gain->activate ();
if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
/* existing state for Click */
int c = 0;
if (Stateful::loading_state_version < 3000) {
c = _click_io->set_state_2X (*child->children().front(), Stateful::loading_state_version, false);
} else {
const XMLNodeList& children (child->children());
XMLNodeList::const_iterator i = children.begin();
if ((c = _click_io->set_state (**i, Stateful::loading_state_version)) == 0) {
++i;
if (i != children.end()) {
c = _click_gain->set_state (**i, Stateful::loading_state_version);
}
const XMLNodeList& children (child->children());
XMLNodeList::const_iterator i = children.begin();
if ((c = _click_io->set_state (**i, Stateful::loading_state_version)) == 0) {
++i;
if (i != children.end()) {
c = _click_gain->set_state (**i, Stateful::loading_state_version);
}
}
}
if (c == 0) {
_clicking = Config->get_clicking ();
} else {
error << _("could not setup Click I/O") << endmsg;
_clicking = false;
}
if (c == 0) {
_clicking = Config->get_clicking ();
} else {
/* default state for Click: dual-mono to first 2 physical outputs */
error << _("could not setup Click I/O") << endmsg;
_clicking = false;
}
vector<string> outs;
_engine.get_physical_outputs (DataType::AUDIO, outs);
for (uint32_t physport = 0; physport < 2; ++physport) {
if (outs.size() > physport) {
if (_click_io->add_port (outs[physport], this)) {
// relax, even though its an error
}
} else {
/* default state for Click: dual-mono to first 2 physical outputs */
vector<string> outs;
_engine.get_physical_outputs (DataType::AUDIO, outs);
for (uint32_t physport = 0; physport < 2; ++physport) {
if (outs.size() > physport) {
if (_click_io->add_port (outs[physport], this)) {
// relax, even though its an error
}
}
}
if (_click_io->n_ports () > ChanCount::ZERO) {
_clicking = Config->get_clicking ();
}
if (_click_io->n_ports () > ChanCount::ZERO) {
_clicking = Config->get_clicking ();
}
}
}
catch (failed_constructor& err) {
error << _("cannot setup Click I/O") << endmsg;
}
BootMessage (_("Compute I/O Latencies"));
if (_clicking) {
// XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
}
BootMessage (_("Set up standard connections"));
void
Session::setup_bundles ()
{
vector<string> inputs[DataType::num_types];
vector<string> outputs[DataType::num_types];
for (uint32_t i = 0; i < DataType::num_types; ++i) {
@@ -567,6 +681,37 @@ Session::when_engine_running ()
add_bundle (c);
}
}
int
Session::when_engine_running ()
{
/* every time we reconnect, recompute worst case output latencies */
_engine.Running.connect_same_thread (*this, boost::bind (&Session::initialize_latencies, this));
if (synced_to_jack()) {
_engine.transport_stop ();
}
if (config.get_jack_time_master()) {
_engine.transport_locate (_transport_frame);
}
try {
BootMessage (_("Set up LTC"));
setup_ltc ();
BootMessage (_("Set up Click"));
setup_click ();
BootMessage (_("Set up standard connections"));
setup_bundles ();
}
catch (failed_constructor& err) {
return -1;
}
BootMessage (_("Setup signal flow and plugins"));
/* Reset all panners */
@@ -584,7 +729,8 @@ Session::when_engine_running ()
as it will set states for ports which the ControlProtocolManager creates.
*/
MIDI::Manager::instance()->set_port_states (Config->midi_port_states ());
// XXX set state of MIDI::Port's
// MidiPortManager::instance()->set_port_states (Config->midi_port_states ());
/* And this must be done after the MIDI::Manager::set_port_states as
* it will try to make connections whose details are loaded by set_port_states.
@@ -609,11 +755,7 @@ Session::when_engine_running ()
initialize_latencies ();
/* hook us up to the engine */
BootMessage (_("Connect to engine"));
_engine.set_session (this);
_engine.reset_timebase ();
return 0;
}
void
@@ -874,7 +1016,12 @@ Session::hookup_io ()
/* Tell all IO objects to connect themselves together */
IO::enable_connecting ();
MIDI::JackMIDIPort::MakeConnections ();
/* Now tell all "floating" ports to connect to whatever
they should be connected to.
*/
AudioEngine::instance()->reconnect_ports ();
/* Anyone who cares about input state, wake up and do something */
@@ -936,7 +1083,7 @@ Session::set_track_monitor_input_status (bool yn)
boost::shared_ptr<AudioTrack> tr = boost::dynamic_pointer_cast<AudioTrack> (*i);
if (tr && tr->record_enabled ()) {
//cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
tr->request_jack_monitors_input (yn);
tr->request_input_monitoring (yn);
}
}
}
@@ -1169,7 +1316,7 @@ Session::enable_record ()
if (g_atomic_int_compare_and_exchange (&_record_status, rs, Recording)) {
_last_record_location = _transport_frame;
MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
_mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordStrobe));
if (Config->get_monitoring_model() == HardwareMonitoring && config.get_auto_input()) {
set_track_monitor_input_status (true);
@@ -1190,7 +1337,7 @@ Session::disable_record (bool rt_context, bool force)
if ((!Config->get_latched_record_enable () && !play_loop) || force) {
g_atomic_int_set (&_record_status, Disabled);
MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
_mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordExit));
} else {
if (rs == Recording) {
g_atomic_int_set (&_record_status, Enabled);
@@ -1244,7 +1391,7 @@ Session::maybe_enable_record ()
enable_record ();
}
} else {
MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
_mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdRecordPause));
RecordStateChanged (); /* EMIT SIGNAL */
}
@@ -1341,6 +1488,7 @@ Session::set_frame_rate (framecnt_t frames_per_second)
*/
_base_frame_rate = frames_per_second;
_nominal_frame_rate = frames_per_second;
sync_time_vars();

View File

@@ -21,7 +21,6 @@
#include "pbd/error.h"
#include <glibmm/threads.h>
#include <midi++/manager.h>
#include <midi++/mmc.h>
#include "ardour/audioengine.h"
@@ -93,8 +92,8 @@ Session::pre_export ()
/* disable MMC output early */
_pre_export_mmc_enabled = MIDI::Manager::instance()->mmc()->send_enabled ();
MIDI::Manager::instance()->mmc()->enable_send (false);
_pre_export_mmc_enabled = _mmc->send_enabled ();
_mmc->enable_send (false);
return 0;
}
@@ -237,7 +236,7 @@ Session::finalize_audio_export ()
export_freewheel_connection.disconnect();
MIDI::Manager::instance()->mmc()->enable_send (_pre_export_mmc_enabled);
_mmc->enable_send (_pre_export_mmc_enabled);
/* maybe write CUE/TOC */

185
libs/ardour/session_jack.cc Normal file
View File

@@ -0,0 +1,185 @@
/*
Copyright (C) 1999-2013 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.
*/
#ifdef WAF_BUILD
#include "libardour-config.h"
#endif
#include <time.h>
#include <glibmm/miscutils.h>
#include "jack/jack.h"
#include "jack/session.h"
#include "ardour/audioengine.h"
#include "ardour/filename_extensions.h"
#include "ardour/session.h"
#include "ardour/session_directory.h"
#include "ardour/tempo.h"
using namespace ARDOUR;
using std::string;
#ifdef HAVE_JACK_SESSION
void
Session::jack_session_event (jack_session_event_t* event)
{
char timebuf[128], *tmp;
time_t n;
struct tm local_time;
time (&n);
localtime_r (&n, &local_time);
strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
while ((tmp = strchr(timebuf, ':'))) { *tmp = '.'; }
if (event->type == JackSessionSaveTemplate)
{
if (save_template( timebuf )) {
event->flags = JackSessionSaveError;
} else {
string cmd ("ardour3 -P -U ");
cmd += event->client_uuid;
cmd += " -T ";
cmd += timebuf;
event->command_line = strdup (cmd.c_str());
}
}
else
{
if (save_state (timebuf)) {
event->flags = JackSessionSaveError;
} else {
std::string xml_path (_session_dir->root_path());
std::string legalized_filename = legalize_for_path (timebuf) + statefile_suffix;
xml_path = Glib::build_filename (xml_path, legalized_filename);
string cmd ("ardour3 -P -U ");
cmd += event->client_uuid;
cmd += " \"";
cmd += xml_path;
cmd += '\"';
event->command_line = strdup (cmd.c_str());
}
}
/* this won't be called if the port engine in use is not JACK, so we do
not have to worry about the type of PortEngine::private_handle()
*/
jack_client_t* jack_client = (jack_client_t*) AudioEngine::instance()->port_engine().private_handle();
if (jack_client) {
jack_session_reply (jack_client, event);
}
if (event->type == JackSessionSaveAndQuit) {
Quit (); /* EMIT SIGNAL */
}
jack_session_event_free( event );
}
#endif
void
Session::jack_timebase_callback (jack_transport_state_t /*state*/,
pframes_t /*nframes*/,
jack_position_t* pos,
int /*new_position*/)
{
Timecode::BBT_Time bbt;
/* BBT info */
if (_tempo_map) {
TempoMetric metric (_tempo_map->metric_at (_transport_frame));
try {
_tempo_map->bbt_time_rt (_transport_frame, bbt);
pos->bar = bbt.bars;
pos->beat = bbt.beats;
pos->tick = bbt.ticks;
// XXX still need to set bar_start_tick
pos->beats_per_bar = metric.meter().divisions_per_bar();
pos->beat_type = metric.meter().note_divisor();
pos->ticks_per_beat = Timecode::BBT_Time::ticks_per_beat;
pos->beats_per_minute = metric.tempo().beats_per_minute();
pos->valid = jack_position_bits_t (pos->valid | JackPositionBBT);
} catch (...) {
/* no message */
}
}
#ifdef HAVE_JACK_VIDEO_SUPPORT
//poke audio video ratio so Ardour can track Video Sync
pos->audio_frames_per_video_frame = frame_rate() / timecode_frames_per_second();
pos->valid = jack_position_bits_t (pos->valid | JackAudioVideoRatio);
#endif
#if 0
/* Timecode info */
pos->timecode_offset = config.get_timecode_offset();
t.timecode_frame_rate = timecode_frames_per_second();
pos->valid = jack_position_bits_t (pos->valid | JackPositionTimecode;
if (_transport_speed) {
if (play_loop) {
Location* location = _locations.auto_loop_location();
if (location) {
t.transport_state = JackTransportLooping;
t.loop_start = location->start();
t.loop_end = location->end();
t.valid = jack_transport_bits_t (t.valid | JackTransportLoop);
} else {
t.loop_start = 0;
t.loop_end = 0;
t.transport_state = JackTransportRolling;
}
} else {
t.loop_start = 0;
t.loop_end = 0;
t.transport_state = JackTransportRolling;
}
}
#endif
}

View File

@@ -56,7 +56,7 @@ using namespace Timecode;
* This filter is adaptive so that fast vari-speed signals
* will not be affected by it.
*/
#define LTC_RISE_TIME(speed) MIN (100, MAX(40, (4000000 / ((speed==0)?1:speed) / engine().frame_rate())))
#define LTC_RISE_TIME(speed) MIN (100, MAX(40, (4000000 / ((speed==0)?1:speed) / engine().sample_rate())))
#define TV_STANDARD(tcf) \
(timecode_to_frames_per_second(tcf)==25.0 ? LTC_TV_625_50 : \
@@ -565,7 +565,7 @@ Session::ltc_tx_send_time_code_for_cycle (framepos_t start_frame, framepos_t end
* To do better than this, resampling (or a rewrite of the
* encoder) is required.
*/
ltc_speed -= ((ltc_enc_pos + ltc_enc_cnt - poff) - cycle_start_frame) / engine().frame_rate();
ltc_speed -= ((ltc_enc_pos + ltc_enc_cnt - poff) - cycle_start_frame) / engine().sample_rate();
}

View File

@@ -31,7 +31,6 @@
#include "midi++/mmc.h"
#include "midi++/port.h"
#include "midi++/manager.h"
#include "pbd/error.h"
#include "pbd/pthread_utils.h"
@@ -41,6 +40,7 @@
#include "ardour/audio_track.h"
#include "ardour/audioengine.h"
#include "ardour/debug.h"
#include "ardour/midi_port.h"
#include "ardour/midi_track.h"
#include "ardour/midi_ui.h"
#include "ardour/session.h"
@@ -349,7 +349,7 @@ Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
* @param t time to send.
*/
int
Session::send_full_time_code (framepos_t const t)
Session::send_full_time_code (framepos_t const t, pframes_t nframes)
{
/* This function could easily send at a given frame offset, but would
* that be useful? Does ardour do sub-block accurate locating? [DR] */
@@ -424,10 +424,9 @@ Session::send_full_time_code (framepos_t const t)
msg[8] = timecode.frames;
// Send message at offset 0, sent time is for the start of this cycle
if (MIDI::Manager::instance()->mtc_output_port()->midimsg (msg, sizeof (msg), 0)) {
error << _("Session: could not send full MIDI time code") << endmsg;
return -1;
}
MidiBuffer& mb (_midi_ports->mtc_output_port()->get_midi_buffer (nframes));
mb.push_back (0, sizeof (msg), msg);
_pframes_since_last_mtc = 0;
return 0;
@@ -470,7 +469,7 @@ Session::send_midi_time_code_for_cycle (framepos_t start_frame, framepos_t end_f
next_quarter_frame_to_send, quarter_frame_duration));
if (rint(outbound_mtc_timecode_frame + (next_quarter_frame_to_send * quarter_frame_duration)) < _transport_frame) {
send_full_time_code (_transport_frame);
send_full_time_code (_transport_frame, nframes);
return 0;
}
@@ -516,9 +515,10 @@ Session::send_midi_time_code_for_cycle (framepos_t start_frame, framepos_t end_f
pframes_t const out_stamp = (msg_time - start_frame) / _transport_speed;
assert (out_stamp < nframes);
if (MIDI::Manager::instance()->mtc_output_port()->midimsg (mtc_msg, 2, out_stamp)) {
MidiBuffer& mb (_midi_ports->mtc_output_port()->get_midi_buffer(nframes));
if (!mb.push_back (out_stamp, 2, mtc_msg)) {
error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
<< endmsg;
<< endmsg;
return -1;
}
@@ -588,7 +588,7 @@ Session::mmc_step_timeout ()
void
Session::send_song_position_pointer (framepos_t t)
Session::send_song_position_pointer (framepos_t)
{
if (midi_clock) {
/* Do nothing for the moment */
@@ -603,3 +603,45 @@ Session::start_midi_thread ()
return 0;
}
MIDI::Port*
Session::midi_input_port () const
{
return _midi_ports->midi_input_port ();
}
MIDI::Port*
Session::midi_output_port () const
{
return _midi_ports->midi_output_port ();
}
boost::shared_ptr<MidiPort>
Session::midi_clock_output_port () const
{
return _midi_ports->midi_clock_output_port ();
}
boost::shared_ptr<MidiPort>
Session::midi_clock_input_port () const
{
return _midi_ports->midi_clock_input_port ();
}
boost::shared_ptr<MidiPort>
Session::mtc_output_port () const
{
return _midi_ports->mtc_output_port ();
}
boost::shared_ptr<MidiPort>
Session::mtc_input_port () const
{
return _midi_ports->mtc_input_port ();
}
MIDI::Port*
Session::mmc_output_port () const
{
return _midi_ports->mmc_output_port ();
}
MIDI::Port*
Session::mmc_input_port () const
{
return _midi_ports->mmc_input_port ();
}

View File

@@ -40,7 +40,6 @@
#include "ardour/ticker.h"
#include "ardour/types.h"
#include "midi++/manager.h"
#include "midi++/mmc.h"
#include "i18n.h"
@@ -85,7 +84,7 @@ Session::process (pframes_t nframes)
try {
if (!_engine.freewheeling() && Config->get_send_midi_clock() && transport_speed() == 1.0f && midi_clock->has_midi_port()) {
midi_clock->tick (transport_at_start);
midi_clock->tick (transport_at_start, nframes);
}
} catch (...) {
/* don't bother with a message */
@@ -325,7 +324,7 @@ Session::process_with_events (pframes_t nframes)
* and prepare for rolling)
*/
if (_send_timecode_update) {
send_full_time_code (_transport_frame);
send_full_time_code (_transport_frame, nframes);
}
if (!process_can_proceed()) {

View File

@@ -1,5 +1,5 @@
/*
Copyright (C) 1999-2002 Paul Davis
Copyright (C) 1999-2013 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
@@ -60,7 +60,6 @@
#include "midi++/mmc.h"
#include "midi++/port.h"
#include "midi++/manager.h"
#include "evoral/SMF.hpp"
@@ -87,6 +86,7 @@
#include "ardour/control_protocol_manager.h"
#include "ardour/directory_names.h"
#include "ardour/filename_extensions.h"
#include "ardour/graph.h"
#include "ardour/location.h"
#include "ardour/midi_model.h"
#include "ardour/midi_patch_manager.h"
@@ -125,15 +125,16 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
/** @param snapshot_name Snapshot name, without the .ardour prefix */
void
Session::first_stage_init (string fullpath, string snapshot_name)
Session::pre_engine_init (string fullpath)
{
if (fullpath.length() == 0) {
if (fullpath.empty()) {
destroy ();
throw failed_constructor();
}
/* discover canonical fullpath */
char buf[PATH_MAX+1];
if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
error << string_compose(_("Could not use path %1 (%2)"), buf, strerror(errno)) << endmsg;
@@ -142,102 +143,29 @@ Session::first_stage_init (string fullpath, string snapshot_name)
}
_path = string(buf);
/* we require _path to end with a dir separator */
if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
_path += G_DIR_SEPARATOR;
}
/* these two are just provisional settings. set_state()
will likely override them.
/* is it new ? */
_is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
/* finish initialization that can't be done in a normal C++ constructor
definition.
*/
_name = _current_snapshot_name = snapshot_name;
set_history_depth (Config->get_history_depth());
_current_frame_rate = _engine.frame_rate ();
_nominal_frame_rate = _current_frame_rate;
_base_frame_rate = _current_frame_rate;
_tempo_map = new TempoMap (_current_frame_rate);
_tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
_non_soloed_outs_muted = false;
_listen_cnt = 0;
_solo_isolated_cnt = 0;
timerclear (&last_mmc_step);
g_atomic_int_set (&processing_prohibited, 0);
_transport_speed = 0;
_default_transport_speed = 1.0;
_last_transport_speed = 0;
_target_transport_speed = 0;
auto_play_legal = false;
transport_sub_state = 0;
_transport_frame = 0;
_requested_return_frame = -1;
_session_range_location = 0;
g_atomic_int_set (&_record_status, Disabled);
loop_changing = false;
play_loop = false;
have_looped = false;
_last_roll_location = 0;
_last_roll_or_reversal_location = 0;
_last_record_location = 0;
pending_locate_frame = 0;
pending_locate_roll = false;
pending_locate_flush = false;
state_was_pending = false;
set_next_event ();
outbound_mtc_timecode_frame = 0;
next_quarter_frame_to_send = -1;
current_block_size = 0;
solo_update_disabled = false;
_have_captured = false;
_worst_output_latency = 0;
_worst_input_latency = 0;
_worst_track_latency = 0;
_state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
_was_seamless = Config->get_seamless_loop ();
_slave = 0;
_send_qf_mtc = false;
_pframes_since_last_mtc = 0;
g_atomic_int_set (&_playback_load, 100);
g_atomic_int_set (&_capture_load, 100);
_play_range = false;
_exporting = false;
pending_abort = false;
_adding_routes_in_progress = false;
destructive_index = 0;
first_file_data_format_reset = true;
first_file_header_format_reset = true;
post_export_sync = false;
midi_control_ui = 0;
_step_editors = 0;
no_questions_about_missing_files = false;
_speakers.reset (new Speakers);
_clicks_cleared = 0;
ignore_route_processor_changes = false;
_pre_export_mmc_enabled = false;
AudioDiskstream::allocate_working_buffers();
/* default short fade = 15ms */
SndFileSource::setup_standard_crossfades (*this, frame_rate());
last_mmc_step.tv_sec = 0;
last_mmc_step.tv_usec = 0;
step_speed = 0.0;
/* click sounds are unset by default, which causes us to internal
waveforms for clicks.
*/
click_length = 0;
click_emphasis_length = 0;
_clicking = false;
process_function = &Session::process_with_events;
set_next_event ();
_all_route_group->set_active (true, this);
interpolation.add_channel_to (0, 0);
if (config.get_use_video_sync()) {
waiting_for_sync_offset = true;
@@ -245,32 +173,19 @@ Session::first_stage_init (string fullpath, string snapshot_name)
waiting_for_sync_offset = false;
}
last_timecode_when = 0;
last_timecode_valid = false;
sync_time_vars ();
last_rr_session_dir = session_dirs.begin();
refresh_disk_space ();
set_history_depth (Config->get_history_depth());
/* default: assume simple stereo speaker configuration */
_speakers->setup_default_speakers (2);
/* slave stuff */
average_slave_delta = 1800; // !!! why 1800 ????
have_first_delta_accumulator = false;
delta_accumulator_cnt = 0;
_slave_state = Stopped;
_solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
add_controllable (_solo_cut_control);
_engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
/* These are all static "per-class" signals */
SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
@@ -283,87 +198,108 @@ Session::first_stage_init (string fullpath, string snapshot_name)
Delivery::disable_panners ();
IO::disable_connecting ();
AudioFileSource::set_peak_dir (_session_dir->peak_path());
}
int
Session::second_stage_init ()
Session::post_engine_init ()
{
AudioFileSource::set_peak_dir (_session_dir->peak_path());
BootMessage (_("Set block size and sample rate"));
if (!_is_new) {
if (load_state (_current_snapshot_name)) {
return -1;
}
set_block_size (_engine.samples_per_cycle());
set_frame_rate (_engine.sample_rate());
if (how_many_dsp_threads () > 1) {
/* For now, only create the graph if we are using >1 DSP threads, as
it is a bit slower than the old code with 1 thread.
*/
_process_graph.reset (new Graph (*this));
}
n_physical_outputs = _engine.n_physical_outputs ();
n_physical_inputs = _engine.n_physical_inputs ();
BootMessage (_("Using configuration"));
_midi_ports = new MidiPortManager;
setup_midi_machine_control ();
if (_butler->start_thread()) {
return -1;
}
if (start_midi_thread ()) {
return -1;
}
setup_midi_machine_control ();
// set_state() will call setup_raid_path(), but if it's a new session we need
// to call setup_raid_path() here.
if (state_tree) {
if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
return -1;
}
} else {
setup_raid_path(_path);
}
/* we can't save till after ::when_engine_running() is called,
because otherwise we save state with no connections made.
therefore, we reset _state_of_the_state because ::set_state()
will have cleared it.
we also have to include Loading so that any events that get
generated between here and the end of ::when_engine_running()
will be processed directly rather than queued.
*/
_state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
_locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
_locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
setup_click_sounds (0);
setup_midi_control ();
/* Pay attention ... */
_engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
_engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
midi_clock = new MidiClockTicker ();
midi_clock->set_session (this);
try {
/* tempo map requires sample rate knowledge */
_tempo_map = new TempoMap (_current_frame_rate);
_tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
/* MidiClock requires a tempo map */
midi_clock = new MidiClockTicker ();
midi_clock->set_session (this);
/* crossfades require sample rate knowledge */
SndFileSource::setup_standard_crossfades (*this, frame_rate());
_engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
AudioDiskstream::allocate_working_buffers();
refresh_disk_space ();
/* we're finally ready to call set_state() ... all objects have
* been created, the engine is running.
*/
if (state_tree) {
if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
return -1;
}
} else {
// set_state() will call setup_raid_path(), but if it's a new session we need
// to call setup_raid_path() here.
setup_raid_path (_path);
}
/* ENGINE */
boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
Config->map_parameters (ff);
config.map_parameters (ft);
when_engine_running ();
}
/* handle this one in a different way than all others, so that its clear what happened */
catch (AudioEngine::PortRegistrationFailure& err) {
_locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
_locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
} catch (AudioEngine::PortRegistrationFailure& err) {
/* handle this one in a different way than all others, so that its clear what happened */
error << err.what() << endmsg;
return -1;
}
catch (...) {
} catch (...) {
return -1;
}
BootMessage (_("Reset Remote Controls"));
send_full_time_code (0);
// send_full_time_code (0);
_engine.transport_locate (0);
MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
_mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
_mmc->send (MIDI::MachineControlCommand (Timecode::Time ()));
MIDI::Name::MidiPatchManager::instance().set_session (this);
@@ -376,14 +312,14 @@ Session::second_stage_init ()
DirtyChanged (); /* EMIT SIGNAL */
if (state_was_pending) {
save_state (_current_snapshot_name);
if (_is_new) {
save_state ("");
} else if (state_was_pending) {
save_state ("");
remove_pending_capture_state ();
state_was_pending = false;
}
BootMessage (_("Session loading complete"));
return 0;
}
@@ -610,8 +546,6 @@ Session::create (const string& session_template, BusProfile* bus_profile)
add_monitor_section ();
}
save_state ("");
return 0;
}
@@ -690,62 +624,6 @@ Session::remove_state (string snapshot_name)
}
}
#ifdef HAVE_JACK_SESSION
void
Session::jack_session_event (jack_session_event_t * event)
{
char timebuf[128], *tmp;
time_t n;
struct tm local_time;
time (&n);
localtime_r (&n, &local_time);
strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
while ((tmp = strchr(timebuf, ':'))) { *tmp = '.'; }
if (event->type == JackSessionSaveTemplate)
{
if (save_template( timebuf )) {
event->flags = JackSessionSaveError;
} else {
string cmd ("ardour3 -P -U ");
cmd += event->client_uuid;
cmd += " -T ";
cmd += timebuf;
event->command_line = strdup (cmd.c_str());
}
}
else
{
if (save_state (timebuf)) {
event->flags = JackSessionSaveError;
} else {
std::string xml_path (_session_dir->root_path());
std::string legalized_filename = legalize_for_path (timebuf) + statefile_suffix;
xml_path = Glib::build_filename (xml_path, legalized_filename);
string cmd ("ardour3 -P -U ");
cmd += event->client_uuid;
cmd += " \"";
cmd += xml_path;
cmd += '\"';
event->command_line = strdup (cmd.c_str());
}
}
jack_session_reply (_engine.jack(), event);
if (event->type == JackSessionSaveAndQuit) {
Quit (); /* EMIT SIGNAL */
}
jack_session_event_free( event );
}
#endif
/** @param snapshot_name Name to save under, without .ardour / .pending prefix */
int
Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
@@ -1040,6 +918,15 @@ Session::state (bool full_state)
/* various options */
list<XMLNode*> midi_port_nodes = _midi_ports->get_midi_port_states();
if (!midi_port_nodes.empty()) {
XMLNode* midi_port_stuff = new XMLNode ("MIDIPorts");
for (list<XMLNode*>::const_iterator n = midi_port_nodes.begin(); n != midi_port_nodes.end(); ++n) {
midi_port_stuff->add_child_nocopy (**n);
}
node->add_child_nocopy (*midi_port_stuff);
}
node->add_child_nocopy (config.get_variables ());
node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
@@ -1245,6 +1132,11 @@ Session::set_state (const XMLNode& node, int version)
Evoral::init_event_id_counter (atoi (prop->value()));
}
if ((child = find_named_node (node, "MIDIPorts")) != 0) {
_midi_ports->set_midi_port_states (child->children());
}
IO::disable_connecting ();
Stateful::save_extra_xml (node);
@@ -3421,11 +3313,11 @@ Session::config_changed (std::string p, bool ours)
} else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
_mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
} else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
_mmc->set_send_device_id (Config->get_mmc_send_device_id());
} else if (p == "midi-control") {
@@ -3488,7 +3380,7 @@ Session::config_changed (std::string p, bool ours)
} else if (p == "send-mmc") {
MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
_mmc->enable_send (Config->get_send_mmc ());
} else if (p == "midi-feedback") {
@@ -3546,13 +3438,13 @@ Session::config_changed (std::string p, bool ours)
} else if (p == "initial-program-change") {
if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
if (_mmc->output_port() && Config->get_initial_program_change() >= 0) {
MIDI::byte buf[2];
buf[0] = MIDI::program; // channel zero by default
buf[1] = (Config->get_initial_program_change() & 0x7f);
MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
_mmc->output_port()->midimsg (buf, sizeof (buf), 0);
}
} else if (p == "solo-mute-override") {
// catch_up_on_solo_mute_override ();
@@ -3616,27 +3508,28 @@ Session::load_diskstreams_2X (XMLNode const & node, int)
void
Session::setup_midi_machine_control ()
{
MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
_mmc = new MIDI::MachineControl;
_mmc->set_ports (_midi_ports->mmc_input_port(), _midi_ports->mmc_output_port());
mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
_mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
_mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
_mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
_mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
_mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
_mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
_mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
_mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
_mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
_mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
_mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
_mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
_mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
/* also handle MIDI SPP because its so common */
mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
_mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
_mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
_mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
}
boost::shared_ptr<Controllable>

View File

@@ -180,31 +180,30 @@ Session::timecode_time (Timecode::Time &t)
}
int
Session::jack_sync_callback (jack_transport_state_t state,
jack_position_t* pos)
Session::backend_sync_callback (TransportState state, framepos_t pos)
{
bool slave = synced_to_jack();
switch (state) {
case JackTransportStopped:
if (slave && _transport_frame != pos->frame && post_transport_work() == 0) {
request_locate (pos->frame, false);
case TransportStopped:
if (slave && _transport_frame != pos && post_transport_work() == 0) {
request_locate (pos, false);
// cerr << "SYNC: stopped, locate to " << pos->frame << " from " << _transport_frame << endl;
return false;
} else {
return true;
}
case JackTransportStarting:
case TransportStarting:
// cerr << "SYNC: starting @ " << pos->frame << " a@ " << _transport_frame << " our work = " << post_transport_work() << " pos matches ? " << (_transport_frame == pos->frame) << endl;
if (slave) {
return _transport_frame == pos->frame && post_transport_work() == 0;
return _transport_frame == pos && post_transport_work() == 0;
} else {
return true;
}
break;
case JackTransportRolling:
case TransportRolling:
// cerr << "SYNC: rolling slave = " << slave << endl;
if (slave) {
start_transport ();
@@ -212,93 +211,13 @@ Session::jack_sync_callback (jack_transport_state_t state,
break;
default:
error << string_compose (_("Unknown JACK transport state %1 in sync callback"), state)
error << string_compose (_("Unknown transport state %1 in sync callback"), state)
<< endmsg;
}
return true;
}
void
Session::jack_timebase_callback (jack_transport_state_t /*state*/,
pframes_t /*nframes*/,
jack_position_t* pos,
int /*new_position*/)
{
Timecode::BBT_Time bbt;
/* BBT info */
if (_tempo_map) {
TempoMetric metric (_tempo_map->metric_at (_transport_frame));
try {
_tempo_map->bbt_time_rt (_transport_frame, bbt);
pos->bar = bbt.bars;
pos->beat = bbt.beats;
pos->tick = bbt.ticks;
// XXX still need to set bar_start_tick
pos->beats_per_bar = metric.meter().divisions_per_bar();
pos->beat_type = metric.meter().note_divisor();
pos->ticks_per_beat = Timecode::BBT_Time::ticks_per_beat;
pos->beats_per_minute = metric.tempo().beats_per_minute();
pos->valid = jack_position_bits_t (pos->valid | JackPositionBBT);
} catch (...) {
/* no message */
}
}
#ifdef HAVE_JACK_VIDEO_SUPPORT
//poke audio video ratio so Ardour can track Video Sync
pos->audio_frames_per_video_frame = frame_rate() / timecode_frames_per_second();
pos->valid = jack_position_bits_t (pos->valid | JackAudioVideoRatio);
#endif
#if 0
/* Timecode info */
pos->timecode_offset = config.get_timecode_offset();
t.timecode_frame_rate = timecode_frames_per_second();
pos->valid = jack_position_bits_t (pos->valid | JackPositionTimecode;
if (_transport_speed) {
if (play_loop) {
Location* location = _locations.auto_loop_location();
if (location) {
t.transport_state = JackTransportLooping;
t.loop_start = location->start();
t.loop_end = location->end();
t.valid = jack_transport_bits_t (t.valid | JackTransportLoop);
} else {
t.loop_start = 0;
t.loop_end = 0;
t.transport_state = JackTransportRolling;
}
} else {
t.loop_start = 0;
t.loop_end = 0;
t.transport_state = JackTransportRolling;
}
}
#endif
}
ARDOUR::framecnt_t
Session::convert_to_frames (AnyTime const & position)

View File

@@ -33,7 +33,6 @@
#include "midi++/mmc.h"
#include "midi++/port.h"
#include "midi++/manager.h"
#include "ardour/audioengine.h"
#include "ardour/auditioner.h"
@@ -610,11 +609,23 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
have_looped = false;
if (!_engine.freewheeling()) {
send_full_time_code (_transport_frame);
/* don't bother with this stuff if we're disconnected from the engine,
because there will be no process callbacks to deliver stuff from
*/
if (_engine.connected() && !_engine.freewheeling()) {
// need to queue this in the next RT cycle
_send_timecode_update = true;
if (!dynamic_cast<MTC_Slave*>(_slave)) {
MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdStop));
_mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdStop));
/* This (::non_realtime_stop()) gets called by main
process thread, which will lead to confusion
when calling AsyncMIDIPort::write().
Something must be done. XXX
*/
send_mmc_locate (_transport_frame);
}
}
@@ -1260,7 +1271,7 @@ Session::start_transport ()
Timecode::Time time;
timecode_time_subframes (_transport_frame, time);
if (!dynamic_cast<MTC_Slave*>(_slave)) {
MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay));
_mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdDeferredPlay));
}
}
@@ -1338,8 +1349,9 @@ Session::use_sync_source (Slave* new_slave)
_slave = new_slave;
DEBUG_TRACE (DEBUG::Slave, string_compose ("set new slave to %1\n", _slave));
send_full_time_code (_transport_frame);
// need to queue this for next process() cycle
_send_timecode_update = true;
boost::shared_ptr<RouteList> rl = routes.reader();
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
@@ -1380,7 +1392,7 @@ Session::switch_to_sync_source (SyncSource src)
}
try {
new_slave = new MTC_Slave (*this, *MIDI::Manager::instance()->mtc_input_port());
new_slave = new MTC_Slave (*this, *_midi_ports->mtc_input_port());
}
catch (failed_constructor& err) {
@@ -1409,7 +1421,7 @@ Session::switch_to_sync_source (SyncSource src)
}
try {
new_slave = new MIDIClock_Slave (*this, *MIDI::Manager::instance()->midi_clock_input_port(), 24);
new_slave = new MIDIClock_Slave (*this, *_midi_ports->midi_clock_input_port(), 24);
}
catch (failed_constructor& err) {
@@ -1426,7 +1438,7 @@ Session::switch_to_sync_source (SyncSource src)
return;
}
new_slave = new JACK_Slave (_engine.jack());
new_slave = new JACK_Slave (*AudioEngine::instance());
break;
default:
@@ -1616,16 +1628,6 @@ Session::allow_auto_play (bool yn)
auto_play_legal = yn;
}
void
Session::reset_jack_connection (jack_client_t* jack)
{
JACK_Slave* js;
if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
js->reset_client (jack);
}
}
bool
Session::maybe_stop (framepos_t limit)
{
@@ -1646,7 +1648,7 @@ Session::send_mmc_locate (framepos_t t)
if (!_engine.freewheeling()) {
Timecode::Time time;
timecode_time_subframes (t, time);
MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (time));
_mmc->send (MIDI::MachineControlCommand (time));
}
}

View File

@@ -50,13 +50,13 @@ SlaveSessionProxy::transport_frame() const
pframes_t
SlaveSessionProxy::frames_since_cycle_start() const
{
return session.engine().frames_since_cycle_start();
return session.engine().samples_since_cycle_start();
}
framepos_t
SlaveSessionProxy::frame_time() const
{
return session.engine().frame_time();
return session.engine().sample_time();
}
void

View File

@@ -19,13 +19,12 @@
#include "pbd/compose.h"
#include "pbd/stacktrace.h"
#include "midi++/port.h"
#include "midi++/jack_midi_port.h"
#include "midi++/manager.h"
#include "evoral/midi_events.h"
#include "ardour/async_midi_port.h"
#include "ardour/audioengine.h"
#include "ardour/midi_buffer.h"
#include "ardour/midi_port.h"
#include "ardour/ticker.h"
#include "ardour/session.h"
#include "ardour/tempo.h"
@@ -95,16 +94,16 @@ public:
MidiClockTicker::MidiClockTicker ()
: _midi_port (0)
, _ppqn (24)
: _ppqn (24)
, _last_tick (0.0)
, _send_pos (false)
, _send_state (false)
{
_pos.reset (new Position());
}
MidiClockTicker::~MidiClockTicker()
{
_midi_port = 0;
_pos.reset (0);
}
@@ -115,7 +114,6 @@ MidiClockTicker::set_session (Session* s)
if (_session) {
_session->TransportStateChange.connect_same_thread (_session_connections, boost::bind (&MidiClockTicker::transport_state_changed, this));
_session->PositionChanged.connect_same_thread (_session_connections, boost::bind (&MidiClockTicker::position_changed, this, _1));
_session->TransportLooped.connect_same_thread (_session_connections, boost::bind (&MidiClockTicker::transport_looped, this));
_session->Located.connect_same_thread (_session_connections, boost::bind (&MidiClockTicker::session_located, this));
@@ -139,41 +137,20 @@ MidiClockTicker::session_located()
return;
}
if (_pos->speed == 0.0f) {
uint32_t where = llrint (_pos->midi_beats);
send_position_event (where, 0);
} else if (_pos->speed == 1.0f) {
#if 1
/* Experimental. To really do this and have accuracy, the
stop/locate/continue sequence would need queued to send immediately
before the next midi clock. */
send_stop_event (0);
if (_pos->frame == 0) {
send_start_event (0);
} else {
uint32_t where = llrint (_pos->midi_beats);
send_position_event (where, 0);
send_continue_event (0);
}
#endif
} else {
/* Varispeed not supported */
}
_send_pos = true;
}
void
MidiClockTicker::session_going_away ()
{
SessionHandlePtr::session_going_away();
_midi_port = 0;
_midi_port.reset ();
}
void
MidiClockTicker::update_midi_clock_port()
{
_midi_port = MIDI::Manager::instance()->midi_clock_output_port();
_midi_port = _session->midi_clock_output_port();
}
void
@@ -204,48 +181,11 @@ MidiClockTicker::transport_state_changed()
return;
}
if (_pos->speed == 1.0f) {
if (_session->get_play_loop()) {
assert(_session->locations()->auto_loop_location());
if (_pos->frame == _session->locations()->auto_loop_location()->start()) {
send_start_event(0);
} else {
send_continue_event(0);
}
} else if (_pos->frame == 0) {
send_start_event(0);
} else {
send_continue_event(0);
}
// send_midi_clock_event (0);
} else if (_pos->speed == 0.0f) {
send_stop_event (0);
send_position_event (llrint (_pos->midi_beats), 0);
}
_send_state = true;
// tick (_pos->frame);
}
void
MidiClockTicker::position_changed (framepos_t)
{
#if 0
const double speed = _session->transport_speed();
DEBUG_TRACE (DEBUG::MidiClock, string_compose ("Transport Position Change: %1, speed: %2\n", position, speed));
if (speed == 0.0f && Config->get_send_midi_clock()) {
send_position_event (position, 0);
}
_last_tick = position;
#endif
}
void
MidiClockTicker::transport_looped()
{
@@ -270,18 +210,68 @@ MidiClockTicker::transport_looped()
}
void
MidiClockTicker::tick (const framepos_t& /* transport_frame */)
MidiClockTicker::tick (const framepos_t& /* transport_frame */, pframes_t nframes)
{
if (!Config->get_send_midi_clock() || _session == 0 || _session->transport_speed() != 1.0f || _midi_port == 0) {
return;
}
MIDI::JackMIDIPort* mp = dynamic_cast<MIDI::JackMIDIPort*> (_midi_port);
if (! mp) {
return;
if (_send_pos) {
if (_pos->speed == 0.0f) {
uint32_t where = llrint (_pos->midi_beats);
send_position_event (where, 0, nframes);
} else if (_pos->speed == 1.0f) {
#if 1
/* Experimental. To really do this and have accuracy, the
stop/locate/continue sequence would need queued to send immediately
before the next midi clock. */
send_stop_event (0, nframes);
if (_pos->frame == 0) {
send_start_event (0, nframes);
} else {
uint32_t where = llrint (_pos->midi_beats);
send_position_event (where, 0, nframes);
send_continue_event (0, nframes);
}
#endif
} else {
/* Varispeed not supported */
}
_send_pos = true;
}
const framepos_t end = _pos->frame + mp->nframes_this_cycle();
if (_send_state) {
if (_pos->speed == 1.0f) {
if (_session->get_play_loop()) {
assert(_session->locations()->auto_loop_location());
if (_pos->frame == _session->locations()->auto_loop_location()->start()) {
send_start_event (0, nframes);
} else {
send_continue_event (0, nframes);
}
} else if (_pos->frame == 0) {
send_start_event (0, nframes);
} else {
send_continue_event (0, nframes);
}
// send_midi_clock_event (0);
} else if (_pos->speed == 0.0f) {
send_stop_event (0, nframes);
send_position_event (llrint (_pos->midi_beats), 0, nframes);
}
_send_state = false;
}
const framepos_t end = _pos->frame + nframes;
double iter = _last_tick;
while (true) {
@@ -291,14 +281,14 @@ MidiClockTicker::tick (const framepos_t& /* transport_frame */)
DEBUG_TRACE (DEBUG::MidiClock,
string_compose ("Tick: iter: %1, last tick time: %2, next tick time: %3, offset: %4, cycle length: %5\n",
iter, _last_tick, next_tick, next_tick_offset, mp ? mp->nframes_this_cycle() : 0));
iter, _last_tick, next_tick, next_tick_offset, nframes));
if (!mp || (next_tick_offset >= mp->nframes_this_cycle())) {
if (next_tick_offset >= nframes) {
break;
}
if (next_tick_offset >= 0) {
send_midi_clock_event (next_tick_offset);
send_midi_clock_event (next_tick_offset, nframes);
}
iter = next_tick;
@@ -308,7 +298,6 @@ MidiClockTicker::tick (const framepos_t& /* transport_frame */)
_pos->frame = end;
}
double
MidiClockTicker::one_ppqn_in_frames (framepos_t transport_position)
{
@@ -322,7 +311,7 @@ MidiClockTicker::one_ppqn_in_frames (framepos_t transport_position)
}
void
MidiClockTicker::send_midi_clock_event (pframes_t offset)
MidiClockTicker::send_midi_clock_event (pframes_t offset, pframes_t nframes)
{
if (!_midi_port) {
return;
@@ -330,12 +319,13 @@ MidiClockTicker::send_midi_clock_event (pframes_t offset)
DEBUG_TRACE (DEBUG::MidiClock, string_compose ("Tick with offset %1\n", offset));
static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_CLOCK };
_midi_port->write (_midi_clock_tick, 1, offset);
static uint8_t tick_byte = { MIDI_CMD_COMMON_CLOCK };
MidiBuffer& mb (_midi_port->get_midi_buffer (nframes));
mb.push_back (offset, 1, &tick_byte);
}
void
MidiClockTicker::send_start_event (pframes_t offset)
MidiClockTicker::send_start_event (pframes_t offset, pframes_t nframes)
{
if (!_midi_port) {
return;
@@ -343,12 +333,13 @@ MidiClockTicker::send_start_event (pframes_t offset)
DEBUG_TRACE (DEBUG::MidiClock, string_compose ("Start %1\n", _last_tick));
static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_START };
_midi_port->write (_midi_clock_tick, 1, offset);
static uint8_t tick_byte = { MIDI_CMD_COMMON_START };
MidiBuffer& mb (_midi_port->get_midi_buffer (nframes));
mb.push_back (offset, 1, &tick_byte);
}
void
MidiClockTicker::send_continue_event (pframes_t offset)
MidiClockTicker::send_continue_event (pframes_t offset, pframes_t nframes)
{
if (!_midi_port) {
return;
@@ -356,12 +347,13 @@ MidiClockTicker::send_continue_event (pframes_t offset)
DEBUG_TRACE (DEBUG::MidiClock, string_compose ("Continue %1\n", _last_tick));
static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_CONTINUE };
_midi_port->write (_midi_clock_tick, 1, offset);
static uint8_t tick_byte = { MIDI_CMD_COMMON_CONTINUE };
MidiBuffer& mb (_midi_port->get_midi_buffer (nframes));
mb.push_back (offset, 1, &tick_byte);
}
void
MidiClockTicker::send_stop_event (pframes_t offset)
MidiClockTicker::send_stop_event (pframes_t offset, pframes_t nframes)
{
if (!_midi_port) {
return;
@@ -369,12 +361,13 @@ MidiClockTicker::send_stop_event (pframes_t offset)
DEBUG_TRACE (DEBUG::MidiClock, string_compose ("Stop %1\n", _last_tick));
static uint8_t _midi_clock_tick[1] = { MIDI_CMD_COMMON_STOP };
_midi_port->write (_midi_clock_tick, 1, offset);
static uint8_t tick_byte = { MIDI_CMD_COMMON_STOP };
MidiBuffer& mb (_midi_port->get_midi_buffer (nframes));
mb.push_back (offset, 1, &tick_byte);
}
void
MidiClockTicker::send_position_event (uint32_t midi_beats, pframes_t offset)
MidiClockTicker::send_position_event (uint32_t midi_beats, pframes_t offset, pframes_t nframes)
{
if (!_midi_port) {
return;
@@ -391,7 +384,8 @@ MidiClockTicker::send_position_event (uint32_t midi_beats, pframes_t offset)
msg[1] = midi_beats & 0x007f;
msg[2] = midi_beats >> 7;
_midi_port->midimsg (msg, sizeof (msg), offset);
MidiBuffer& mb (_midi_port->get_midi_buffer (nframes));
mb.push_back (offset, 3, &msg[0]);
DEBUG_TRACE (DEBUG::MidiClock, string_compose ("Song Position Sent: %1\n", midi_beats));
}

View File

@@ -550,15 +550,15 @@ Track::playlist ()
}
void
Track::request_jack_monitors_input (bool m)
Track::request_input_monitoring (bool m)
{
_diskstream->request_jack_monitors_input (m);
_diskstream->request_input_monitoring (m);
}
void
Track::ensure_jack_monitors_input (bool m)
Track::ensure_input_monitoring (bool m)
{
_diskstream->ensure_jack_monitors_input (m);
_diskstream->ensure_input_monitoring (m);
}
bool

View File

@@ -43,8 +43,8 @@ void Vumeterdsp::process (float *p, int n)
{
float z1, z2, m, t1, t2;
z1 = _z1;
z2 = _z2;
z1 = _z1 > 20 ? 20 : (_z1 < -20 ? -20 : _z1);
z2 = _z2 > 20 ? 20 : (_z2 < -20 ? -20 : _z2);
m = _res ? 0: _m;
_res = false;
@@ -64,6 +64,8 @@ void Vumeterdsp::process (float *p, int n)
if (z2 > m) m = z2;
}
if (isnan(z1)) z1 = 0;
if (isnan(z2)) z2 = 0;
_z1 = z1;
_z2 = z2 + 1e-10f;
_m = m;

View File

@@ -1,9 +1,10 @@
#!/usr/bin/env python
1#!/usr/bin/env python
from waflib.extras import autowaf as autowaf
from waflib import Options
import os
import re
import subprocess
import sys
# default state file version for this build
CURRENT_SESSION_FILE_VERSION = 3001
@@ -21,6 +22,7 @@ path_prefix = 'libs/ardour/'
libardour_sources = [
'amp.cc',
'analyser.cc',
'async_midi_port.cc',
'audio_buffer.cc',
'audio_diskstream.cc',
'audio_library.cc',
@@ -43,6 +45,7 @@ libardour_sources = [
'automation_control.cc',
'automation_list.cc',
'automation_watch.cc',
'backend_search_path.cc',
'beats_frames_converter.cc',
'broadcast_info.cc',
'buffer.cc',
@@ -125,6 +128,7 @@ libardour_sources = [
'midi_stretch.cc',
'midi_track.cc',
'midi_ui.cc',
'midiport_manager.cc',
'mix.cc',
'monitor_processor.cc',
'mtc_slave.cc',
@@ -148,6 +152,7 @@ libardour_sources = [
'plugin_manager.cc',
'port.cc',
'port_insert.cc',
'port_manager.cc',
'port_set.cc',
'process_thread.cc',
'processor.cc',
@@ -175,6 +180,7 @@ libardour_sources = [
'session_events.cc',
'session_export.cc',
'session_handle.cc',
'session_jack.cc',
'session_ltc.cc',
'session_metadata.cc',
'session_midi.cc',
@@ -249,6 +255,10 @@ def configure(conf):
atleast_version='0.1.0')
autowaf.check_pkg(conf, 'sigc++-2.0', uselib_store='SIGCPP',
atleast_version='2.0')
if re.search ("linux", sys.platform) != None:
autowaf.check_pkg(conf, 'alsa', uselib_store='ALSA')
if Options.options.lv2:
autowaf.check_pkg(conf, 'lv2', uselib_store='LV2',
atleast_version='1.0.0', mandatory=True)
@@ -293,60 +303,6 @@ def configure(conf):
conf.check(header_name='unistd.h', define_name='HAVE_UNISTD',mandatory=False)
conf.check_cc(fragment = '''
#include <jack/jack.h>
void callback(jack_status_t code, const char* reason, void* arg) { return; }
int main(int argc, char **argv) {
jack_client_t* c;
jack_on_info_shutdown(c, callback, (void*) 0);
return 0;
}''',
uselib= [ 'JACK' ],
msg = 'Checking for jack_on_info_shutdown',
define_name = 'HAVE_JACK_ON_INFO_SHUTDOWN',
okmsg = 'present')
missing_jack_message = 'missing - a version of JACK that supports jack_port_set_latency_range() is required to compile Ardour3.'
conf.check_cc(fragment = '''
#include <jack/jack.h>
int main(int argc, char **argv) {
jack_port_t* p;
jack_latency_range_t r;
jack_port_set_latency_range(p, JackCaptureLatency, &r);
return 0;
}''',
uselib = [ 'JACK' ],
msg = 'Checking for new JACK latency API',
okmsg = 'present',
mandatory = True,
errmsg = missing_jack_message)
conf.check_cc(fragment = '''
#include <jack/jack.h>
int main(int argc, char **argv) {
jack_port_type_get_buffer_size((jack_client_t*)0, "");
return 0;
}''',
uselib = [ 'JACK' ],
msg = 'Checking for new jack_port_type_get_buffer_size',
okmsg = 'present',
mandatory = True,
errmsg = missing_jack_message)
conf.check_cc(fragment = '''
#include <jack/transport.h>
int main(int argc, char** argv) {
jack_position_t pos;
pos.valid & JackVideoFrameOffset;
return 0;
}''',
uselib= [ 'JACK' ],
msg = 'Checking for JackVideoFrameOffset',
define_name = 'HAVE_JACK_VIDEO_SUPPORT',
mandatory = False,
okmsg = 'present')
if flac_supported():
conf.define ('HAVE_FLAC', 1)
if ogg_supported():

View File

@@ -0,0 +1,78 @@
/*
Copyright (C) 2013 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 "jack_connection.h"
#include "jack_audiobackend.h"
using namespace ARDOUR;
static boost::shared_ptr<JACKAudioBackend> backend;
static boost::shared_ptr<JackConnection> jack_connection;
static boost::shared_ptr<AudioBackend>
backend_factory (AudioEngine& ae)
{
if (!jack_connection) {
return boost::shared_ptr<AudioBackend>();
}
if (!backend) {
backend.reset (new JACKAudioBackend (ae, jack_connection));
}
return backend;
}
static int
instantiate (const std::string& arg1, const std::string& arg2)
{
try {
jack_connection.reset (new JackConnection (arg1, arg2));
} catch (...) {
return -1;
}
return 0;
}
static int
deinstantiate ()
{
backend.reset ();
jack_connection.reset ();
return 0;
}
static bool
already_configured ()
{
return JackConnection::server_running ();
}
static ARDOUR::AudioBackendInfo _descriptor = {
"JACK",
instantiate,
deinstantiate,
backend_factory,
already_configured,
};
extern "C" ARDOURBACKEND_API ARDOUR::AudioBackendInfo* descriptor() { return &_descriptor; }

Some files were not shown because too many files have changed in this diff Show More