fix merge conflicts with master
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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__ */
|
||||
444
libs/ardour/ardour/audio_backend.h
Normal file
444
libs/ardour/ardour/audio_backend.h
Normal 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__ */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
39
libs/ardour/ardour/backend_search_path.h
Normal file
39
libs/ardour/ardour/backend_search_path.h
Normal 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__ */
|
||||
@@ -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
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -63,6 +63,7 @@ namespace PBD {
|
||||
extern uint64_t OrderKeys;
|
||||
extern uint64_t Automation;
|
||||
extern uint64_t WiimoteControl;
|
||||
extern uint64_t Ports;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
|
||||
99
libs/ardour/ardour/midiport_manager.h
Normal file
99
libs/ardour/ardour/midiport_manager.h
Normal 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__
|
||||
@@ -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;
|
||||
|
||||
|
||||
345
libs/ardour/ardour/port_engine.h
Normal file
345
libs/ardour/ardour/port_engine.h
Normal 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__ */
|
||||
170
libs/ardour/ardour/port_manager.h
Normal file
170
libs/ardour/ardour/port_manager.h
Normal 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__ */
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
44
libs/ardour/ardour/visibility.h
Normal file
44
libs/ardour/ardour/visibility.h
Normal 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__ */
|
||||
303
libs/ardour/async_midi_port.cc
Normal file
303
libs/ardour/async_midi_port.cc
Normal 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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
45
libs/ardour/backend_search_path.cc
Normal file
45
libs/ardour/backend_search_path.cc
Normal 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
|
||||
@@ -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 ());
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ();
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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))) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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*
|
||||
|
||||
170
libs/ardour/midiport_manager.cc
Normal file
170
libs/ardour/midiport_manager.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -79,6 +79,7 @@ PannerManager::discover_panners ()
|
||||
panner_discover (*i);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
PannerManager::panner_discover (string path)
|
||||
{
|
||||
|
||||
@@ -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)"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)"
|
||||
|
||||
@@ -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 ""
|
||||
|
||||
|
||||
@@ -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)"
|
||||
|
||||
@@ -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...)"
|
||||
|
||||
|
||||
@@ -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)"
|
||||
|
||||
@@ -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)"
|
||||
|
||||
|
||||
@@ -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 ""
|
||||
|
||||
|
||||
@@ -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)"
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
667
libs/ardour/port_manager.cc
Normal 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;
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
185
libs/ardour/session_jack.cc
Normal 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
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 ();
|
||||
}
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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():
|
||||
|
||||
78
libs/backends/jack/jack_api.cc
Normal file
78
libs/backends/jack/jack_api.cc
Normal 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
Reference in New Issue
Block a user