mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-10 08:36:32 +01:00
Large nasty commit in the form of a 5000 line patch chock-full of completely
unecessary changes. (Sorry, doing a "sprint" based thing, this is the end of the first one) Achieved MIDI track and bus creation, associated Jack port and diskstream creation, and minimal GUI stuff for creating them. Should be set to start work on actually recording and playing midi to/from disk now. Relevant (significant) changes: - Creation of a Buffer class. Base class is type agnostic so things can point to a buffer but not care what kind it is (otherwise it'd be a template). Derived into AudioBuffer and MidiBuffer, with a type tag because checking type is necessary in parts of the code where dynamic_cast wouldn't be wise. Originally I considered this a hack, but passing around a type proved to be a very good solution to all the other problems (below). There is a 1:1 mapping between jack port data types and ardour Buffer types (with a conversion function), but that's easily removed if it ever becomes necessary. Having the type scoped in the Buffer class is maybe not the best spot for it, but whatever (this is proof of concept kinda stuff right now...) - IO now has a "default" port type (passed to the constructor and stored as a member), used by ensure_io (and similar) to create n ports. IO::register_***_port has a type argument that defaults to the default type if not passed. Rationale: previous IO API is identical, no changes needed to existing code, but path is paved for multiple port types in one IO, which we will need for eg synth plugin inserts, among other things. This is not quite ideal (best would be to only have the two port register functions and have them take a type), but the alternative is a lot of work (namely destroying the 'ensure' functions and everything that uses them) for very little gain. (I am convinced after quite a few tries at the whiteboard that subclassing IO in any way is not a feasible option, look at it's inheritance diagram in Doxygen and you can see why) - AudioEngine::register_audio_input_port is now register_input_port and takes a type argument. Ditto for output. - (Most significant change) AudioDiskstream abstracted into Distream, and sibling MidiDiskstream created. Very much still a work in progress, but Diskstream is there to switch references over to (most already are), which is the important part. It is still unclear what the MIDI diskstream's relation to channels is, but I'm pretty sure they will be single channel only (so SMF Type 0) since noone can come up with a reason otherwise. - MidiTrack creation. Same thing as AudioTrack but with a different default type basically. No big deal here. - Random cleanups and variable renamings etc. because I have OCD and can't help myself. :) Known broken: Loading of sessions containing MIDI tracks. git-svn-id: svn://localhost/ardour2/branches/midi@641 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
13532c8500
commit
fe13d08874
194 changed files with 2354 additions and 903 deletions
|
|
@ -36,6 +36,13 @@ audiofilesource.cc
|
|||
audiofilter.cc
|
||||
audioregion.cc
|
||||
audiosource.cc
|
||||
diskstream.cc
|
||||
midi_source.cc
|
||||
midi_diskstream.cc
|
||||
midi_playlist.cc
|
||||
midi_track.cc
|
||||
midi_region.cc
|
||||
smf_source.cc
|
||||
auditioner.cc
|
||||
automation.cc
|
||||
automation_event.cc
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ namespace ARDOUR {
|
|||
|
||||
static const jack_nframes_t max_frames = JACK_MAX_FRAMES;
|
||||
|
||||
int init (AudioEngine&, bool with_vst, bool try_optimization, void (*sighandler)(int,siginfo_t*,void*) = 0);
|
||||
int init (AudioEngine&, bool with_vst, bool try_optimization);
|
||||
int cleanup ();
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@
|
|||
$Id: diskstream.h 579 2006-06-12 19:56:37Z essej $
|
||||
*/
|
||||
|
||||
#ifndef __ardour_diskstream_h__
|
||||
#define __ardour_diskstream_h__
|
||||
#ifndef __ardour_audio_diskstream_h__
|
||||
#define __ardour_audio_diskstream_h__
|
||||
|
||||
#include <sigc++/signal.h>
|
||||
|
||||
|
|
@ -42,8 +42,8 @@
|
|||
#include <ardour/route.h>
|
||||
#include <ardour/port.h>
|
||||
#include <ardour/utils.h>
|
||||
#include <ardour/stateful.h>
|
||||
|
||||
#include <ardour/diskstream.h>
|
||||
#include <ardour/audioplaylist.h>
|
||||
struct tm;
|
||||
|
||||
namespace ARDOUR {
|
||||
|
|
@ -55,52 +55,23 @@ class AudioPlaylist;
|
|||
class AudioFileSource;
|
||||
class IO;
|
||||
|
||||
class AudioDiskstream : public Stateful, public sigc::trackable
|
||||
class AudioDiskstream : public Diskstream
|
||||
{
|
||||
public:
|
||||
enum Flag {
|
||||
Recordable = 0x1,
|
||||
Hidden = 0x2,
|
||||
Destructive = 0x4
|
||||
};
|
||||
|
||||
AudioDiskstream (Session &, const string& name, Flag f = Recordable);
|
||||
AudioDiskstream (Session &, const string& name, Diskstream::Flag f = Recordable);
|
||||
AudioDiskstream (Session &, const XMLNode&);
|
||||
|
||||
string name() const { return _name; }
|
||||
|
||||
ARDOUR::IO* io() const { return _io; }
|
||||
void set_io (ARDOUR::IO& io);
|
||||
|
||||
AudioDiskstream& ref() { _refcnt++; return *this; }
|
||||
void unref() { if (_refcnt) _refcnt--; if (_refcnt == 0) delete this; }
|
||||
uint32_t refcnt() const { return _refcnt; }
|
||||
//void unref() { if (_refcnt) _refcnt--; if (_refcnt == 0) delete this; }
|
||||
//uint32_t refcnt() const { return _refcnt; }
|
||||
|
||||
float playback_buffer_load() const;
|
||||
float capture_buffer_load() const;
|
||||
|
||||
void set_flag (Flag f) {
|
||||
_flags |= f;
|
||||
}
|
||||
|
||||
void unset_flag (Flag f) {
|
||||
_flags &= ~f;
|
||||
}
|
||||
|
||||
AlignStyle alignment_style() const { return _alignment_style; }
|
||||
void set_align_style (AlignStyle);
|
||||
void set_persistent_align_style (AlignStyle);
|
||||
|
||||
bool hidden() const { return _flags & Hidden; }
|
||||
bool recordable() const { return _flags & Recordable; }
|
||||
bool destructive() const { return _flags & Destructive; }
|
||||
|
||||
void set_destructive (bool yn);
|
||||
|
||||
jack_nframes_t roll_delay() const { return _roll_delay; }
|
||||
void set_roll_delay (jack_nframes_t);
|
||||
|
||||
int set_name (string str, void* src);
|
||||
//void set_align_style (AlignStyle);
|
||||
//void set_persistent_align_style (AlignStyle);
|
||||
|
||||
string input_source (uint32_t n=0) const {
|
||||
if (n < channels.size()) {
|
||||
|
|
@ -115,13 +86,7 @@ class AudioDiskstream : public Stateful, public sigc::trackable
|
|||
}
|
||||
|
||||
void set_record_enabled (bool yn, void *src);
|
||||
bool record_enabled() const { return g_atomic_int_get (&_record_enabled); }
|
||||
void punch_in ();
|
||||
void punch_out ();
|
||||
|
||||
bool reversed() const { return _actual_speed < 0.0f; }
|
||||
double speed() const { return _visible_speed; }
|
||||
void set_speed (double);
|
||||
//void set_speed (double);
|
||||
|
||||
float peak_power(uint32_t n=0) {
|
||||
float x = channels[n].peak_power;
|
||||
|
|
@ -133,12 +98,14 @@ class AudioDiskstream : public Stateful, public sigc::trackable
|
|||
}
|
||||
}
|
||||
|
||||
int use_playlist (AudioPlaylist *);
|
||||
int use_playlist (Playlist *);
|
||||
int use_new_playlist ();
|
||||
int use_copy_playlist ();
|
||||
|
||||
void start_scrub (jack_nframes_t where);
|
||||
void end_scrub ();
|
||||
void start_scrub (jack_nframes_t where) {} // FIXME?
|
||||
void end_scrub () {} // FIXME?
|
||||
|
||||
Playlist *playlist () { return _playlist; }
|
||||
|
||||
Sample *playback_buffer (uint32_t n=0) {
|
||||
if (n < channels.size())
|
||||
|
|
@ -152,41 +119,16 @@ class AudioDiskstream : public Stateful, public sigc::trackable
|
|||
return 0;
|
||||
}
|
||||
|
||||
AudioPlaylist *playlist () { return _playlist; }
|
||||
|
||||
AudioFileSource *write_source (uint32_t n=0) {
|
||||
if (n < channels.size())
|
||||
return channels[n].write_source;
|
||||
return 0;
|
||||
}
|
||||
|
||||
jack_nframes_t current_capture_start() const { return capture_start_frame; }
|
||||
jack_nframes_t current_capture_end() const { return capture_start_frame + capture_captured; }
|
||||
jack_nframes_t get_capture_start_frame (uint32_t n=0);
|
||||
jack_nframes_t get_captured_frames (uint32_t n=0);
|
||||
|
||||
uint32_t n_channels() { return _n_channels; }
|
||||
|
||||
int add_channel ();
|
||||
int remove_channel ();
|
||||
|
||||
static void set_disk_io_chunk_frames (uint32_t n) {
|
||||
disk_io_chunk_frames = n;
|
||||
}
|
||||
|
||||
static jack_nframes_t disk_io_frames() { return disk_io_chunk_frames; }
|
||||
|
||||
sigc::signal<void,void*> record_enable_changed;
|
||||
sigc::signal<void> speed_changed;
|
||||
sigc::signal<void,void*> reverse_changed;
|
||||
sigc::signal<void> PlaylistChanged;
|
||||
sigc::signal<void> AlignmentStyleChanged;
|
||||
|
||||
static sigc::signal<void> DiskOverrun;
|
||||
static sigc::signal<void> DiskUnderrun;
|
||||
static sigc::signal<void,AudioDiskstream*> AudioDiskstreamCreated; // XXX use a ref with sigc2
|
||||
static sigc::signal<void,list<AudioFileSource*>*> DeleteSources;
|
||||
|
||||
/* stateful */
|
||||
|
||||
XMLNode& get_state(void);
|
||||
|
|
@ -194,9 +136,7 @@ class AudioDiskstream : public Stateful, public sigc::trackable
|
|||
|
||||
void monitor_input (bool);
|
||||
|
||||
jack_nframes_t capture_offset() const { return _capture_offset; }
|
||||
void set_capture_offset ();
|
||||
|
||||
// FIXME: these don't belong here
|
||||
static void swap_by_ptr (Sample *first, Sample *last) {
|
||||
while (first < last) {
|
||||
Sample tmp = *first;
|
||||
|
|
@ -213,21 +153,12 @@ class AudioDiskstream : public Stateful, public sigc::trackable
|
|||
}
|
||||
}
|
||||
|
||||
bool slaved() const { return _slaved; }
|
||||
void set_slaved(bool yn) { _slaved = yn; }
|
||||
|
||||
int set_loop (Location *loc);
|
||||
sigc::signal<void,Location *> LoopSet;
|
||||
|
||||
std::list<Region*>& last_capture_regions () {
|
||||
return _last_capture_regions;
|
||||
}
|
||||
|
||||
void handle_input_change (IOChange, void *src);
|
||||
|
||||
id_t id() const { return _id; }
|
||||
|
||||
XMLNode* deprecated_io_node;
|
||||
//void handle_input_change (IOChange, void *src);
|
||||
|
||||
//static sigc::signal<void> DiskOverrun;
|
||||
//static sigc::signal<void> DiskUnderrun;
|
||||
//static sigc::signal<void,AudioDiskstream*> AudioDiskstreamCreated; // XXX use a ref with sigc2
|
||||
static sigc::signal<void,list<AudioFileSource*>*> DeleteSources;
|
||||
|
||||
protected:
|
||||
friend class Session;
|
||||
|
|
@ -237,9 +168,9 @@ class AudioDiskstream : public Stateful, public sigc::trackable
|
|||
while they are called.
|
||||
*/
|
||||
|
||||
void set_pending_overwrite (bool);
|
||||
void set_pending_overwrite(bool);
|
||||
int overwrite_existing_buffers ();
|
||||
void reverse_scrub_buffer (bool to_forward);
|
||||
void reverse_scrub_buffer (bool to_forward) {} // FIXME?
|
||||
void set_block_size (jack_nframes_t);
|
||||
int internal_playback_seek (jack_nframes_t distance);
|
||||
int can_internal_playback_seek (jack_nframes_t distance);
|
||||
|
|
@ -247,9 +178,6 @@ class AudioDiskstream : public Stateful, public sigc::trackable
|
|||
void reset_write_sources (bool, bool force = false);
|
||||
void non_realtime_input_change ();
|
||||
|
||||
uint32_t read_data_count() const { return _read_data_count; }
|
||||
uint32_t write_data_count() const { return _write_data_count; }
|
||||
|
||||
protected:
|
||||
friend class Auditioner;
|
||||
int seek (jack_nframes_t which_sample, bool complete_refill = false);
|
||||
|
|
@ -257,38 +185,23 @@ class AudioDiskstream : public Stateful, public sigc::trackable
|
|||
protected:
|
||||
friend class AudioTrack;
|
||||
|
||||
void prepare ();
|
||||
int process (jack_nframes_t transport_frame, jack_nframes_t nframes, jack_nframes_t offset, bool can_record, bool rec_monitors_input);
|
||||
bool commit (jack_nframes_t nframes);
|
||||
void recover (); /* called if commit will not be called, but process was */
|
||||
|
||||
private:
|
||||
|
||||
/* use unref() to destroy a diskstream */
|
||||
|
||||
~AudioDiskstream();
|
||||
|
||||
enum TransitionType {
|
||||
CaptureStart = 0,
|
||||
CaptureEnd
|
||||
};
|
||||
|
||||
struct CaptureTransition {
|
||||
|
||||
TransitionType type;
|
||||
// the start or end file frame pos
|
||||
jack_nframes_t capture_val;
|
||||
};
|
||||
|
||||
struct ChannelInfo {
|
||||
|
||||
Sample *playback_wrap_buffer;
|
||||
Sample *capture_wrap_buffer;
|
||||
Sample *speed_buffer;
|
||||
|
||||
float peak_power;
|
||||
float peak_power;
|
||||
|
||||
AudioFileSource *fades_source;
|
||||
AudioFileSource *fades_source;
|
||||
AudioFileSource *write_source;
|
||||
|
||||
Port *source;
|
||||
|
|
@ -312,90 +225,25 @@ class AudioDiskstream : public Stateful, public sigc::trackable
|
|||
|
||||
typedef vector<ChannelInfo> ChannelList;
|
||||
|
||||
|
||||
string _name;
|
||||
ARDOUR::Session& _session;
|
||||
ARDOUR::IO* _io;
|
||||
ChannelList channels;
|
||||
uint32_t _n_channels;
|
||||
id_t _id;
|
||||
|
||||
mutable gint _record_enabled;
|
||||
AudioPlaylist* _playlist;
|
||||
double _visible_speed;
|
||||
double _actual_speed;
|
||||
/* items needed for speed change logic */
|
||||
bool _buffer_reallocation_required;
|
||||
bool _seek_required;
|
||||
|
||||
bool force_refill;
|
||||
jack_nframes_t capture_start_frame;
|
||||
jack_nframes_t capture_captured;
|
||||
bool was_recording;
|
||||
jack_nframes_t adjust_capture_position;
|
||||
jack_nframes_t _capture_offset;
|
||||
jack_nframes_t _roll_delay;
|
||||
jack_nframes_t first_recordable_frame;
|
||||
jack_nframes_t last_recordable_frame;
|
||||
int last_possibly_recording;
|
||||
AlignStyle _alignment_style;
|
||||
bool _scrubbing;
|
||||
bool _slaved;
|
||||
bool _processed;
|
||||
Location* loop_location;
|
||||
jack_nframes_t overwrite_frame;
|
||||
off_t overwrite_offset;
|
||||
bool pending_overwrite;
|
||||
bool overwrite_queued;
|
||||
IOChange input_change_pending;
|
||||
jack_nframes_t wrap_buffer_size;
|
||||
jack_nframes_t speed_buffer_size;
|
||||
|
||||
uint64_t last_phase;
|
||||
uint64_t phi;
|
||||
|
||||
jack_nframes_t file_frame;
|
||||
jack_nframes_t playback_sample;
|
||||
jack_nframes_t playback_distance;
|
||||
|
||||
uint32_t _read_data_count;
|
||||
uint32_t _write_data_count;
|
||||
|
||||
bool in_set_state;
|
||||
AlignStyle _persistent_alignment_style;
|
||||
bool first_input_change;
|
||||
|
||||
Glib::Mutex state_lock;
|
||||
|
||||
jack_nframes_t scrub_start;
|
||||
jack_nframes_t scrub_buffer_size;
|
||||
jack_nframes_t scrub_offset;
|
||||
uint32_t _refcnt;
|
||||
|
||||
sigc::connection ports_created_c;
|
||||
sigc::connection plmod_connection;
|
||||
sigc::connection plstate_connection;
|
||||
sigc::connection plgone_connection;
|
||||
|
||||
/* the two central butler operations */
|
||||
|
||||
int do_flush (char * workbuf, bool force = false);
|
||||
int do_refill (Sample *mixdown_buffer, float *gain_buffer, char *workbuf);
|
||||
|
||||
virtual int non_realtime_do_refill() { return do_refill(0, 0, 0); }
|
||||
|
||||
int read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, char * workbuf, jack_nframes_t& start, jack_nframes_t cnt,
|
||||
ChannelInfo& channel_info, int channel, bool reversed);
|
||||
|
||||
uint32_t i_am_the_modifier;
|
||||
|
||||
/* XXX fix this redundancy ... */
|
||||
|
||||
void playlist_changed (Change);
|
||||
void playlist_modified ();
|
||||
//void playlist_changed (Change);
|
||||
//void playlist_modified ();
|
||||
void playlist_deleted (Playlist*);
|
||||
void session_controls_changed (Session::ControlType);
|
||||
void session_controls_changed (Session::ControlType) {} // FIXME?
|
||||
|
||||
void finish_capture (bool rec_monitors_input);
|
||||
void clean_up_capture (struct tm&, time_t, bool abort);
|
||||
void clean_up_capture (struct tm&, time_t, bool abort) {} // FIXME?
|
||||
void transport_stopped (struct tm&, time_t, bool abort);
|
||||
|
||||
struct CaptureInfo {
|
||||
|
|
@ -406,29 +254,25 @@ class AudioDiskstream : public Stateful, public sigc::trackable
|
|||
vector<CaptureInfo*> capture_info;
|
||||
Glib::Mutex capture_info_lock;
|
||||
|
||||
void init (Flag);
|
||||
void init (Diskstream::Flag);
|
||||
|
||||
void init_channel (ChannelInfo &chan);
|
||||
void destroy_channel (ChannelInfo &chan);
|
||||
|
||||
static jack_nframes_t disk_io_chunk_frames;
|
||||
|
||||
int use_new_write_source (uint32_t n=0);
|
||||
int use_new_fade_source (uint32_t n=0);
|
||||
int use_new_fade_source (uint32_t n=0) { return 0; } // FIXME?
|
||||
|
||||
int find_and_use_playlist (const string&);
|
||||
|
||||
void allocate_temporary_buffers ();
|
||||
|
||||
unsigned char _flags;
|
||||
int create_input_port () { return 0; } // FIXME?
|
||||
int connect_input_port () { return 0; } // FIXME?
|
||||
int seek_unlocked (jack_nframes_t which_sample) { return 0; } // FIXME?
|
||||
|
||||
int create_input_port ();
|
||||
int connect_input_port ();
|
||||
int seek_unlocked (jack_nframes_t which_sample);
|
||||
int ports_created () { return 0; } // FIXME?
|
||||
|
||||
int ports_created ();
|
||||
|
||||
bool realtime_set_speed (double, bool global_change);
|
||||
//bool realtime_set_speed (double, bool global_change);
|
||||
void non_realtime_set_speed ();
|
||||
|
||||
std::list<Region*> _last_capture_regions;
|
||||
|
|
@ -440,8 +284,12 @@ class AudioDiskstream : public Stateful, public sigc::trackable
|
|||
void set_align_style_from_io();
|
||||
void setup_destructive_playlist ();
|
||||
void use_destructive_playlist ();
|
||||
|
||||
|
||||
ChannelList channels;
|
||||
AudioPlaylist* _playlist;
|
||||
};
|
||||
|
||||
}; /* namespace ARDOUR */
|
||||
|
||||
#endif /* __ardour_diskstream_h__ */
|
||||
#endif /* __ardour_audio_diskstream_h__ */
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class AudioTrack : public Route
|
|||
bool can_record() const { return true; }
|
||||
void set_record_enable (bool yn, void *src);
|
||||
|
||||
AudioDiskstream& disk_stream() const { return *diskstream; }
|
||||
AudioDiskstream& disk_stream() const { return *_diskstream; }
|
||||
int set_diskstream (AudioDiskstream&, void *);
|
||||
int use_diskstream (string name);
|
||||
int use_diskstream (id_t id);
|
||||
|
|
@ -99,7 +99,7 @@ class AudioTrack : public Route
|
|||
void set_meter_point (MeterPoint, void* src);
|
||||
|
||||
protected:
|
||||
AudioDiskstream *diskstream;
|
||||
AudioDiskstream *_diskstream;
|
||||
MeterPoint _saved_meter_point;
|
||||
TrackMode _mode;
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include <ardour/ardour.h>
|
||||
#include <jack/jack.h>
|
||||
#include <jack/transport.h>
|
||||
#include <ardour/buffer.h>
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
|
|
@ -104,8 +105,8 @@ class AudioEngine : public sigc::trackable
|
|||
virtual const char *what() const throw() { return "could not connect to engine backend"; }
|
||||
};
|
||||
|
||||
Port *register_audio_input_port (const std::string& portname);
|
||||
Port *register_audio_output_port (const std::string& portname);
|
||||
Port *register_input_port (Buffer::Type type, const std::string& portname);
|
||||
Port *register_output_port (Buffer::Type type, const std::string& portname);
|
||||
int unregister_port (Port *);
|
||||
|
||||
int connect (const std::string& source, const std::string& destination);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include <ardour/utils.h>
|
||||
#include <ardour/state_manager.h>
|
||||
#include <ardour/curve.h>
|
||||
#include <ardour/buffer.h>
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
|
@ -53,6 +54,11 @@ class Port;
|
|||
class Connection;
|
||||
class Panner;
|
||||
|
||||
/** A collection of input and output ports with connections.
|
||||
*
|
||||
* An IO can contain ports of varying types, making routes/inserts/etc with
|
||||
* varied combinations of types (eg MIDI and audio) possible.
|
||||
*/
|
||||
class IO : public Stateful, public ARDOUR::StateManager
|
||||
{
|
||||
|
||||
|
|
@ -61,7 +67,8 @@ class IO : public Stateful, public ARDOUR::StateManager
|
|||
|
||||
IO (Session&, string name,
|
||||
int input_min = -1, int input_max = -1,
|
||||
int output_min = -1, int output_max = -1);
|
||||
int output_min = -1, int output_max = -1,
|
||||
Buffer::Type default_type = Buffer::AUDIO);
|
||||
|
||||
virtual ~IO();
|
||||
|
||||
|
|
@ -80,20 +87,22 @@ class IO : public Stateful, public ARDOUR::StateManager
|
|||
|
||||
virtual void silence (jack_nframes_t, jack_nframes_t offset);
|
||||
|
||||
// These should be moved in to a separate object that manipulates an IO
|
||||
|
||||
void pan (vector<Sample*>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset, gain_t gain_coeff);
|
||||
void pan_automated (vector<Sample*>& bufs, uint32_t nbufs, jack_nframes_t start_frame, jack_nframes_t end_frame,
|
||||
jack_nframes_t nframes, jack_nframes_t offset);
|
||||
void collect_input (vector<Sample*>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset);
|
||||
void deliver_output (vector<Sample *>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset);
|
||||
void deliver_output_no_pan (vector<Sample *>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset);
|
||||
void deliver_output (vector<Sample*>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset);
|
||||
void deliver_output_no_pan (vector<Sample*>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset);
|
||||
void just_meter_input (jack_nframes_t start_frame, jack_nframes_t end_frame,
|
||||
jack_nframes_t nframes, jack_nframes_t offset);
|
||||
|
||||
virtual uint32_t n_process_buffers () { return 0; }
|
||||
|
||||
virtual void set_gain (gain_t g, void *src);
|
||||
void inc_gain (gain_t delta, void *src);
|
||||
gain_t gain () const { return _desired_gain; }
|
||||
void inc_gain (gain_t delta, void *src);
|
||||
gain_t gain () const { return _desired_gain; }
|
||||
virtual gain_t effective_gain () const;
|
||||
|
||||
Panner& panner() { return *_panner; }
|
||||
|
|
@ -106,8 +115,8 @@ class IO : public Stateful, public ARDOUR::StateManager
|
|||
Connection *input_connection() const { return _input_connection; }
|
||||
Connection *output_connection() const { return _output_connection; }
|
||||
|
||||
int add_input_port (string source, void *src);
|
||||
int add_output_port (string destination, void *src);
|
||||
int add_input_port (string source, void *src, Buffer::Type type = Buffer::NIL);
|
||||
int add_output_port (string destination, void *src, Buffer::Type type = Buffer::NIL);
|
||||
|
||||
int remove_input_port (Port *, void *src);
|
||||
int remove_output_port (Port *, void *src);
|
||||
|
|
@ -289,6 +298,7 @@ public:
|
|||
id_t _id;
|
||||
bool no_panner_reset;
|
||||
XMLNode* deferred_state;
|
||||
Buffer::Type _default_type;
|
||||
|
||||
virtual void set_deferred_state() {}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ class Playlist : public Stateful, public StateManager {
|
|||
Playlist (const Playlist&, string name, bool hidden = false);
|
||||
Playlist (const Playlist&, jack_nframes_t start, jack_nframes_t cnt, string name, bool hidden = false);
|
||||
|
||||
virtual jack_nframes_t read (Sample *dst, Sample *mixdown, float *gain_buffer, char * workbuf, jack_nframes_t start, jack_nframes_t cnt, uint32_t chan_n=0) = 0;
|
||||
//virtual jack_nframes_t read (Sample *dst, Sample *mixdown, float *gain_buffer, char * workbuf, jack_nframes_t start, jack_nframes_t cnt, uint32_t chan_n=0) = 0;
|
||||
virtual void clear (bool with_delete = false, bool with_save = true);
|
||||
virtual void dump () const;
|
||||
virtual UndoAction get_memento() const = 0;
|
||||
|
|
|
|||
|
|
@ -33,24 +33,24 @@ class AudioEngine;
|
|||
class Port : public sigc::trackable {
|
||||
public:
|
||||
virtual ~Port() {
|
||||
free (port);
|
||||
free (_port);
|
||||
}
|
||||
|
||||
Sample *get_buffer (jack_nframes_t nframes) {
|
||||
if (_flags & JackPortIsOutput) {
|
||||
return _buffer;
|
||||
} else {
|
||||
return (Sample *) jack_port_get_buffer (port, nframes);
|
||||
return (Sample *) jack_port_get_buffer (_port, nframes);
|
||||
}
|
||||
}
|
||||
|
||||
void reset_buffer () {
|
||||
if (_flags & JackPortIsOutput) {
|
||||
_buffer = (Sample *) jack_port_get_buffer (port, 0);
|
||||
_buffer = (Sample *) jack_port_get_buffer (_port, 0);
|
||||
} else {
|
||||
_buffer = 0; /* catch illegal attempts to use it */
|
||||
}
|
||||
silent = false;
|
||||
_silent = false;
|
||||
}
|
||||
|
||||
std::string name() {
|
||||
|
|
@ -58,7 +58,7 @@ class Port : public sigc::trackable {
|
|||
}
|
||||
|
||||
std::string short_name() {
|
||||
return jack_port_short_name (port);
|
||||
return jack_port_short_name (_port);
|
||||
}
|
||||
|
||||
int set_name (std::string str);
|
||||
|
|
@ -68,7 +68,7 @@ class Port : public sigc::trackable {
|
|||
}
|
||||
|
||||
bool is_mine (jack_client_t *client) {
|
||||
return jack_port_is_mine (client, port);
|
||||
return jack_port_is_mine (client, _port);
|
||||
}
|
||||
|
||||
const char* type() const {
|
||||
|
|
@ -76,21 +76,21 @@ class Port : public sigc::trackable {
|
|||
}
|
||||
|
||||
int connected () const {
|
||||
return jack_port_connected (port);
|
||||
return jack_port_connected (_port);
|
||||
}
|
||||
|
||||
bool connected_to (const std::string& portname) const {
|
||||
return jack_port_connected_to (port, portname.c_str());
|
||||
return jack_port_connected_to (_port, portname.c_str());
|
||||
}
|
||||
|
||||
const char ** get_connections () const {
|
||||
return jack_port_get_connections (port);
|
||||
return jack_port_get_connections (_port);
|
||||
}
|
||||
|
||||
void reset_overs () {
|
||||
_short_overs = 0;
|
||||
_long_overs = 0;
|
||||
overlen = 0;
|
||||
_overlen = 0;
|
||||
}
|
||||
|
||||
void reset_peak_meter () {
|
||||
|
|
@ -103,18 +103,18 @@ class Port : public sigc::trackable {
|
|||
}
|
||||
|
||||
void enable_metering() {
|
||||
metering++;
|
||||
_metering++;
|
||||
}
|
||||
|
||||
void disable_metering () {
|
||||
if (metering) { metering--; }
|
||||
if (_metering) { _metering--; }
|
||||
}
|
||||
|
||||
float peak_db() const { return _peak_db; }
|
||||
float peak_db() const { return _peak_db; }
|
||||
jack_default_audio_sample_t peak() const { return _peak; }
|
||||
|
||||
uint32_t short_overs () const { return _short_overs; }
|
||||
uint32_t long_overs () const { return _long_overs; }
|
||||
uint32_t long_overs () const { return _long_overs; }
|
||||
|
||||
static void set_short_over_length (jack_nframes_t);
|
||||
static void set_long_over_length (jack_nframes_t);
|
||||
|
|
@ -128,7 +128,7 @@ class Port : public sigc::trackable {
|
|||
}
|
||||
|
||||
bool monitoring_input () const {
|
||||
return jack_port_monitoring_input (port);
|
||||
return jack_port_monitoring_input (_port);
|
||||
}
|
||||
|
||||
bool can_monitor () const {
|
||||
|
|
@ -136,30 +136,29 @@ class Port : public sigc::trackable {
|
|||
}
|
||||
|
||||
void ensure_monitor_input (bool yn) {
|
||||
jack_port_request_monitor (port, yn);
|
||||
jack_port_request_monitor (_port, yn);
|
||||
}
|
||||
|
||||
void request_monitor_input (bool yn) {
|
||||
jack_port_request_monitor (port, yn);
|
||||
jack_port_request_monitor (_port, yn);
|
||||
}
|
||||
|
||||
jack_nframes_t latency () const {
|
||||
return jack_port_get_latency (port);
|
||||
return jack_port_get_latency (_port);
|
||||
}
|
||||
|
||||
void set_latency (jack_nframes_t nframes) {
|
||||
jack_port_set_latency (port, nframes);
|
||||
jack_port_set_latency (_port, nframes);
|
||||
}
|
||||
|
||||
sigc::signal<void,bool> MonitorInputChanged;
|
||||
sigc::signal<void,bool> ClockSyncChanged;
|
||||
|
||||
bool is_silent() const { return silent; }
|
||||
bool is_silent() const { return _silent; }
|
||||
|
||||
/** Assumes that the port is an audio output port */
|
||||
void silence (jack_nframes_t nframes, jack_nframes_t offset) {
|
||||
/* assumes that the port is an output port */
|
||||
|
||||
if (!silent) {
|
||||
if (!_silent) {
|
||||
memset (_buffer + offset, 0, sizeof (Sample) * nframes);
|
||||
if (offset == 0) {
|
||||
/* XXX this isn't really true, but i am not sure
|
||||
|
|
@ -167,13 +166,13 @@ class Port : public sigc::trackable {
|
|||
want to set it true when the entire port
|
||||
buffer has been overrwritten.
|
||||
*/
|
||||
silent = true;
|
||||
_silent = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mark_silence (bool yn) {
|
||||
silent = yn;
|
||||
_silent = yn;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -184,7 +183,7 @@ class Port : public sigc::trackable {
|
|||
|
||||
/* engine isn't supposed to below here */
|
||||
|
||||
Sample *_buffer;
|
||||
Sample *_buffer;
|
||||
|
||||
/* cache these 3 from JACK so that we can
|
||||
access them for reconnecting.
|
||||
|
|
@ -194,18 +193,18 @@ class Port : public sigc::trackable {
|
|||
std::string _type;
|
||||
std::string _name;
|
||||
|
||||
bool last_monitor : 1;
|
||||
bool silent : 1;
|
||||
jack_port_t *port;
|
||||
jack_nframes_t overlen;
|
||||
jack_default_audio_sample_t _peak;
|
||||
float _peak_db;
|
||||
uint32_t _short_overs;
|
||||
uint32_t _long_overs;
|
||||
unsigned short metering;
|
||||
bool _last_monitor : 1;
|
||||
bool _silent : 1;
|
||||
jack_port_t *_port;
|
||||
jack_nframes_t _overlen;
|
||||
jack_default_audio_sample_t _peak;
|
||||
float _peak_db;
|
||||
uint32_t _short_overs;
|
||||
uint32_t _long_overs;
|
||||
unsigned short _metering;
|
||||
|
||||
static jack_nframes_t long_over_length;
|
||||
static jack_nframes_t short_over_length;
|
||||
static jack_nframes_t _long_over_length;
|
||||
static jack_nframes_t _short_over_length;
|
||||
};
|
||||
|
||||
}; /* namespace ARDOUR */
|
||||
|
|
|
|||
|
|
@ -140,11 +140,11 @@ class Region : public Stateful, public StateManager
|
|||
return ARDOUR::coverage (_position, _position + _length - 1, start, end);
|
||||
}
|
||||
|
||||
virtual jack_nframes_t read_at (Sample *buf, Sample *mixdown_buffer,
|
||||
/*virtual jack_nframes_t read_at (Sample *buf, Sample *mixdown_buffer,
|
||||
float *gain_buffer, char * workbuf, jack_nframes_t position, jack_nframes_t cnt,
|
||||
uint32_t chan_n = 0,
|
||||
jack_nframes_t read_frames = 0,
|
||||
jack_nframes_t skip_frames = 0) const = 0;
|
||||
jack_nframes_t skip_frames = 0) const = 0;*/
|
||||
|
||||
/* EDITING OPERATIONS */
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include <ardour/io.h>
|
||||
#include <ardour/session.h>
|
||||
#include <ardour/redirect.h>
|
||||
#include <ardour/buffer.h>
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
|
|
@ -66,7 +67,9 @@ class Route : public IO
|
|||
};
|
||||
|
||||
|
||||
Route (Session&, std::string name, int input_min, int input_max, int output_min, int output_max, Flag flags = Flag(0));
|
||||
Route (Session&, std::string name, int input_min, int input_max, int output_min, int output_max,
|
||||
Flag flags = Flag(0), Buffer::Type default_type = Buffer::AUDIO);
|
||||
|
||||
Route (Session&, const XMLNode&);
|
||||
virtual ~Route();
|
||||
|
||||
|
|
|
|||
|
|
@ -62,11 +62,13 @@ namespace ARDOUR {
|
|||
class Port;
|
||||
class AudioEngine;
|
||||
class Slave;
|
||||
class AudioDiskstream;
|
||||
class Diskstream;
|
||||
class Route;
|
||||
class AuxInput;
|
||||
class Source;
|
||||
class AudioSource;
|
||||
|
||||
class AudioDiskstream;
|
||||
class AudioFileSource;
|
||||
class Auditioner;
|
||||
class Insert;
|
||||
|
|
@ -79,11 +81,18 @@ class TempoMap;
|
|||
class AudioTrack;
|
||||
class NamedSelection;
|
||||
class AudioRegion;
|
||||
|
||||
class Region;
|
||||
class Playlist;
|
||||
class VSTPlugin;
|
||||
class ControlProtocolManager;
|
||||
|
||||
//class MidiDiskstream;
|
||||
class MidiSource;
|
||||
class MidiTrack;
|
||||
class MidiRegion;
|
||||
class SMFSource;
|
||||
|
||||
struct AudioExportSpecification;
|
||||
struct RouteGroup;
|
||||
|
||||
|
|
@ -264,8 +273,8 @@ class Session : public sigc::trackable, public Stateful
|
|||
vector<Sample*>& get_silent_buffers (uint32_t howmany);
|
||||
vector<Sample*>& get_send_buffers () { return _send_buffers; }
|
||||
|
||||
AudioDiskstream *diskstream_by_id (id_t id);
|
||||
AudioDiskstream *diskstream_by_name (string name);
|
||||
Diskstream *diskstream_by_id (id_t id);
|
||||
Diskstream *diskstream_by_name (string name);
|
||||
|
||||
bool have_captured() const { return _have_captured; }
|
||||
|
||||
|
|
@ -352,7 +361,7 @@ class Session : public sigc::trackable, public Stateful
|
|||
sigc::signal<void> HaltOnXrun;
|
||||
|
||||
sigc::signal<void,Route*> RouteAdded;
|
||||
sigc::signal<void,AudioDiskstream*> AudioDiskstreamAdded;
|
||||
sigc::signal<void,Diskstream*> DiskstreamAdded;
|
||||
|
||||
void request_roll ();
|
||||
void request_bounded_roll (jack_nframes_t start, jack_nframes_t end);
|
||||
|
|
@ -364,15 +373,15 @@ class Session : public sigc::trackable, public Stateful
|
|||
void goto_start () { request_locate (start_location->start(), false); }
|
||||
void use_rf_shuttle_speed ();
|
||||
void request_transport_speed (float speed);
|
||||
void request_overwrite_buffer (AudioDiskstream*);
|
||||
void request_diskstream_speed (AudioDiskstream&, float speed);
|
||||
void request_overwrite_buffer (Diskstream*);
|
||||
void request_diskstream_speed (Diskstream&, float speed);
|
||||
void request_input_change_handling ();
|
||||
|
||||
bool locate_pending() const { return static_cast<bool>(post_transport_work&PostTransportLocate); }
|
||||
bool transport_locked () const;
|
||||
|
||||
int wipe ();
|
||||
int wipe_diskstream (AudioDiskstream *);
|
||||
//int wipe_diskstream (AudioDiskstream *);
|
||||
|
||||
int remove_region_from_region_list (Region&);
|
||||
|
||||
|
|
@ -545,10 +554,11 @@ class Session : public sigc::trackable, public Stateful
|
|||
|
||||
/* fundamental operations. duh. */
|
||||
|
||||
|
||||
AudioTrack *new_audio_track (int input_channels, int output_channels, TrackMode mode = Normal);
|
||||
|
||||
Route *new_audio_route (int input_channels, int output_channels);
|
||||
|
||||
MidiTrack *new_midi_track (TrackMode mode = Normal);
|
||||
Route *new_midi_route ();
|
||||
|
||||
void remove_route (Route&);
|
||||
void resort_routes (void *src);
|
||||
|
|
@ -1429,12 +1439,12 @@ class Session : public sigc::trackable, public Stateful
|
|||
bool waiting_to_start;
|
||||
|
||||
void set_auto_loop (bool yn);
|
||||
void overwrite_some_buffers (AudioDiskstream*);
|
||||
void overwrite_some_buffers (Diskstream*);
|
||||
void flush_all_redirects ();
|
||||
void locate (jack_nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
|
||||
void start_locate (jack_nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
|
||||
void force_locate (jack_nframes_t frame, bool with_roll = false);
|
||||
void set_diskstream_speed (AudioDiskstream*, float speed);
|
||||
void set_diskstream_speed (Diskstream*, float speed);
|
||||
void set_transport_speed (float speed, bool abort = false);
|
||||
void stop_transport (bool abort = false);
|
||||
void start_transport ();
|
||||
|
|
@ -1468,7 +1478,7 @@ class Session : public sigc::trackable, public Stateful
|
|||
AudioDiskstreamList audio_diskstreams;
|
||||
mutable Glib::RWLock diskstream_lock;
|
||||
uint32_t dstream_buffer_size;
|
||||
void add_diskstream (AudioDiskstream*);
|
||||
void add_diskstream (Diskstream*);
|
||||
int load_diskstreams (const XMLNode&);
|
||||
|
||||
/* routes stuff */
|
||||
|
|
@ -1536,7 +1546,7 @@ class Session : public sigc::trackable, public Stateful
|
|||
Playlist *XMLPlaylistFactory (const XMLNode&);
|
||||
|
||||
void playlist_length_changed (Playlist *);
|
||||
void diskstream_playlist_changed (AudioDiskstream *);
|
||||
void diskstream_playlist_changed (Diskstream *);
|
||||
|
||||
/* NAMED SELECTIONS */
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ namespace ARDOUR {
|
|||
typedef uint32_t layer_t;
|
||||
typedef uint64_t id_t;
|
||||
|
||||
typedef unsigned char RawMidi;
|
||||
|
||||
enum IOChange {
|
||||
NoChange = 0,
|
||||
ConfigurationChanged = 0x1,
|
||||
|
|
|
|||
|
|
@ -53,17 +53,16 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
jack_nframes_t AudioDiskstream::disk_io_chunk_frames;
|
||||
|
||||
sigc::signal<void,AudioDiskstream*> AudioDiskstream::AudioDiskstreamCreated;
|
||||
//sigc::signal<void,AudioDiskstream*> AudioDiskstream::AudioDiskstreamCreated;
|
||||
sigc::signal<void,list<AudioFileSource*>*> AudioDiskstream::DeleteSources;
|
||||
sigc::signal<void> AudioDiskstream::DiskOverrun;
|
||||
sigc::signal<void> AudioDiskstream::DiskUnderrun;
|
||||
//sigc::signal<void> AudioDiskstream::DiskOverrun;
|
||||
//sigc::signal<void> AudioDiskstream::DiskUnderrun;
|
||||
|
||||
AudioDiskstream::AudioDiskstream (Session &sess, const string &name, Flag flag)
|
||||
: _name (name),
|
||||
_session (sess)
|
||||
AudioDiskstream::AudioDiskstream (Session &sess, const string &name, Diskstream::Flag flag)
|
||||
: Diskstream(sess, name, flag)
|
||||
, _playlist(NULL)
|
||||
{
|
||||
/* prevent any write sources from being created */
|
||||
|
||||
|
|
@ -74,12 +73,12 @@ AudioDiskstream::AudioDiskstream (Session &sess, const string &name, Flag flag)
|
|||
|
||||
in_set_state = false;
|
||||
|
||||
AudioDiskstreamCreated (this); /* EMIT SIGNAL */
|
||||
DiskstreamCreated (this); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
AudioDiskstream::AudioDiskstream (Session& sess, const XMLNode& node)
|
||||
: _session (sess)
|
||||
|
||||
: Diskstream(sess, node)
|
||||
, _playlist(NULL)
|
||||
{
|
||||
in_set_state = true;
|
||||
init (Recordable);
|
||||
|
|
@ -95,7 +94,7 @@ AudioDiskstream::AudioDiskstream (Session& sess, const XMLNode& node)
|
|||
use_destructive_playlist ();
|
||||
}
|
||||
|
||||
AudioDiskstreamCreated (this); /* EMIT SIGNAL */
|
||||
DiskstreamCreated (this); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -128,44 +127,9 @@ AudioDiskstream::init_channel (ChannelInfo &chan)
|
|||
|
||||
|
||||
void
|
||||
AudioDiskstream::init (Flag f)
|
||||
AudioDiskstream::init (Diskstream::Flag f)
|
||||
{
|
||||
_id = new_id();
|
||||
_refcnt = 0;
|
||||
_flags = f;
|
||||
_io = 0;
|
||||
_alignment_style = ExistingMaterial;
|
||||
_persistent_alignment_style = ExistingMaterial;
|
||||
first_input_change = true;
|
||||
_playlist = 0;
|
||||
i_am_the_modifier = 0;
|
||||
g_atomic_int_set (&_record_enabled, 0);
|
||||
was_recording = false;
|
||||
capture_start_frame = 0;
|
||||
capture_captured = 0;
|
||||
_visible_speed = 1.0f;
|
||||
_actual_speed = 1.0f;
|
||||
_buffer_reallocation_required = false;
|
||||
_seek_required = false;
|
||||
first_recordable_frame = max_frames;
|
||||
last_recordable_frame = max_frames;
|
||||
_roll_delay = 0;
|
||||
_capture_offset = 0;
|
||||
_processed = false;
|
||||
_slaved = false;
|
||||
adjust_capture_position = 0;
|
||||
last_possibly_recording = 0;
|
||||
loop_location = 0;
|
||||
wrap_buffer_size = 0;
|
||||
speed_buffer_size = 0;
|
||||
last_phase = 0;
|
||||
phi = (uint64_t) (0x1000000);
|
||||
file_frame = 0;
|
||||
playback_sample = 0;
|
||||
playback_distance = 0;
|
||||
_read_data_count = 0;
|
||||
_write_data_count = 0;
|
||||
deprecated_io_node = 0;
|
||||
Diskstream::init(f);
|
||||
|
||||
/* there are no channels at this point, so these
|
||||
two calls just get speed_buffer_size and wrap_buffer
|
||||
|
|
@ -215,9 +179,8 @@ AudioDiskstream::~AudioDiskstream ()
|
|||
{
|
||||
Glib::Mutex::Lock lm (state_lock);
|
||||
|
||||
if (_playlist) {
|
||||
if (_playlist)
|
||||
_playlist->unref ();
|
||||
}
|
||||
|
||||
for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
|
||||
destroy_channel((*chan));
|
||||
|
|
@ -225,7 +188,7 @@ AudioDiskstream::~AudioDiskstream ()
|
|||
|
||||
channels.clear();
|
||||
}
|
||||
|
||||
/*
|
||||
void
|
||||
AudioDiskstream::handle_input_change (IOChange change, void *src)
|
||||
{
|
||||
|
|
@ -236,7 +199,7 @@ AudioDiskstream::handle_input_change (IOChange change, void *src)
|
|||
_session.request_input_change_handling ();
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
void
|
||||
AudioDiskstream::non_realtime_input_change ()
|
||||
{
|
||||
|
|
@ -346,8 +309,10 @@ AudioDiskstream::find_and_use_playlist (const string& name)
|
|||
}
|
||||
|
||||
int
|
||||
AudioDiskstream::use_playlist (AudioPlaylist* playlist)
|
||||
AudioDiskstream::use_playlist (Playlist* playlist)
|
||||
{
|
||||
assert(dynamic_cast<AudioPlaylist*>(playlist));
|
||||
|
||||
{
|
||||
Glib::Mutex::Lock lm (state_lock);
|
||||
|
||||
|
|
@ -363,7 +328,7 @@ AudioDiskstream::use_playlist (AudioPlaylist* playlist)
|
|||
_playlist->unref();
|
||||
}
|
||||
|
||||
_playlist = playlist;
|
||||
_playlist = dynamic_cast<AudioPlaylist*>(playlist);
|
||||
_playlist->ref();
|
||||
|
||||
if (!in_set_state && recordable()) {
|
||||
|
|
@ -386,17 +351,6 @@ AudioDiskstream::use_playlist (AudioPlaylist* playlist)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::playlist_deleted (Playlist* pl)
|
||||
{
|
||||
/* this catches an ordering issue with session destruction. playlists
|
||||
are destroyed before diskstreams. we have to invalidate any handles
|
||||
we have to the playlist.
|
||||
*/
|
||||
|
||||
_playlist = 0;
|
||||
}
|
||||
|
||||
int
|
||||
AudioDiskstream::use_new_playlist ()
|
||||
{
|
||||
|
|
@ -446,6 +400,19 @@ AudioDiskstream::use_copy_playlist ()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioDiskstream::playlist_deleted (Playlist* pl)
|
||||
{
|
||||
/* this catches an ordering issue with session destruction. playlists
|
||||
are destroyed before diskstreams. we have to invalidate any handles
|
||||
we have to the playlist.
|
||||
*/
|
||||
|
||||
_playlist = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioDiskstream::setup_destructive_playlist ()
|
||||
{
|
||||
|
|
@ -499,67 +466,6 @@ AudioDiskstream::set_io (IO& io)
|
|||
set_align_style_from_io ();
|
||||
}
|
||||
|
||||
int
|
||||
AudioDiskstream::set_name (string str, void *src)
|
||||
{
|
||||
if (str != _name) {
|
||||
_playlist->set_name (str);
|
||||
_name = str;
|
||||
|
||||
if (!in_set_state && recordable()) {
|
||||
/* rename existing capture files so that they have the correct name */
|
||||
return rename_write_sources ();
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::set_speed (double sp)
|
||||
{
|
||||
_session.request_diskstream_speed (*this, sp);
|
||||
|
||||
/* to force a rebuffering at the right place */
|
||||
playlist_modified();
|
||||
}
|
||||
|
||||
bool
|
||||
AudioDiskstream::realtime_set_speed (double sp, bool global)
|
||||
{
|
||||
bool changed = false;
|
||||
double new_speed = sp * _session.transport_speed();
|
||||
|
||||
if (_visible_speed != sp) {
|
||||
_visible_speed = sp;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (new_speed != _actual_speed) {
|
||||
|
||||
jack_nframes_t required_wrap_size = (jack_nframes_t) floor (_session.get_block_size() *
|
||||
fabs (new_speed)) + 1;
|
||||
|
||||
if (required_wrap_size > wrap_buffer_size) {
|
||||
_buffer_reallocation_required = true;
|
||||
}
|
||||
|
||||
_actual_speed = new_speed;
|
||||
phi = (uint64_t) (0x1000000 * fabs(_actual_speed));
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
if (!global) {
|
||||
_seek_required = true;
|
||||
}
|
||||
speed_changed (); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
return _buffer_reallocation_required || _seek_required;
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::non_realtime_set_speed ()
|
||||
{
|
||||
|
|
@ -583,13 +489,6 @@ AudioDiskstream::non_realtime_set_speed ()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::prepare ()
|
||||
{
|
||||
_processed = false;
|
||||
playback_distance = 0;
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::check_record_status (jack_nframes_t transport_frame, jack_nframes_t nframes, bool can_record)
|
||||
{
|
||||
|
|
@ -1009,13 +908,6 @@ AudioDiskstream::process (jack_nframes_t transport_frame, jack_nframes_t nframes
|
|||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::recover ()
|
||||
{
|
||||
state_lock.unlock();
|
||||
_processed = false;
|
||||
}
|
||||
|
||||
bool
|
||||
AudioDiskstream::commit (jack_nframes_t nframes)
|
||||
{
|
||||
|
|
@ -1155,9 +1047,9 @@ AudioDiskstream::seek (jack_nframes_t frame, bool complete_refill)
|
|||
file_frame = frame;
|
||||
|
||||
if (complete_refill) {
|
||||
while ((ret = do_refill (0, 0, 0)) > 0);
|
||||
while ((ret = non_realtime_do_refill ()) > 0);
|
||||
} else {
|
||||
ret = do_refill (0, 0, 0);
|
||||
ret = non_realtime_do_refill ();
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
@ -1649,21 +1541,6 @@ AudioDiskstream::do_flush (char * workbuf, bool force_flush)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::playlist_changed (Change ignored)
|
||||
{
|
||||
playlist_modified ();
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::playlist_modified ()
|
||||
{
|
||||
if (!i_am_the_modifier && !overwrite_queued) {
|
||||
_session.request_overwrite_buffer (this);
|
||||
overwrite_queued = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_capture)
|
||||
{
|
||||
|
|
@ -1898,7 +1775,7 @@ AudioDiskstream::finish_capture (bool rec_monitors_input)
|
|||
void
|
||||
AudioDiskstream::set_record_enabled (bool yn, void* src)
|
||||
{
|
||||
bool rolling = _session.transport_speed() != 0.0f;
|
||||
bool rolling = _session.transport_speed() != 0.0f;
|
||||
|
||||
if (!recordable() || !_session.record_enabling_legal()) {
|
||||
return;
|
||||
|
|
@ -1958,7 +1835,7 @@ XMLNode&
|
|||
AudioDiskstream::get_state ()
|
||||
{
|
||||
XMLNode* node = new XMLNode ("AudioDiskstream");
|
||||
char buf[64];
|
||||
char buf[64] = "";
|
||||
LocaleGuard lg (X_("POSIX"));
|
||||
|
||||
snprintf (buf, sizeof(buf), "0x%x", _flags);
|
||||
|
|
@ -2288,23 +2165,6 @@ AudioDiskstream::monitor_input (bool yn)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::set_capture_offset ()
|
||||
{
|
||||
if (_io == 0) {
|
||||
/* can't capture, so forget it */
|
||||
return;
|
||||
}
|
||||
|
||||
_capture_offset = _io->input_latency();
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::set_persistent_align_style (AlignStyle a)
|
||||
{
|
||||
_persistent_alignment_style = a;
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::set_align_style_from_io ()
|
||||
{
|
||||
|
|
@ -2330,20 +2190,6 @@ AudioDiskstream::set_align_style_from_io ()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::set_align_style (AlignStyle a)
|
||||
{
|
||||
if (record_enabled() && _session.actively_recording()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (a != _alignment_style) {
|
||||
_alignment_style = a;
|
||||
AlignmentStyleChanged ();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
AudioDiskstream::add_channel ()
|
||||
{
|
||||
|
|
@ -2394,57 +2240,6 @@ AudioDiskstream::capture_buffer_load () const
|
|||
(double) channels.front().capture_buf->bufsize());
|
||||
}
|
||||
|
||||
int
|
||||
AudioDiskstream::set_loop (Location *location)
|
||||
{
|
||||
if (location) {
|
||||
if (location->start() >= location->end()) {
|
||||
error << string_compose(_("Location \"%1\" not valid for track loop (start >= end)"), location->name()) << endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
loop_location = location;
|
||||
|
||||
LoopSet (location); /* EMIT SIGNAL */
|
||||
return 0;
|
||||
}
|
||||
|
||||
jack_nframes_t
|
||||
AudioDiskstream::get_capture_start_frame (uint32_t n)
|
||||
{
|
||||
Glib::Mutex::Lock lm (capture_info_lock);
|
||||
|
||||
if (capture_info.size() > n) {
|
||||
return capture_info[n]->start;
|
||||
}
|
||||
else {
|
||||
return capture_start_frame;
|
||||
}
|
||||
}
|
||||
|
||||
jack_nframes_t
|
||||
AudioDiskstream::get_captured_frames (uint32_t n)
|
||||
{
|
||||
Glib::Mutex::Lock lm (capture_info_lock);
|
||||
|
||||
if (capture_info.size() > n) {
|
||||
return capture_info[n]->frames;
|
||||
}
|
||||
else {
|
||||
return capture_captured;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::punch_in ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::punch_out ()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
AudioDiskstream::use_pending_capture_data (XMLNode& node)
|
||||
|
|
@ -2541,22 +2336,3 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::set_roll_delay (jack_nframes_t nframes)
|
||||
{
|
||||
_roll_delay = nframes;
|
||||
}
|
||||
|
||||
void
|
||||
AudioDiskstream::set_destructive (bool yn)
|
||||
{
|
||||
if (yn != destructive()) {
|
||||
reset_write_sources (true, true);
|
||||
if (yn) {
|
||||
_flags |= Destructive;
|
||||
} else {
|
||||
_flags &= ~Destructive;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
static char* SOUNDFILE = "http://ardour.org/ontology/Soundfile";
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
using namespace ARDOUR;
|
||||
using namespace sigc;
|
||||
using namespace std;
|
||||
using namespace PBD;
|
||||
|
||||
AudioPlaylist::State::~State ()
|
||||
{
|
||||
|
|
@ -242,16 +243,18 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, ch
|
|||
|
||||
for (vector<uint32_t>::iterator l = relevant_layers.begin(); l != relevant_layers.end(); ++l) {
|
||||
|
||||
// FIXME: Should be vector<AudioRegion*>
|
||||
vector<Region*>& r (relevant_regions[*l]);
|
||||
vector<Crossfade*>& x (relevant_xfades[*l]);
|
||||
|
||||
for (vector<Region*>::iterator i = r.begin(); i != r.end(); ++i) {
|
||||
(*i)->read_at (buf, mixdown_buffer, gain_buffer, workbuf, start, cnt, chan_n, read_frames, skip_frames);
|
||||
_read_data_count += (*i)->read_data_count();
|
||||
AudioRegion* const ar = dynamic_cast<AudioRegion*>(*i);
|
||||
assert(ar);
|
||||
ar->read_at (buf, mixdown_buffer, gain_buffer, workbuf, start, cnt, chan_n, read_frames, skip_frames);
|
||||
_read_data_count += ar->read_data_count();
|
||||
}
|
||||
|
||||
for (vector<Crossfade*>::iterator i = x.begin(); i != x.end(); ++i) {
|
||||
|
||||
(*i)->read_at (buf, mixdown_buffer, gain_buffer, workbuf, start, cnt, chan_n);
|
||||
|
||||
/* don't JACK up _read_data_count, since its the same data as we just
|
||||
|
|
|
|||
|
|
@ -38,10 +38,11 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode mode)
|
||||
: Route (sess, name, 1, -1, -1, -1, flag),
|
||||
diskstream (0),
|
||||
_diskstream (0),
|
||||
_midi_rec_enable_control (*this, _session.midi_port())
|
||||
{
|
||||
AudioDiskstream::Flag dflags = AudioDiskstream::Flag (0);
|
||||
|
|
@ -74,7 +75,7 @@ AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode
|
|||
|
||||
AudioTrack::AudioTrack (Session& sess, const XMLNode& node)
|
||||
: Route (sess, "to be renamed", 0, 0, -1, -1),
|
||||
diskstream (0),
|
||||
_diskstream (0),
|
||||
_midi_rec_enable_control (*this, _session.midi_port())
|
||||
{
|
||||
_freeze_record.state = NoFreeze;
|
||||
|
|
@ -88,8 +89,8 @@ AudioTrack::AudioTrack (Session& sess, const XMLNode& node)
|
|||
|
||||
AudioTrack::~AudioTrack ()
|
||||
{
|
||||
if (diskstream) {
|
||||
diskstream->unref();
|
||||
if (_diskstream) {
|
||||
_diskstream->unref();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -104,16 +105,16 @@ AudioTrack::handle_smpte_offset_change ()
|
|||
int
|
||||
AudioTrack::deprecated_use_diskstream_connections ()
|
||||
{
|
||||
if (diskstream->deprecated_io_node == 0) {
|
||||
if (_diskstream->deprecated_io_node == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const XMLProperty* prop;
|
||||
XMLNode& node (*diskstream->deprecated_io_node);
|
||||
XMLNode& node (*_diskstream->deprecated_io_node);
|
||||
|
||||
/* don't do this more than once. */
|
||||
|
||||
diskstream->deprecated_io_node = 0;
|
||||
_diskstream->deprecated_io_node = 0;
|
||||
|
||||
set_input_minimum (-1);
|
||||
set_input_maximum (-1);
|
||||
|
|
@ -156,15 +157,15 @@ AudioTrack::deprecated_use_diskstream_connections ()
|
|||
int
|
||||
AudioTrack::set_diskstream (AudioDiskstream& ds, void *src)
|
||||
{
|
||||
if (diskstream) {
|
||||
diskstream->unref();
|
||||
if (_diskstream) {
|
||||
_diskstream->unref();
|
||||
}
|
||||
|
||||
diskstream = &ds.ref();
|
||||
diskstream->set_io (*this);
|
||||
diskstream->set_destructive (_mode == Destructive);
|
||||
_diskstream = &ds.ref();
|
||||
_diskstream->set_io (*this);
|
||||
_diskstream->set_destructive (_mode == Destructive);
|
||||
|
||||
if (diskstream->deprecated_io_node) {
|
||||
if (_diskstream->deprecated_io_node) {
|
||||
|
||||
if (!connecting_legal) {
|
||||
ConnectingLegal.connect (mem_fun (*this, &AudioTrack::deprecated_use_diskstream_connections));
|
||||
|
|
@ -173,11 +174,11 @@ AudioTrack::set_diskstream (AudioDiskstream& ds, void *src)
|
|||
}
|
||||
}
|
||||
|
||||
diskstream->set_record_enabled (false, this);
|
||||
diskstream->monitor_input (false);
|
||||
_diskstream->set_record_enabled (false, this);
|
||||
_diskstream->monitor_input (false);
|
||||
|
||||
ic_connection.disconnect();
|
||||
ic_connection = input_changed.connect (mem_fun (*diskstream, &AudioDiskstream::handle_input_change));
|
||||
ic_connection = input_changed.connect (mem_fun (*_diskstream, &AudioDiskstream::handle_input_change));
|
||||
|
||||
diskstream_changed (src); /* EMIT SIGNAL */
|
||||
|
||||
|
|
@ -189,8 +190,8 @@ AudioTrack::use_diskstream (string name)
|
|||
{
|
||||
AudioDiskstream *dstream;
|
||||
|
||||
if ((dstream = _session.diskstream_by_name (name)) == 0) {
|
||||
error << string_compose(_("AudioTrack: diskstream \"%1\" not known by session"), name) << endmsg;
|
||||
if ((dstream = dynamic_cast<AudioDiskstream*>(_session.diskstream_by_name (name))) == 0) {
|
||||
error << string_compose(_("AudioTrack: audio diskstream \"%1\" not known by session"), name) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -202,8 +203,8 @@ AudioTrack::use_diskstream (id_t id)
|
|||
{
|
||||
AudioDiskstream *dstream;
|
||||
|
||||
if ((dstream = _session.diskstream_by_id (id)) == 0) {
|
||||
error << string_compose(_("AudioTrack: diskstream \"%1\" not known by session"), id) << endmsg;
|
||||
if ((dstream = dynamic_cast<AudioDiskstream*>(_session.diskstream_by_id (id))) == 0) {
|
||||
error << string_compose(_("AudioTrack: audio diskstream \"%1\" not known by session"), id) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -213,7 +214,7 @@ AudioTrack::use_diskstream (id_t id)
|
|||
bool
|
||||
AudioTrack::record_enabled () const
|
||||
{
|
||||
return diskstream->record_enabled ();
|
||||
return _diskstream->record_enabled ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -230,13 +231,13 @@ AudioTrack::set_record_enable (bool yn, void *src)
|
|||
|
||||
/* keep track of the meter point as it was before we rec-enabled */
|
||||
|
||||
if (!diskstream->record_enabled()) {
|
||||
if (!_diskstream->record_enabled()) {
|
||||
_saved_meter_point = _meter_point;
|
||||
}
|
||||
|
||||
diskstream->set_record_enabled (yn, src);
|
||||
_diskstream->set_record_enabled (yn, src);
|
||||
|
||||
if (diskstream->record_enabled()) {
|
||||
if (_diskstream->record_enabled()) {
|
||||
set_meter_point (MeterInput, this);
|
||||
} else {
|
||||
set_meter_point (_saved_meter_point, this);
|
||||
|
|
@ -398,7 +399,7 @@ AudioTrack::state(bool full_state)
|
|||
/* Alignment: act as a proxy for the diskstream */
|
||||
|
||||
XMLNode* align_node = new XMLNode (X_("alignment"));
|
||||
switch (diskstream->alignment_style()) {
|
||||
switch (_diskstream->alignment_style()) {
|
||||
case ExistingMaterial:
|
||||
snprintf (buf, sizeof (buf), X_("existing"));
|
||||
break;
|
||||
|
|
@ -452,7 +453,7 @@ AudioTrack::state(bool full_state)
|
|||
diskstream.
|
||||
*/
|
||||
|
||||
snprintf (buf, sizeof (buf), "%" PRIu64, diskstream->id());
|
||||
snprintf (buf, sizeof (buf), "%" PRIu64, _diskstream->id());
|
||||
root.add_property ("diskstream-id", buf);
|
||||
|
||||
return root;
|
||||
|
|
@ -524,9 +525,9 @@ AudioTrack::set_state_part_two ()
|
|||
|
||||
if ((prop = fnode->property (X_("style"))) != 0) {
|
||||
if (prop->value() == "existing") {
|
||||
diskstream->set_persistent_align_style (ExistingMaterial);
|
||||
_diskstream->set_persistent_align_style (ExistingMaterial);
|
||||
} else if (prop->value() == "capture") {
|
||||
diskstream->set_persistent_align_style (CaptureTime);
|
||||
_diskstream->set_persistent_align_style (CaptureTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -536,7 +537,7 @@ AudioTrack::set_state_part_two ()
|
|||
uint32_t
|
||||
AudioTrack::n_process_buffers ()
|
||||
{
|
||||
return max ((uint32_t) diskstream->n_channels(), redirect_max_outs);
|
||||
return max ((uint32_t) _diskstream->n_channels(), redirect_max_outs);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -567,7 +568,7 @@ AudioTrack::no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nf
|
|||
return 0;
|
||||
}
|
||||
|
||||
diskstream->check_record_status (start_frame, nframes, can_record);
|
||||
_diskstream->check_record_status (start_frame, nframes, can_record);
|
||||
|
||||
bool send_silence;
|
||||
|
||||
|
|
@ -586,7 +587,7 @@ AudioTrack::no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nf
|
|||
send_silence = true;
|
||||
}
|
||||
} else {
|
||||
if (diskstream->record_enabled()) {
|
||||
if (_diskstream->record_enabled()) {
|
||||
if (Config->get_use_sw_monitoring()) {
|
||||
send_silence = false;
|
||||
} else {
|
||||
|
|
@ -660,13 +661,13 @@ AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nfram
|
|||
playback distance to zero, thus causing diskstream::commit
|
||||
to do nothing.
|
||||
*/
|
||||
return diskstream->process (transport_frame, 0, 0, can_record, rec_monitors_input);
|
||||
return _diskstream->process (transport_frame, 0, 0, can_record, rec_monitors_input);
|
||||
}
|
||||
|
||||
_silent = false;
|
||||
apply_gain_automation = false;
|
||||
|
||||
if ((dret = diskstream->process (transport_frame, nframes, offset, can_record, rec_monitors_input)) != 0) {
|
||||
if ((dret = _diskstream->process (transport_frame, nframes, offset, can_record, rec_monitors_input)) != 0) {
|
||||
|
||||
silence (nframes, offset);
|
||||
|
||||
|
|
@ -679,7 +680,7 @@ AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nfram
|
|||
just_meter_input (start_frame, end_frame, nframes, offset);
|
||||
}
|
||||
|
||||
if (diskstream->record_enabled() && !can_record && !_session.get_auto_input()) {
|
||||
if (_diskstream->record_enabled() && !can_record && !_session.get_auto_input()) {
|
||||
|
||||
/* not actually recording, but we want to hear the input material anyway,
|
||||
at least potentially (depending on monitoring options)
|
||||
|
|
@ -687,7 +688,7 @@ AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nfram
|
|||
|
||||
passthru (start_frame, end_frame, nframes, offset, 0, true);
|
||||
|
||||
} else if ((b = diskstream->playback_buffer(0)) != 0) {
|
||||
} else if ((b = _diskstream->playback_buffer(0)) != 0) {
|
||||
|
||||
/*
|
||||
XXX is it true that the earlier test on n_outputs()
|
||||
|
|
@ -709,8 +710,8 @@ AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nfram
|
|||
|
||||
for (i = 0, n = 1; i < limit; ++i, ++n) {
|
||||
memcpy (bufs[i], b, sizeof (Sample) * nframes);
|
||||
if (n < diskstream->n_channels()) {
|
||||
tmpb = diskstream->playback_buffer(n);
|
||||
if (n < _diskstream->n_channels()) {
|
||||
tmpb = _diskstream->playback_buffer(n);
|
||||
if (tmpb!=0) {
|
||||
b = tmpb;
|
||||
}
|
||||
|
|
@ -719,7 +720,7 @@ AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nfram
|
|||
|
||||
/* don't waste time with automation if we're recording or we've just stopped (yes it can happen) */
|
||||
|
||||
if (!diskstream->record_enabled() && _session.transport_rolling()) {
|
||||
if (!_diskstream->record_enabled() && _session.transport_rolling()) {
|
||||
Glib::Mutex::Lock am (automation_lock, Glib::TRY_LOCK);
|
||||
|
||||
if (am.locked() && gain_automation_playback()) {
|
||||
|
|
@ -755,7 +756,7 @@ AudioTrack::silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jac
|
|||
|
||||
silence (nframes, offset);
|
||||
|
||||
return diskstream->process (_session.transport_frame() + offset, nframes, offset, can_record, rec_monitors_input);
|
||||
return _diskstream->process (_session.transport_frame() + offset, nframes, offset, can_record, rec_monitors_input);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -776,7 +777,7 @@ AudioTrack::set_name (string str, void *src)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (diskstream->set_name (str, src)) {
|
||||
if (_diskstream->set_name (str, src)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -801,8 +802,12 @@ AudioTrack::export_stuff (vector<Sample*>& buffers, char * workbuf, uint32_t nbu
|
|||
Sample * b;
|
||||
|
||||
Glib::RWLock::ReaderLock rlock (redirect_lock);
|
||||
|
||||
if (diskstream->playlist()->read (buffers[0], mix_buffer, gain_buffer, workbuf, start, nframes) != nframes) {
|
||||
|
||||
// FIXME
|
||||
AudioPlaylist* const apl = dynamic_cast<AudioPlaylist*>(_diskstream->playlist());
|
||||
assert(apl);
|
||||
|
||||
if (apl->read (buffers[0], mix_buffer, gain_buffer, workbuf, start, nframes) != nframes) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -811,8 +816,8 @@ AudioTrack::export_stuff (vector<Sample*>& buffers, char * workbuf, uint32_t nbu
|
|||
b = buffers[0];
|
||||
++bi;
|
||||
for (; bi != buffers.end(); ++bi, ++n) {
|
||||
if (n < diskstream->n_channels()) {
|
||||
if (diskstream->playlist()->read ((*bi), mix_buffer, gain_buffer, workbuf, start, nframes, n) != nframes) {
|
||||
if (n < _diskstream->n_channels()) {
|
||||
if (apl->read ((*bi), mix_buffer, gain_buffer, workbuf, start, nframes, n) != nframes) {
|
||||
return -1;
|
||||
}
|
||||
b = (*bi);
|
||||
|
|
@ -888,7 +893,7 @@ void
|
|||
AudioTrack::set_latency_delay (jack_nframes_t longest_session_latency)
|
||||
{
|
||||
Route::set_latency_delay (longest_session_latency);
|
||||
diskstream->set_roll_delay (_roll_delay);
|
||||
_diskstream->set_roll_delay (_roll_delay);
|
||||
}
|
||||
|
||||
jack_nframes_t
|
||||
|
|
@ -933,7 +938,7 @@ AudioTrack::freeze (InterThreadInfo& itt)
|
|||
AudioRegion* region;
|
||||
string region_name;
|
||||
|
||||
if ((_freeze_record.playlist = diskstream->playlist()) == 0) {
|
||||
if ((_freeze_record.playlist = dynamic_cast<AudioPlaylist*>(_diskstream->playlist())) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1000,13 +1005,13 @@ AudioTrack::freeze (InterThreadInfo& itt)
|
|||
(AudioRegion::Flag) (AudioRegion::WholeFile|AudioRegion::DefaultFlags),
|
||||
false);
|
||||
|
||||
new_playlist->set_orig_diskstream_id (diskstream->id());
|
||||
new_playlist->set_orig_diskstream_id (_diskstream->id());
|
||||
new_playlist->add_region (*region, 0);
|
||||
new_playlist->set_frozen (true);
|
||||
region->set_locked (true);
|
||||
|
||||
diskstream->use_playlist (dynamic_cast<AudioPlaylist*>(new_playlist));
|
||||
diskstream->set_record_enabled (false, this);
|
||||
_diskstream->use_playlist (dynamic_cast<AudioPlaylist*>(new_playlist));
|
||||
_diskstream->set_record_enabled (false, this);
|
||||
|
||||
_freeze_record.state = Frozen;
|
||||
FreezeChange(); /* EMIT SIGNAL */
|
||||
|
|
@ -1016,7 +1021,7 @@ void
|
|||
AudioTrack::unfreeze ()
|
||||
{
|
||||
if (_freeze_record.playlist) {
|
||||
diskstream->use_playlist (_freeze_record.playlist);
|
||||
_diskstream->use_playlist (_freeze_record.playlist);
|
||||
|
||||
if (_freeze_record.have_mementos) {
|
||||
|
||||
|
|
@ -1149,10 +1154,10 @@ AudioTrack::MIDIRecEnableControl::write_feedback (MIDI::byte* buf, int32_t& bufs
|
|||
void
|
||||
AudioTrack::set_mode (TrackMode m)
|
||||
{
|
||||
if (diskstream) {
|
||||
if (_diskstream) {
|
||||
if (_mode != m) {
|
||||
_mode = m;
|
||||
diskstream->set_destructive (m == Destructive);
|
||||
_diskstream->set_destructive (m == Destructive);
|
||||
ModeChanged();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,9 +40,11 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
jack_nframes_t Port::short_over_length = 2;
|
||||
jack_nframes_t Port::long_over_length = 10;
|
||||
// Why here? [DR]
|
||||
jack_nframes_t Port::_short_over_length = 2;
|
||||
jack_nframes_t Port::_long_over_length = 10;
|
||||
|
||||
AudioEngine::AudioEngine (string client_name)
|
||||
{
|
||||
|
|
@ -91,12 +93,6 @@ _thread_init_callback (void *arg)
|
|||
*/
|
||||
|
||||
PBD::ThreadCreatedWithRequestSize (pthread_self(), X_("Audioengine"), 4096);
|
||||
|
||||
#ifdef VST_SUPPORT
|
||||
if (Config->get_use_vst()) {
|
||||
fst_adopt_thread ();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -279,8 +275,8 @@ AudioEngine::process_callback (jack_nframes_t nframes)
|
|||
Port *port = (*i);
|
||||
bool x;
|
||||
|
||||
if (port->last_monitor != (x = port->monitoring_input ())) {
|
||||
port->last_monitor = x;
|
||||
if (port->_last_monitor != (x = port->monitoring_input ())) {
|
||||
port->_last_monitor = x;
|
||||
/* XXX I think this is dangerous, due to
|
||||
a likely mutex in the signal handlers ...
|
||||
*/
|
||||
|
|
@ -393,18 +389,19 @@ AudioEngine::remove_session ()
|
|||
}
|
||||
|
||||
Port *
|
||||
AudioEngine::register_audio_input_port (const string& portname)
|
||||
AudioEngine::register_input_port (Buffer::Type type, const string& portname)
|
||||
{
|
||||
if (!_running) {
|
||||
if (!_has_run) {
|
||||
fatal << _("register audio input port called before engine was started") << endmsg;
|
||||
fatal << _("register input port called before engine was started") << endmsg;
|
||||
/*NOTREACHED*/
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
jack_port_t *p = jack_port_register (_jack, portname.c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
|
||||
jack_port_t *p = jack_port_register (_jack, portname.c_str(),
|
||||
Buffer::type_to_jack_type(type), JackPortIsInput, 0);
|
||||
|
||||
if (p) {
|
||||
|
||||
|
|
@ -424,11 +421,11 @@ AudioEngine::register_audio_input_port (const string& portname)
|
|||
}
|
||||
|
||||
Port *
|
||||
AudioEngine::register_audio_output_port (const string& portname)
|
||||
AudioEngine::register_output_port (Buffer::Type type, const string& portname)
|
||||
{
|
||||
if (!_running) {
|
||||
if (!_has_run) {
|
||||
fatal << _("register audio output port called before engine was started") << endmsg;
|
||||
fatal << _("register output port called before engine was started") << endmsg;
|
||||
/*NOTREACHED*/
|
||||
} else {
|
||||
return 0;
|
||||
|
|
@ -437,7 +434,8 @@ AudioEngine::register_audio_output_port (const string& portname)
|
|||
|
||||
jack_port_t *p;
|
||||
|
||||
if ((p = jack_port_register (_jack, portname.c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) != 0) {
|
||||
if ((p = jack_port_register (_jack, portname.c_str(),
|
||||
Buffer::type_to_jack_type(type), JackPortIsOutput, 0)) != 0) {
|
||||
Port *newport = new Port (p);
|
||||
ports.insert (ports.begin(), newport);
|
||||
return newport;
|
||||
|
|
@ -451,6 +449,7 @@ AudioEngine::register_audio_output_port (const string& portname)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
AudioEngine::unregister_port (Port *port)
|
||||
{
|
||||
|
|
@ -463,7 +462,7 @@ AudioEngine::unregister_port (Port *port)
|
|||
|
||||
if (port) {
|
||||
|
||||
int ret = jack_port_unregister (_jack, port->port);
|
||||
int ret = jack_port_unregister (_jack, port->_port);
|
||||
|
||||
if (ret == 0) {
|
||||
|
||||
|
|
@ -554,7 +553,7 @@ AudioEngine::disconnect (Port *port)
|
|||
}
|
||||
}
|
||||
|
||||
int ret = jack_port_disconnect (_jack, port->port);
|
||||
int ret = jack_port_disconnect (_jack, port->_port);
|
||||
|
||||
if (ret == 0) {
|
||||
remove_connections_for (port);
|
||||
|
|
@ -704,7 +703,6 @@ AudioEngine::n_physical_inputs () const
|
|||
}
|
||||
|
||||
string
|
||||
|
||||
AudioEngine::get_nth_physical (uint32_t n, int flag)
|
||||
{
|
||||
const char ** ports;
|
||||
|
|
@ -752,7 +750,7 @@ AudioEngine::get_port_total_latency (const Port& port)
|
|||
}
|
||||
}
|
||||
|
||||
return jack_port_get_total_latency (_jack, port.port);
|
||||
return jack_port_get_total_latency (_jack, port._port);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -830,7 +828,7 @@ AudioEngine::remove_all_ports ()
|
|||
|
||||
if (_jack) {
|
||||
for (Ports::iterator i = ports.begin(); i != ports.end(); ++i) {
|
||||
jack_port_unregister (_jack, (*i)->port);
|
||||
jack_port_unregister (_jack, (*i)->_port);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -953,7 +951,7 @@ AudioEngine::reconnect_to_jack ()
|
|||
|
||||
short_name = long_name.substr (long_name.find_last_of (':') + 1);
|
||||
|
||||
if (((*i)->port = jack_port_register (_jack, short_name.c_str(), (*i)->type(), (*i)->flags(), 0)) == 0) {
|
||||
if (((*i)->_port = jack_port_register (_jack, short_name.c_str(), (*i)->type(), (*i)->flags(), 0)) == 0) {
|
||||
error << string_compose (_("could not reregister %1"), (*i)->name()) << endmsg;
|
||||
break;
|
||||
} else {
|
||||
|
|
@ -968,7 +966,7 @@ AudioEngine::reconnect_to_jack ()
|
|||
|
||||
if (i != ports.end()) {
|
||||
for (Ports::iterator i = ports.begin(); i != ports.end(); ++i) {
|
||||
jack_port_unregister (_jack, (*i)->port);
|
||||
jack_port_unregister (_jack, (*i)->_port);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
#include "i18n.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
string AudioFileSource::peak_dir = "";
|
||||
string AudioFileSource::search_path;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "i18n.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
int
|
||||
AudioFilter::make_new_sources (AudioRegion& region, AudioRegion::SourceList& nsrcs)
|
||||
|
|
|
|||
|
|
@ -44,12 +44,12 @@ Auditioner::Auditioner (Session& s)
|
|||
defer_pan_reset ();
|
||||
|
||||
if (left.length()) {
|
||||
add_output_port (left, this);
|
||||
add_output_port (left, this, Buffer::AUDIO);
|
||||
}
|
||||
|
||||
if (right.length()) {
|
||||
disk_stream().add_channel();
|
||||
add_output_port (right, this);
|
||||
add_output_port (right, this, Buffer::AUDIO);
|
||||
}
|
||||
|
||||
allow_pan_reset ();
|
||||
|
|
@ -67,8 +67,12 @@ Auditioner::~Auditioner ()
|
|||
AudioPlaylist&
|
||||
Auditioner::prepare_playlist ()
|
||||
{
|
||||
diskstream->playlist()->clear (false, false);
|
||||
return *diskstream->playlist();
|
||||
// FIXME
|
||||
AudioPlaylist* const apl = dynamic_cast<AudioPlaylist*>(_diskstream->playlist());
|
||||
assert(apl);
|
||||
|
||||
apl->clear (false, false);
|
||||
return *apl;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -82,13 +86,13 @@ Auditioner::audition_current_playlist ()
|
|||
}
|
||||
|
||||
Glib::Mutex::Lock lm (lock);
|
||||
diskstream->seek (0);
|
||||
length = diskstream->playlist()->get_maximum_extent();
|
||||
_diskstream->seek (0);
|
||||
length = _diskstream->playlist()->get_maximum_extent();
|
||||
current_frame = 0;
|
||||
|
||||
/* force a panner reset now that we have all channels */
|
||||
|
||||
_panner->reset (n_outputs(), diskstream->n_channels());
|
||||
_panner->reset (n_outputs(), _diskstream->n_channels());
|
||||
|
||||
g_atomic_int_set (&_active, 1);
|
||||
}
|
||||
|
|
@ -108,23 +112,23 @@ Auditioner::audition_region (AudioRegion& region)
|
|||
the_region = new AudioRegion (region);
|
||||
the_region->set_position (0, this);
|
||||
|
||||
diskstream->playlist()->clear (true, false);
|
||||
diskstream->playlist()->add_region (*the_region, 0, 1, false);
|
||||
_diskstream->playlist()->clear (true, false);
|
||||
_diskstream->playlist()->add_region (*the_region, 0, 1, false);
|
||||
|
||||
while (diskstream->n_channels() < the_region->n_channels()) {
|
||||
diskstream->add_channel ();
|
||||
while (_diskstream->n_channels() < the_region->n_channels()) {
|
||||
_diskstream->add_channel ();
|
||||
}
|
||||
|
||||
while (diskstream->n_channels() > the_region->n_channels()) {
|
||||
diskstream->remove_channel ();
|
||||
while (_diskstream->n_channels() > the_region->n_channels()) {
|
||||
_diskstream->remove_channel ();
|
||||
}
|
||||
|
||||
/* force a panner reset now that we have all channels */
|
||||
|
||||
_panner->reset (n_outputs(), diskstream->n_channels());
|
||||
_panner->reset (n_outputs(), _diskstream->n_channels());
|
||||
|
||||
length = the_region->length();
|
||||
diskstream->seek (0);
|
||||
_diskstream->seek (0);
|
||||
current_frame = 0;
|
||||
g_atomic_int_set (&_active, 1);
|
||||
}
|
||||
|
|
@ -143,14 +147,14 @@ Auditioner::play_audition (jack_nframes_t nframes)
|
|||
|
||||
this_nframes = min (nframes, length - current_frame);
|
||||
|
||||
diskstream->prepare ();
|
||||
_diskstream->prepare ();
|
||||
|
||||
if ((ret = roll (this_nframes, current_frame, current_frame + nframes, 0, false, false, false)) != 0) {
|
||||
silence (nframes, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
need_butler = diskstream->commit (this_nframes);
|
||||
need_butler = _diskstream->commit (this_nframes);
|
||||
current_frame += this_nframes;
|
||||
|
||||
if (current_frame >= length) {
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace sigc;
|
||||
using namespace PBD;
|
||||
|
||||
#if 0
|
||||
static void dumpit (const AutomationList& al, string prefix = "")
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
using namespace ARDOUR;
|
||||
using namespace std;
|
||||
using namespace PBD;
|
||||
|
||||
/* this is global so that we do not have to indirect through an object pointer
|
||||
to reference it.
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include "i18n.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
Connection::Connection (const XMLNode& node)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,11 +9,9 @@
|
|||
#include <ardour/session.h>
|
||||
#include <ardour/control_protocol_manager.h>
|
||||
|
||||
|
||||
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace std;
|
||||
using namespace PBD;
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include <AudioToolbox/AudioFormat.h>
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
CoreAudioSource::CoreAudioSource (const XMLNode& node)
|
||||
: AudioFileSource (node)
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
//using namespace sigc;
|
||||
using namespace PBD;
|
||||
|
||||
jack_nframes_t Crossfade::_short_xfade_length = 0;
|
||||
Change Crossfade::ActiveChanged = ARDOUR::new_change();
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace sigc;
|
||||
using namespace PBD;
|
||||
|
||||
Curve::Curve (double minv, double maxv, double canv, bool nostate)
|
||||
: AutomationList (canv, nostate)
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace PBD;
|
||||
|
||||
float CycleTimer::cycles_per_usec = 0;
|
||||
|
||||
float
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ typedef off_t off64_t;
|
|||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
gain_t* DestructiveFileSource::out_coefficient = 0;
|
||||
gain_t* DestructiveFileSource::in_coefficient = 0;
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ ARDOUR::OSC* ARDOUR::osc = 0;
|
|||
|
||||
using namespace ARDOUR;
|
||||
using namespace std;
|
||||
using namespace PBD;
|
||||
|
||||
MIDI::Port *default_mmc_port = 0;
|
||||
MIDI::Port *default_mtc_port = 0;
|
||||
|
|
@ -191,7 +192,7 @@ setup_midi (AudioEngine& engine )
|
|||
}
|
||||
|
||||
int
|
||||
ARDOUR::init (AudioEngine& engine, bool use_vst, bool try_optimization, void (*sighandler)(int,siginfo_t*,void*))
|
||||
ARDOUR::init (AudioEngine& engine, bool use_vst, bool try_optimization)
|
||||
{
|
||||
bool generic_mix_functions = true;
|
||||
|
||||
|
|
@ -216,7 +217,7 @@ ARDOUR::init (AudioEngine& engine, bool use_vst, bool try_optimization, void (*s
|
|||
#endif
|
||||
|
||||
#ifdef VST_SUPPORT
|
||||
if (Config->get_use_vst() && fst_init (sighandler)) {
|
||||
if (Config->get_use_vst() && fst_init ()) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "i18n.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
#define BLOCKSIZE 4096U
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
//using namespace sigc;
|
||||
using namespace PBD;
|
||||
|
||||
Insert::Insert(Session& s, Placement p)
|
||||
: Redirect (s, s.next_insert_name(), p)
|
||||
|
|
|
|||
|
|
@ -55,7 +55,8 @@ extern "C" int isinf (double);
|
|||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
//using namespace sigc;
|
||||
using namespace PBD;
|
||||
|
||||
|
||||
static float current_automation_version_number = 1.0;
|
||||
|
||||
|
|
@ -96,11 +97,18 @@ static bool sort_ports_by_name (Port* a, Port* b)
|
|||
}
|
||||
|
||||
|
||||
/** The 'default_type' argument here isn't very good, but port creation is too
|
||||
* brufty and all over the place to make anything else feasible without massive
|
||||
* changes. The default typed passed is the type of port that will be created
|
||||
* by ensure_io and friends. This is a temporary compatibility hack to get
|
||||
* multiple data types off the gound and should be removed.
|
||||
*/
|
||||
IO::IO (Session& s, string name,
|
||||
|
||||
int input_min, int input_max, int output_min, int output_max)
|
||||
int input_min, int input_max, int output_min, int output_max,
|
||||
Buffer::Type default_type)
|
||||
: _session (s),
|
||||
_name (name),
|
||||
_default_type(default_type),
|
||||
_midi_gain_control (*this, _session.midi_port()),
|
||||
_gain_automation_curve (0.0, 2.0, 1.0),
|
||||
_input_minimum (input_min),
|
||||
|
|
@ -784,11 +792,20 @@ IO::remove_output_port (Port* port, void* src)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/** Add an output port.
|
||||
*
|
||||
* @param destination Name of input port to connect new port to.
|
||||
* @param src Source for emitted ConfigurationChanged signal.
|
||||
* @param type Data type of port. Default value (Buffer::NIL) will use this IO's default type.
|
||||
*/
|
||||
int
|
||||
IO::add_output_port (string destination, void* src)
|
||||
IO::add_output_port (string destination, void* src, Buffer::Type type)
|
||||
{
|
||||
Port* our_port;
|
||||
char buf[64];
|
||||
char name[64];
|
||||
|
||||
if (type == Buffer::NIL)
|
||||
type = _default_type;
|
||||
|
||||
{
|
||||
Glib::Mutex::Lock em(_session.engine().process_lock());
|
||||
|
|
@ -802,14 +819,15 @@ IO::add_output_port (string destination, void* src)
|
|||
|
||||
/* Create a new output port */
|
||||
|
||||
// FIXME: naming scheme for differently typed ports?
|
||||
if (_output_maximum == 1) {
|
||||
snprintf (buf, sizeof (buf), _("%s/out"), _name.c_str());
|
||||
snprintf (name, sizeof (name), _("%s/out"), _name.c_str());
|
||||
} else {
|
||||
snprintf (buf, sizeof (buf), _("%s/out %u"), _name.c_str(), find_output_port_hole());
|
||||
snprintf (name, sizeof (name), _("%s/out %u"), _name.c_str(), find_output_port_hole());
|
||||
}
|
||||
|
||||
if ((our_port = _session.engine().register_audio_output_port (buf)) == 0) {
|
||||
error << string_compose(_("IO: cannot register output port %1"), buf) << endmsg;
|
||||
if ((our_port = _session.engine().register_output_port (type, name)) == 0) {
|
||||
error << string_compose(_("IO: cannot register output port %1"), name) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -885,11 +903,21 @@ IO::remove_input_port (Port* port, void* src)
|
|||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/** Add an input port.
|
||||
*
|
||||
* @param type Data type of port. The appropriate Jack port type, and @ref Port will be created.
|
||||
* @param destination Name of input port to connect new port to.
|
||||
* @param src Source for emitted ConfigurationChanged signal.
|
||||
*/
|
||||
int
|
||||
IO::add_input_port (string source, void* src)
|
||||
IO::add_input_port (string source, void* src, Buffer::Type type)
|
||||
{
|
||||
Port* our_port;
|
||||
char buf[64];
|
||||
char name[64];
|
||||
|
||||
if (type == Buffer::NIL)
|
||||
type = _default_type;
|
||||
|
||||
{
|
||||
Glib::Mutex::Lock em (_session.engine().process_lock());
|
||||
|
|
@ -903,14 +931,15 @@ IO::add_input_port (string source, void* src)
|
|||
|
||||
/* Create a new input port */
|
||||
|
||||
// FIXME: naming scheme for differently typed ports?
|
||||
if (_input_maximum == 1) {
|
||||
snprintf (buf, sizeof (buf), _("%s/in"), _name.c_str());
|
||||
snprintf (name, sizeof (name), _("%s/in"), _name.c_str());
|
||||
} else {
|
||||
snprintf (buf, sizeof (buf), _("%s/in %u"), _name.c_str(), find_input_port_hole());
|
||||
snprintf (name, sizeof (name), _("%s/in %u"), _name.c_str(), find_input_port_hole());
|
||||
}
|
||||
|
||||
if ((our_port = _session.engine().register_audio_input_port (buf)) == 0) {
|
||||
error << string_compose(_("IO: cannot register input port %1"), buf) << endmsg;
|
||||
if ((our_port = _session.engine().register_input_port (type, name)) == 0) {
|
||||
error << string_compose(_("IO: cannot register input port %1"), name) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -1006,6 +1035,8 @@ IO::ensure_inputs_locked (uint32_t n, bool clear, void* src)
|
|||
|
||||
/* Create a new input port */
|
||||
|
||||
// FIXME: of what type?
|
||||
|
||||
if (_input_maximum == 1) {
|
||||
snprintf (buf, sizeof (buf), _("%s/in"), _name.c_str());
|
||||
}
|
||||
|
|
@ -1015,7 +1046,7 @@ IO::ensure_inputs_locked (uint32_t n, bool clear, void* src)
|
|||
|
||||
try {
|
||||
|
||||
if ((input_port = _session.engine().register_audio_input_port (buf)) == 0) {
|
||||
if ((input_port = _session.engine().register_input_port (_default_type, buf)) == 0) {
|
||||
error << string_compose(_("IO: cannot register input port %1"), buf) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1106,6 +1137,8 @@ IO::ensure_io (uint32_t nin, uint32_t nout, bool clear, void* src)
|
|||
|
||||
/* create any necessary new ports */
|
||||
|
||||
// FIXME: of what type?
|
||||
|
||||
while (_ninputs < nin) {
|
||||
|
||||
char buf[64];
|
||||
|
|
@ -1120,7 +1153,7 @@ IO::ensure_io (uint32_t nin, uint32_t nout, bool clear, void* src)
|
|||
}
|
||||
|
||||
try {
|
||||
if ((port = _session.engine().register_audio_input_port (buf)) == 0) {
|
||||
if ((port = _session.engine().register_input_port (_default_type, buf)) == 0) {
|
||||
error << string_compose(_("IO: cannot register input port %1"), buf) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1153,7 +1186,7 @@ IO::ensure_io (uint32_t nin, uint32_t nout, bool clear, void* src)
|
|||
}
|
||||
|
||||
try {
|
||||
if ((port = _session.engine().register_audio_output_port (buf)) == 0) {
|
||||
if ((port = _session.engine().register_output_port (_default_type, buf)) == 0) {
|
||||
error << string_compose(_("IO: cannot register output port %1"), buf) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1278,7 +1311,7 @@ IO::ensure_outputs_locked (uint32_t n, bool clear, void* src)
|
|||
snprintf (buf, sizeof (buf), _("%s/out %u"), _name.c_str(), find_output_port_hole());
|
||||
}
|
||||
|
||||
if ((output_port = _session.engine().register_audio_output_port (buf)) == 0) {
|
||||
if ((output_port = _session.engine().register_output_port (_default_type, buf)) == 0) {
|
||||
error << string_compose(_("IO: cannot register output port %1"), buf) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
#include <errno.h>
|
||||
#include <jack/jack.h>
|
||||
#include <jack/transport.h>
|
||||
#include <pbd/error.h>
|
||||
|
||||
#include <ardour/slave.h>
|
||||
#include <ardour/session.h>
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
LadspaPlugin::LadspaPlugin (void *mod, AudioEngine& e, Session& session, uint32_t index, jack_nframes_t rate)
|
||||
: Plugin (e, session)
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace sigc;
|
||||
using namespace PBD;
|
||||
|
||||
Location::Location (const Location& other)
|
||||
: _name (other._name),
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
using namespace ARDOUR;
|
||||
using namespace sigc;
|
||||
using namespace MIDI;
|
||||
using namespace PBD;
|
||||
|
||||
MTC_Slave::MTC_Slave (Session& s, MIDI::Port& p)
|
||||
: session (s)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "i18n.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
sigc::signal<void,NamedSelection*> NamedSelection::NamedSelectionCreated;
|
||||
|
||||
|
|
|
|||
|
|
@ -44,9 +44,9 @@
|
|||
|
||||
#include <pbd/mathfix.h>
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
float Panner::current_automation_version_number = 1.0;
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
//using namespace sigc;
|
||||
using namespace PBD;
|
||||
|
||||
sigc::signal<void,Playlist*> Playlist::PlaylistCreated;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,25 @@
|
|||
/*
|
||||
Copyright (C) 2000-2006 Paul Davis
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#include <pbd/error.h>
|
||||
|
||||
#include <ardour/session.h>
|
||||
|
||||
#include <ardour/playlist.h>
|
||||
|
|
@ -10,6 +32,7 @@
|
|||
#include "i18n.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
Region*
|
||||
ARDOUR::createRegion (const Region& region, jack_nframes_t start,
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
#include <locale.h>
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
Plugin::Plugin (AudioEngine& e, Session& s)
|
||||
: _engine (e), _session (s)
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "i18n.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
PluginManager* PluginManager::_manager = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -24,15 +24,15 @@ using namespace ARDOUR;
|
|||
using namespace std;
|
||||
|
||||
Port::Port (jack_port_t *p)
|
||||
: port (p)
|
||||
: _port (p)
|
||||
{
|
||||
if (port == 0) {
|
||||
if (_port == 0) {
|
||||
throw failed_constructor();
|
||||
}
|
||||
|
||||
_flags = JackPortFlags (jack_port_flags (port));
|
||||
_type = jack_port_type (port);
|
||||
_name = jack_port_name (port);
|
||||
_flags = JackPortFlags (jack_port_flags (_port));
|
||||
_type = jack_port_type (_port);
|
||||
_name = jack_port_name (_port);
|
||||
|
||||
reset ();
|
||||
}
|
||||
|
|
@ -42,9 +42,9 @@ Port::reset ()
|
|||
{
|
||||
reset_buffer ();
|
||||
|
||||
last_monitor = false;
|
||||
silent = false;
|
||||
metering = 0;
|
||||
_last_monitor = false;
|
||||
_silent = false;
|
||||
_metering = 0;
|
||||
|
||||
reset_meters ();
|
||||
}
|
||||
|
|
@ -54,7 +54,7 @@ Port::set_name (string str)
|
|||
{
|
||||
int ret;
|
||||
|
||||
if ((ret = jack_port_set_name (port, str.c_str())) == 0) {
|
||||
if ((ret = jack_port_set_name (_port, str.c_str())) == 0) {
|
||||
_name = str;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@
|
|||
#include <ardour/utils.h>
|
||||
#include "i18n.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
int
|
||||
ARDOUR::read_recent_sessions (RecentSessions& rs)
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
//using namespace sigc;
|
||||
using namespace PBD;
|
||||
|
||||
const string Redirect::state_node_name = "Redirect";
|
||||
sigc::signal<void,Redirect*> Redirect::RedirectCreated;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
Change Region::FadeChanged = ARDOUR::new_change ();
|
||||
Change Region::SyncOffsetChanged = ARDOUR::new_change ();
|
||||
|
|
|
|||
|
|
@ -44,14 +44,14 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
//using namespace sigc;
|
||||
using namespace PBD;
|
||||
|
||||
|
||||
uint32_t Route::order_key_cnt = 0;
|
||||
|
||||
|
||||
Route::Route (Session& sess, string name, int input_min, int input_max, int output_min, int output_max, Flag flg)
|
||||
: IO (sess, name, input_min, input_max, output_min, output_max),
|
||||
Route::Route (Session& sess, string name, int input_min, int input_max, int output_min, int output_max, Flag flg, Buffer::Type default_type)
|
||||
: IO (sess, name, input_min, input_max, output_min, output_max, default_type),
|
||||
_flags (flg),
|
||||
_midi_solo_control (*this, MIDIToggleControl::SoloControl, _session.midi_port()),
|
||||
_midi_mute_control (*this, MIDIToggleControl::MuteControl, _session.midi_port())
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "i18n.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
Send::Send (Session& s, Placement p)
|
||||
: Redirect (s, s.next_send_name(), p)
|
||||
|
|
|
|||
|
|
@ -44,11 +44,15 @@
|
|||
#include <ardour/audioengine.h>
|
||||
#include <ardour/configuration.h>
|
||||
#include <ardour/session.h>
|
||||
#include <ardour/audio_diskstream.h>
|
||||
#include <ardour/utils.h>
|
||||
#include <ardour/audio_diskstream.h>
|
||||
#include <ardour/audioplaylist.h>
|
||||
#include <ardour/audioregion.h>
|
||||
#include <ardour/audiofilesource.h>
|
||||
#include <ardour/midi_diskstream.h>
|
||||
#include <ardour/midi_playlist.h>
|
||||
#include <ardour/midi_region.h>
|
||||
#include <ardour/smf_source.h>
|
||||
#include <ardour/destructive_filesource.h>
|
||||
#include <ardour/auditioner.h>
|
||||
#include <ardour/recent_sessions.h>
|
||||
|
|
@ -59,6 +63,7 @@
|
|||
#include <ardour/slave.h>
|
||||
#include <ardour/tempo.h>
|
||||
#include <ardour/audio_track.h>
|
||||
#include <ardour/midi_track.h>
|
||||
#include <ardour/cycle_timer.h>
|
||||
#include <ardour/named_selection.h>
|
||||
#include <ardour/crossfade.h>
|
||||
|
|
@ -73,7 +78,7 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
//using namespace sigc;
|
||||
using namespace PBD;
|
||||
|
||||
const char* Session::_template_suffix = X_(".template");
|
||||
const char* Session::_statefile_suffix = X_(".ardour");
|
||||
|
|
@ -300,6 +305,7 @@ Session::Session (AudioEngine &eng,
|
|||
_midi_port (default_midi_port),
|
||||
pending_events (2048),
|
||||
//midi_requests (16),
|
||||
_send_smpte_update (false),
|
||||
main_outs (0)
|
||||
|
||||
{
|
||||
|
|
@ -617,8 +623,13 @@ Session::when_engine_running ()
|
|||
|
||||
/* default state for Click */
|
||||
|
||||
// FIXME: there's no JackPortIsAudio flag or anything like that, so this is _bad_.
|
||||
// we need a get_nth_physical_audio_output or similar, but the existing one just
|
||||
// deals with strings :/
|
||||
|
||||
first_physical_output = _engine.get_nth_physical_output (0);
|
||||
|
||||
cerr << "FIXME: click type" << endl;
|
||||
|
||||
if (first_physical_output.length()) {
|
||||
if (_click_io->add_output_port (first_physical_output, this)) {
|
||||
// relax, even though its an error
|
||||
|
|
@ -736,7 +747,7 @@ Session::when_engine_running ()
|
|||
_master_out->defer_pan_reset ();
|
||||
|
||||
while ((int) _master_out->n_inputs() < _master_out->input_maximum()) {
|
||||
if (_master_out->add_input_port ("", this)) {
|
||||
if (_master_out->add_input_port ("", this)) { // FIXME
|
||||
error << _("cannot setup master inputs")
|
||||
<< endmsg;
|
||||
break;
|
||||
|
|
@ -744,7 +755,7 @@ Session::when_engine_running ()
|
|||
}
|
||||
n = 0;
|
||||
while ((int) _master_out->n_outputs() < _master_out->output_maximum()) {
|
||||
if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) {
|
||||
if (_master_out->add_output_port (_engine.get_nth_physical_output (n), this)) { // FIXME
|
||||
error << _("cannot setup master outputs")
|
||||
<< endmsg;
|
||||
break;
|
||||
|
|
@ -882,7 +893,7 @@ Session::playlist_length_changed (Playlist* pl)
|
|||
}
|
||||
|
||||
void
|
||||
Session::diskstream_playlist_changed (AudioDiskstream* dstream)
|
||||
Session::diskstream_playlist_changed (Diskstream* dstream)
|
||||
{
|
||||
Playlist *playlist;
|
||||
|
||||
|
|
@ -1670,6 +1681,202 @@ Session::resort_routes (void* src)
|
|||
|
||||
}
|
||||
|
||||
MidiTrack*
|
||||
Session::new_midi_track (TrackMode mode)
|
||||
{
|
||||
MidiTrack *track;
|
||||
char track_name[32];
|
||||
uint32_t n = 0;
|
||||
uint32_t channels_used = 0;
|
||||
string port;
|
||||
|
||||
/* count existing midi tracks */
|
||||
|
||||
{
|
||||
Glib::RWLock::ReaderLock lm (route_lock);
|
||||
for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
|
||||
if (dynamic_cast<MidiTrack*>(*i) != 0) {
|
||||
if (!(*i)->hidden()) {
|
||||
n++;
|
||||
channels_used += (*i)->n_inputs();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* check for duplicate route names, since we might have pre-existing
|
||||
routes with this name (e.g. create Midi1, Midi2, delete Midi1,
|
||||
save, close,restart,add new route - first named route is now
|
||||
Midi2)
|
||||
*/
|
||||
|
||||
do {
|
||||
snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, n+1);
|
||||
if (route_by_name (track_name) == 0) {
|
||||
break;
|
||||
}
|
||||
n++;
|
||||
|
||||
} while (n < (UINT_MAX-1));
|
||||
|
||||
try {
|
||||
track = new MidiTrack (*this, track_name, Route::Flag (0), mode);
|
||||
|
||||
if (track->ensure_io (1, 1, false, this)) {
|
||||
error << string_compose (_("cannot configure %1 in/%2 out configuration for new midi track"), track_name)
|
||||
<< endmsg;
|
||||
}
|
||||
#if 0
|
||||
if (nphysical_in) {
|
||||
for (uint32_t x = 0; x < track->n_inputs() && x < nphysical_in; ++x) {
|
||||
|
||||
port = "";
|
||||
|
||||
if (input_auto_connect & AutoConnectPhysical) {
|
||||
port = _engine.get_nth_physical_input ((channels_used+x)%nphysical_in);
|
||||
}
|
||||
|
||||
if (port.length() && track->connect_input (track->input (x), port, this)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t x = 0; x < track->n_outputs(); ++x) {
|
||||
|
||||
port = "";
|
||||
|
||||
if (nphysical_out && (output_auto_connect & AutoConnectPhysical)) {
|
||||
port = _engine.get_nth_physical_output ((channels_used+x)%nphysical_out);
|
||||
} else if (output_auto_connect & AutoConnectMaster) {
|
||||
if (_master_out) {
|
||||
port = _master_out->input (x%_master_out->n_inputs())->name();
|
||||
}
|
||||
}
|
||||
|
||||
if (port.length() && track->connect_output (track->output (x), port, this)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_control_out) {
|
||||
vector<string> cports;
|
||||
uint32_t ni = _control_out->n_inputs();
|
||||
|
||||
for (n = 0; n < ni; ++n) {
|
||||
cports.push_back (_control_out->input(n)->name());
|
||||
}
|
||||
|
||||
track->set_control_outs (cports);
|
||||
}
|
||||
#endif
|
||||
track->diskstream_changed.connect (mem_fun (this, &Session::resort_routes));
|
||||
|
||||
add_route (track);
|
||||
|
||||
track->set_remote_control_id (ntracks());
|
||||
}
|
||||
|
||||
catch (failed_constructor &err) {
|
||||
error << _("Session: could not create new midi track.") << endmsg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return track;
|
||||
}
|
||||
|
||||
|
||||
Route*
|
||||
Session::new_midi_route ()
|
||||
{
|
||||
Route *bus;
|
||||
char bus_name[32];
|
||||
uint32_t n = 0;
|
||||
string port;
|
||||
|
||||
/* count existing midi busses */
|
||||
|
||||
{
|
||||
Glib::RWLock::ReaderLock lm (route_lock);
|
||||
for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
|
||||
if (dynamic_cast<MidiTrack*>(*i) == 0) {
|
||||
if (!(*i)->hidden()) {
|
||||
n++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, n+1);
|
||||
if (route_by_name (bus_name) == 0) {
|
||||
break;
|
||||
}
|
||||
n++;
|
||||
|
||||
} while (n < (UINT_MAX-1));
|
||||
|
||||
try {
|
||||
bus = new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), Buffer::MIDI);
|
||||
|
||||
if (bus->ensure_io (1, 1, false, this)) {
|
||||
error << (_("cannot configure 1 in/1 out configuration for new midi track"))
|
||||
<< endmsg;
|
||||
}
|
||||
#if 0
|
||||
for (uint32_t x = 0; x < bus->n_inputs(); ++x) {
|
||||
|
||||
port = "";
|
||||
|
||||
if (input_auto_connect & AutoConnectPhysical) {
|
||||
port = _engine.get_nth_physical_input ((n+x)%n_physical_inputs);
|
||||
}
|
||||
|
||||
if (port.length() && bus->connect_input (bus->input (x), port, this)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t x = 0; x < bus->n_outputs(); ++x) {
|
||||
|
||||
port = "";
|
||||
|
||||
if (output_auto_connect & AutoConnectPhysical) {
|
||||
port = _engine.get_nth_physical_input ((n+x)%n_physical_outputs);
|
||||
} else if (output_auto_connect & AutoConnectMaster) {
|
||||
if (_master_out) {
|
||||
port = _master_out->input (x%_master_out->n_inputs())->name();
|
||||
}
|
||||
}
|
||||
|
||||
if (port.length() && bus->connect_output (bus->output (x), port, this)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
if (_control_out) {
|
||||
vector<string> cports;
|
||||
uint32_t ni = _control_out->n_inputs();
|
||||
|
||||
for (uint32_t n = 0; n < ni; ++n) {
|
||||
cports.push_back (_control_out->input(n)->name());
|
||||
}
|
||||
bus->set_control_outs (cports);
|
||||
}
|
||||
*/
|
||||
add_route (bus);
|
||||
}
|
||||
|
||||
catch (failed_constructor &err) {
|
||||
error << _("Session: could not create new MIDI route.") << endmsg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return bus;
|
||||
}
|
||||
|
||||
|
||||
AudioTrack*
|
||||
Session::new_audio_track (int input_channels, int output_channels, TrackMode mode)
|
||||
{
|
||||
|
|
@ -1820,7 +2027,7 @@ Session::new_audio_route (int input_channels, int output_channels)
|
|||
} while (n < (UINT_MAX-1));
|
||||
|
||||
try {
|
||||
bus = new Route (*this, bus_name, -1, -1, -1, -1);
|
||||
bus = new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), Buffer::AUDIO);
|
||||
|
||||
if (bus->ensure_io (input_channels, output_channels, false, this)) {
|
||||
error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
|
||||
|
|
@ -1872,7 +2079,7 @@ Session::new_audio_route (int input_channels, int output_channels)
|
|||
}
|
||||
|
||||
catch (failed_constructor &err) {
|
||||
error << _("Session: could not create new route.") << endmsg;
|
||||
error << _("Session: could not create new audio route.") << endmsg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1908,10 +2115,17 @@ Session::add_route (Route* route)
|
|||
}
|
||||
|
||||
void
|
||||
Session::add_diskstream (AudioDiskstream* dstream)
|
||||
Session::add_diskstream (Diskstream* s)
|
||||
{
|
||||
// FIXME: temporary. duh.
|
||||
AudioDiskstream* dstream = dynamic_cast<AudioDiskstream*>(s);
|
||||
if (!dstream) {
|
||||
cerr << "FIXME: Non Audio Diskstream" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
/* need to do this in case we're rolling at the time, to prevent false underruns */
|
||||
dstream->do_refill(0, 0, 0);
|
||||
dstream->non_realtime_do_refill();
|
||||
|
||||
{
|
||||
Glib::RWLock::WriterLock lm (diskstream_lock);
|
||||
|
|
@ -1935,7 +2149,7 @@ Session::add_diskstream (AudioDiskstream* dstream)
|
|||
set_dirty();
|
||||
save_state (_current_snapshot_name);
|
||||
|
||||
AudioDiskstreamAdded (dstream); /* EMIT SIGNAL */
|
||||
DiskstreamAdded (dstream); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -2279,11 +2493,12 @@ Session::get_maximum_extent () const
|
|||
return max;
|
||||
}
|
||||
|
||||
AudioDiskstream *
|
||||
Diskstream *
|
||||
Session::diskstream_by_name (string name)
|
||||
{
|
||||
Glib::RWLock::ReaderLock lm (diskstream_lock);
|
||||
|
||||
// FIXME: duh
|
||||
for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
|
||||
if ((*i)->name() == name) {
|
||||
return* i;
|
||||
|
|
@ -2293,11 +2508,12 @@ Session::diskstream_by_name (string name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
AudioDiskstream *
|
||||
Diskstream *
|
||||
Session::diskstream_by_id (id_t id)
|
||||
{
|
||||
Glib::RWLock::ReaderLock lm (diskstream_lock);
|
||||
|
||||
// FIXME: duh
|
||||
for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
|
||||
if ((*i)->id() == id) {
|
||||
return *i;
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
//using namespace sigc;
|
||||
using namespace PBD;
|
||||
|
||||
static float _read_data_rate;
|
||||
static float _write_data_rate;
|
||||
|
|
@ -174,9 +174,8 @@ Session::butler_thread_work ()
|
|||
butler_gain_buffer = new gain_t[AudioDiskstream::disk_io_frames()];
|
||||
// this buffer is used for temp conversion purposes in filesources
|
||||
char * conv_buffer = conversion_buffer(ButlerContext);
|
||||
|
||||
|
||||
while (true) {
|
||||
|
||||
pfd[0].fd = butler_request_pipe[0];
|
||||
pfd[0].events = POLLIN|POLLERR|POLLHUP;
|
||||
|
||||
|
|
@ -198,14 +197,13 @@ Session::butler_thread_work ()
|
|||
}
|
||||
|
||||
if (pfd[0].revents & POLLIN) {
|
||||
|
||||
|
||||
char req;
|
||||
|
||||
/* empty the pipe of all current requests */
|
||||
|
||||
while (1) {
|
||||
size_t nread = ::read (butler_request_pipe[0], &req, sizeof (req));
|
||||
|
||||
if (nread == 1) {
|
||||
|
||||
switch ((ButlerRequest::Type) req) {
|
||||
|
|
@ -240,10 +238,10 @@ Session::butler_thread_work ()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
|
||||
|
||||
//for (i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
|
||||
// cerr << "BEFORE " << (*i)->name() << ": pb = " << (*i)->playback_buffer_load() << " cp = " << (*i)->capture_buffer_load() << endl;
|
||||
}
|
||||
//}
|
||||
|
||||
if (transport_work_requested()) {
|
||||
butler_transport_work ();
|
||||
|
|
@ -258,7 +256,6 @@ Session::butler_thread_work ()
|
|||
Glib::RWLock::ReaderLock dsm (diskstream_lock);
|
||||
|
||||
for (i = audio_diskstreams.begin(); !transport_work_requested() && butler_should_run && i != audio_diskstreams.end(); ++i) {
|
||||
|
||||
// cerr << "rah fondr " << (*i)->io()->name () << endl;
|
||||
|
||||
switch ((*i)->do_refill (butler_mixdown_buffer, butler_gain_buffer, conv_buffer)) {
|
||||
|
|
@ -299,9 +296,8 @@ Session::butler_thread_work ()
|
|||
bytes = 0;
|
||||
compute_io = true;
|
||||
gettimeofday (&begin, 0);
|
||||
|
||||
|
||||
for (i = audio_diskstreams.begin(); !transport_work_requested() && butler_should_run && i != audio_diskstreams.end(); ++i) {
|
||||
|
||||
// cerr << "write behind for " << (*i)->name () << endl;
|
||||
|
||||
switch ((*i)->do_flush (conv_buffer)) {
|
||||
|
|
@ -375,18 +371,17 @@ Session::butler_thread_work ()
|
|||
|
||||
|
||||
void
|
||||
Session::request_overwrite_buffer (AudioDiskstream* stream)
|
||||
Session::request_overwrite_buffer (Diskstream* stream)
|
||||
{
|
||||
Event *ev = new Event (Event::Overwrite, Event::Add, Event::Immediate, 0, 0, 0.0);
|
||||
ev->set_ptr (stream);
|
||||
queue_event (ev);
|
||||
}
|
||||
|
||||
/** Process thread. */
|
||||
void
|
||||
Session::overwrite_some_buffers (AudioDiskstream* ds)
|
||||
Session::overwrite_some_buffers (Diskstream* ds)
|
||||
{
|
||||
/* executed by the audio thread */
|
||||
|
||||
if (actively_recording()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
Pool Session::Click::pool ("click", sizeof (Click), 128);
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
#include "i18n.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
//using namespace sigc;
|
||||
using namespace PBD;
|
||||
|
||||
MultiAllocSingleReleasePool Session::Event::pool ("event", sizeof (Session::Event), 512);
|
||||
|
||||
|
|
@ -397,7 +397,7 @@ Session::process_event (Event* ev)
|
|||
break;
|
||||
|
||||
case Event::SetDiskstreamSpeed:
|
||||
set_diskstream_speed (static_cast<AudioDiskstream*> (ev->ptr), ev->speed);
|
||||
set_diskstream_speed (static_cast<Diskstream*> (ev->ptr), ev->speed);
|
||||
break;
|
||||
|
||||
case Event::SetSlaveSource:
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
//using namespace sigc;
|
||||
using namespace PBD;
|
||||
|
||||
static int
|
||||
convert_spec_to_info (AudioExportSpecification& spec, SF_INFO& sfinfo)
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@
|
|||
|
||||
#include <glibmm/thread.h>
|
||||
|
||||
#include <pbd/error.h>
|
||||
#include <pbd/pthread_utils.h>
|
||||
|
||||
#include <ardour/configuration.h>
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
//using namespace sigc;
|
||||
using namespace PBD;
|
||||
using namespace MIDI;
|
||||
|
||||
MachineControl::CommandSignature MMC_CommandSignature;
|
||||
|
|
@ -660,7 +660,6 @@ Session::mmc_pause (MIDI::MachineControl &mmc)
|
|||
static bool step_queued = false;
|
||||
|
||||
void
|
||||
|
||||
Session::mmc_step (MIDI::MachineControl &mmc, int steps)
|
||||
{
|
||||
if (!mmc_control) {
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
#include "i18n.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
//using namespace sigc;
|
||||
using namespace PBD;
|
||||
using namespace std;
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
void
|
||||
Session::first_stage_init (string fullpath, string snapshot_name)
|
||||
|
|
@ -269,7 +270,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
|
|||
AudioSource::AudioSourceCreated.connect (mem_fun (*this, &Session::add_audio_source));
|
||||
Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
|
||||
Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
|
||||
AudioDiskstream::AudioDiskstreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
|
||||
AudioDiskstream::DiskstreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
|
||||
NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
|
||||
|
||||
IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
#include "i18n.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
//using namespace sigc;
|
||||
using namespace PBD;
|
||||
|
||||
/* BBT TIME*/
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
using namespace soundtouch;
|
||||
|
||||
AudioRegion*
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace sigc;
|
||||
using namespace PBD;
|
||||
|
||||
void
|
||||
Session::request_input_change_handling ()
|
||||
|
|
@ -78,7 +79,7 @@ Session::request_transport_speed (float speed)
|
|||
}
|
||||
|
||||
void
|
||||
Session::request_diskstream_speed (AudioDiskstream& ds, float speed)
|
||||
Session::request_diskstream_speed (Diskstream& ds, float speed)
|
||||
{
|
||||
Event* ev = new Event (Event::SetDiskstreamSpeed, Event::Add, Event::Immediate, 0, speed);
|
||||
ev->set_ptr (&ds);
|
||||
|
|
@ -1045,7 +1046,7 @@ Session::reverse_diskstream_buffers ()
|
|||
}
|
||||
|
||||
void
|
||||
Session::set_diskstream_speed (AudioDiskstream* stream, float speed)
|
||||
Session::set_diskstream_speed (Diskstream* stream, float speed)
|
||||
{
|
||||
if (stream->realtime_set_speed (speed, false)) {
|
||||
post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
SndFileSource::SndFileSource (const XMLNode& node)
|
||||
: AudioFileSource (node)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
using namespace ARDOUR;
|
||||
using namespace std;
|
||||
using namespace PBD;
|
||||
|
||||
bool StateManager::_allow_save = true;
|
||||
sigc::signal<void,const char*> StateManager::SaveAllowed;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace PBD;
|
||||
|
||||
Stateful::Stateful ()
|
||||
{
|
||||
_extra_xml = 0;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
/* _default tempo is 4/4 qtr=120 */
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
using namespace ARDOUR;
|
||||
using namespace std;
|
||||
using namespace PBD;
|
||||
|
||||
void
|
||||
elapsed_time_to_str (char *buf, uint32_t seconds)
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
#include <locale.h>
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
using std::min;
|
||||
using std::max;
|
||||
|
||||
|
|
|
|||
27
libs/fst/SConscript
Normal file
27
libs/fst/SConscript
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# -*- python -*-
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import glob
|
||||
|
||||
fst_src = glob.glob('*.c')
|
||||
|
||||
Import('env install_prefix')
|
||||
fst = env.Copy(CC="winegcc")
|
||||
fst.Append (CPPPATH=".")
|
||||
|
||||
hackSDK = fst.Command('vst/aeffectx.h', 'vstsdk2.3/source/common/aeffectx.h', [
|
||||
Delete ('${TARGET.dir}'),
|
||||
Copy ('${TARGET.dir}', '${SOURCE.dir}'),
|
||||
"sed -i '/struct VstFileType\|struct VstFileSelect/,/};/d' $TARGET"
|
||||
])
|
||||
|
||||
a = fst.Object ('fst', 'fst.c')
|
||||
b = fst.Object ('fstinfofile', 'fstinfofile.c')
|
||||
c = fst.Object ('vstwin', 'vstwin.c')
|
||||
d = fst.Object ('vsti', 'vsti.c')
|
||||
|
||||
Default([hackSDK,a,b,c,d])
|
||||
|
||||
env.Alias('tarball', env.Distribute (env['DISTTREE'], fst_src + ['SConscript'] ))
|
||||
|
||||
27
libs/fst/fst.c
Normal file
27
libs/fst/fst.c
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "fst.h"
|
||||
|
||||
|
||||
void
|
||||
default_fst_error_callback (const char *desc)
|
||||
{
|
||||
fprintf(stderr, "%s\n", desc);
|
||||
}
|
||||
|
||||
void (*fst_error_callback)(const char *desc) = &default_fst_error_callback;
|
||||
|
||||
void
|
||||
fst_error (const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char buffer[512];
|
||||
|
||||
va_start (ap, fmt);
|
||||
vsnprintf (buffer, sizeof(buffer), fmt, ap);
|
||||
fst_error_callback (buffer);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
|
||||
108
libs/fst/fst.h
Normal file
108
libs/fst/fst.h
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
#ifndef __fst_fst_h__
|
||||
#define __fst_fst_h__
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
|
||||
/**
|
||||
* Display FST error message.
|
||||
*
|
||||
* @param fmt printf-style formatting specification
|
||||
*/
|
||||
extern void fst_error (const char *fmt, ...);
|
||||
|
||||
/**
|
||||
* Set the @ref fst_error_callback for error message display.
|
||||
*
|
||||
* The FST library provides two built-in callbacks for this purpose:
|
||||
* default_fst_error_callback().
|
||||
*
|
||||
* The default will print the message (plus a newline) to stderr.
|
||||
*
|
||||
*/
|
||||
void fst_set_error_function (void (*func)(const char *));
|
||||
|
||||
#include <vst/AEffect.h>
|
||||
|
||||
typedef struct _FST FST;
|
||||
typedef struct _FSTHandle FSTHandle;
|
||||
typedef struct _FSTInfo FSTInfo;
|
||||
|
||||
struct _FSTInfo
|
||||
{
|
||||
char *name;
|
||||
int UniqueID;
|
||||
char *Category;
|
||||
|
||||
int numInputs;
|
||||
int numOutputs;
|
||||
int numParams;
|
||||
|
||||
int wantMidi;
|
||||
int wantEvents;
|
||||
int hasEditor;
|
||||
int canProcessReplacing; // what do we need this for ?
|
||||
|
||||
// i think we should save the parameter Info Stuff soon.
|
||||
// struct VstParameterInfo *infos;
|
||||
char **ParamNames;
|
||||
char **ParamLabels;
|
||||
};
|
||||
|
||||
struct _FSTHandle
|
||||
{
|
||||
void* dll;
|
||||
char* name;
|
||||
char* nameptr; /* ptr returned from strdup() etc. */
|
||||
AEffect* (*main_entry)(audioMasterCallback);
|
||||
|
||||
int plugincnt;
|
||||
};
|
||||
|
||||
struct _FST
|
||||
{
|
||||
AEffect* plugin;
|
||||
void* window; /* win32 HWND */
|
||||
int xid; /* X11 XWindow */
|
||||
FSTHandle* handle;
|
||||
int width;
|
||||
int height;
|
||||
int destroy;
|
||||
|
||||
struct _FST* next;
|
||||
|
||||
pthread_mutex_t lock;
|
||||
pthread_cond_t window_status_change;
|
||||
int been_activated;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int fst_init ();
|
||||
|
||||
extern FSTHandle* fst_load (const char*);
|
||||
extern int fst_unload (FSTHandle*);
|
||||
|
||||
extern FST* fst_instantiate (FSTHandle*, audioMasterCallback amc, void* userptr);
|
||||
extern void fst_close (FST*);
|
||||
|
||||
extern void fst_event_loop_remove_plugin (FST* fst);
|
||||
extern void fst_event_loop_add_plugin (FST* fst);
|
||||
|
||||
extern int fst_run_editor (FST*);
|
||||
extern void fst_destroy_editor (FST*);
|
||||
extern int fst_get_XID (FST*);
|
||||
|
||||
extern void fst_signal_handler (int sig, siginfo_t* info, void* context);
|
||||
|
||||
extern FSTInfo *fst_get_info( char *dllpathname );
|
||||
extern void fst_free_info( FSTInfo *info );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __fst_fst_h__ */
|
||||
266
libs/fst/fstinfofile.c
Normal file
266
libs/fst/fstinfofile.c
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
|
||||
#include "fst.h"
|
||||
#include "vst/aeffectx.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAX_STRING_LEN 256
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE !FALSE
|
||||
|
||||
static char *read_string( FILE *fp ) {
|
||||
char buf[MAX_STRING_LEN];
|
||||
|
||||
fgets( buf, MAX_STRING_LEN, fp );
|
||||
if( strlen( buf ) < MAX_STRING_LEN ) {
|
||||
|
||||
if( strlen(buf) )
|
||||
buf[strlen(buf)-1] = 0;
|
||||
|
||||
return strdup( buf );
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static FSTInfo *load_fst_info_file( char *filename ) {
|
||||
|
||||
FSTInfo *info = (FSTInfo *) malloc( sizeof( FSTInfo ) );
|
||||
FILE *fp;
|
||||
int i;
|
||||
|
||||
|
||||
if( info == NULL )
|
||||
return NULL;
|
||||
|
||||
fp = fopen( filename, "r" );
|
||||
|
||||
if( fp == NULL ) {
|
||||
free( info );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( (info->name = read_string( fp )) == NULL ) goto error;
|
||||
if( 1 != fscanf( fp, "%d\n", &info->UniqueID ) ) goto error;
|
||||
if( (info->Category = read_string( fp )) == NULL ) goto error;
|
||||
if( 1 != fscanf( fp, "%d\n", &info->numInputs ) ) goto error;
|
||||
if( 1 != fscanf( fp, "%d\n", &info->numOutputs ) ) goto error;
|
||||
if( 1 != fscanf( fp, "%d\n", &info->numParams ) ) goto error;
|
||||
if( 1 != fscanf( fp, "%d\n", &info->wantMidi ) ) goto error;
|
||||
if( 1 != fscanf( fp, "%d\n", &info->hasEditor ) ) goto error;
|
||||
if( 1 != fscanf( fp, "%d\n", &info->canProcessReplacing ) ) goto error;
|
||||
|
||||
if( (info->ParamNames = (char **) malloc( sizeof( char * ) * info->numParams )) == NULL ) goto error;
|
||||
for( i=0; i<info->numParams; i++ ) {
|
||||
if( (info->ParamNames[i] = read_string( fp )) == NULL ) goto error;
|
||||
}
|
||||
if( (info->ParamLabels = (char **) malloc( sizeof( char * ) * info->numParams )) == NULL ) goto error;
|
||||
for( i=0; i<info->numParams; i++ ) {
|
||||
if( (info->ParamLabels[i] = read_string( fp )) == NULL ) goto error;
|
||||
}
|
||||
|
||||
|
||||
fclose( fp );
|
||||
return info;
|
||||
|
||||
error:
|
||||
fclose( fp );
|
||||
free( info );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int save_fst_info_file( FSTInfo *info, char *filename ) {
|
||||
|
||||
FILE *fp;
|
||||
int i;
|
||||
|
||||
|
||||
if( info == NULL ) {
|
||||
fst_error( "info is NULL\n" );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
fp = fopen( filename, "w" );
|
||||
|
||||
if( fp == NULL ) {
|
||||
fst_error( "Cant write info file %s\n", filename );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
fprintf( fp, "%s\n", info->name );
|
||||
fprintf( fp, "%d\n", info->UniqueID );
|
||||
fprintf( fp, "%s\n", info->Category );
|
||||
fprintf( fp, "%d\n", info->numInputs );
|
||||
fprintf( fp, "%d\n", info->numOutputs );
|
||||
fprintf( fp, "%d\n", info->numParams );
|
||||
fprintf( fp, "%d\n", info->wantMidi );
|
||||
fprintf( fp, "%d\n", info->hasEditor );
|
||||
fprintf( fp, "%d\n", info->canProcessReplacing );
|
||||
|
||||
for( i=0; i<info->numParams; i++ ) {
|
||||
fprintf( fp, "%s\n", info->ParamNames[i] );
|
||||
}
|
||||
for( i=0; i<info->numParams; i++ ) {
|
||||
fprintf( fp, "%s\n", info->ParamLabels[i] );
|
||||
}
|
||||
|
||||
|
||||
fclose( fp );
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static char *fst_dllpath_to_infopath( char *dllpath ) {
|
||||
char *retval;
|
||||
if( strstr( dllpath, ".dll" ) == NULL ) return NULL;
|
||||
|
||||
retval = strdup( dllpath );
|
||||
sprintf( retval + strlen(retval) - 4, ".fst" );
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int fst_info_file_is_valid( char *dllpath ) {
|
||||
struct stat dllstat, fststat;
|
||||
char *fstpath = fst_dllpath_to_infopath( dllpath );
|
||||
|
||||
if( !fstpath ) return FALSE;
|
||||
|
||||
if( stat( dllpath, &dllstat ) ){ fst_error( "dll path %s invalid\n", dllpath ); return TRUE; }
|
||||
if( stat( fstpath, &fststat ) ) return FALSE;
|
||||
|
||||
free( fstpath );
|
||||
if( dllstat.st_mtime > fststat.st_mtime )
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int fst_can_midi( FST *fst ) {
|
||||
AEffect *plugin = fst->plugin;
|
||||
int vst_version = plugin->dispatcher (plugin, effGetVstVersion, 0, 0, NULL, 0.0f);
|
||||
|
||||
if (vst_version >= 2) {
|
||||
|
||||
/* should we send it VST events (i.e. MIDI) */
|
||||
|
||||
if ((plugin->flags & effFlagsIsSynth) ||
|
||||
(plugin->dispatcher (plugin, effCanDo, 0, 0,(void*) "receiveVstEvents", 0.0f) > 0))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
static FSTInfo *fst_info_from_plugin( FST *fst ) {
|
||||
FSTInfo *info = (FSTInfo *) malloc( sizeof( FSTInfo ) );
|
||||
AEffect *plugin;
|
||||
int i;
|
||||
|
||||
if( ! fst ) {
|
||||
fst_error( "fst is NULL\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( ! info ) return NULL;
|
||||
|
||||
plugin = fst->plugin;
|
||||
|
||||
|
||||
info->name = strdup(fst->handle->name );
|
||||
info->UniqueID = plugin->uniqueID;
|
||||
info->Category = strdup( "None" ); // FIXME:
|
||||
info->numInputs = plugin->numInputs;
|
||||
info->numOutputs = plugin->numOutputs;
|
||||
info->numParams = plugin->numParams;
|
||||
info->wantMidi = fst_can_midi( fst );
|
||||
info->hasEditor = plugin->flags & effFlagsHasEditor ? TRUE : FALSE;
|
||||
info->canProcessReplacing = plugin->flags & effFlagsCanReplacing ? TRUE : FALSE;
|
||||
|
||||
info->ParamNames = (char **) malloc( sizeof( char * ) * info->numParams );
|
||||
info->ParamLabels = (char **) malloc( sizeof( char * ) * info->numParams );
|
||||
for( i=0; i<info->numParams; i++ ) {
|
||||
char name[20];
|
||||
char label[9];
|
||||
plugin->dispatcher (plugin,
|
||||
effGetParamName,
|
||||
i, 0, name, 0);
|
||||
|
||||
plugin->dispatcher (plugin,
|
||||
effGetParamLabel,
|
||||
i, 0, label, 0);
|
||||
|
||||
info->ParamNames[i] = strdup( name );
|
||||
info->ParamLabels[i] = strdup( label );
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
// most simple one :) could be sufficient....
|
||||
static long simple_master_callback( AEffect *fx, long opcode, long index, long value, void *ptr, float opt ) {
|
||||
if( opcode == audioMasterVersion )
|
||||
return 2;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
FSTInfo *fst_get_info( char *dllpath ) {
|
||||
|
||||
if( fst_info_file_is_valid( dllpath ) ) {
|
||||
FSTInfo *info;
|
||||
char *fstpath = fst_dllpath_to_infopath( dllpath );
|
||||
|
||||
info = load_fst_info_file( fstpath );
|
||||
free( fstpath );
|
||||
return info;
|
||||
|
||||
} else {
|
||||
|
||||
FSTHandle *h;
|
||||
FST *fst;
|
||||
FSTInfo *info;
|
||||
char *fstpath;
|
||||
|
||||
if( !(h = fst_load( dllpath )) ) return NULL;
|
||||
if( !(fst = fst_instantiate( h, simple_master_callback, NULL )) ) {
|
||||
fst_unload( h );
|
||||
fst_error( "instantiate failed\n" );
|
||||
return NULL;
|
||||
}
|
||||
fstpath = fst_dllpath_to_infopath( dllpath );
|
||||
if( !fstpath ) {
|
||||
fst_close( fst );
|
||||
fst_unload( h );
|
||||
fst_error( "get fst filename failed\n" );
|
||||
return NULL;
|
||||
}
|
||||
info = fst_info_from_plugin( fst );
|
||||
save_fst_info_file( info, fstpath );
|
||||
|
||||
free( fstpath );
|
||||
fst_close( fst );
|
||||
fst_unload( h );
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
void fst_free_info( FSTInfo *info ) {
|
||||
|
||||
int i;
|
||||
|
||||
for( i=0; i<info->numParams; i++ ) {
|
||||
free( info->ParamNames[i] );
|
||||
free( info->ParamLabels[i] );
|
||||
}
|
||||
free( info->name );
|
||||
free( info->Category );
|
||||
free( info );
|
||||
}
|
||||
|
||||
|
||||
35
libs/fst/jackvst.h
Normal file
35
libs/fst/jackvst.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef __jack_vst_h__
|
||||
#define __jack_vst_h__
|
||||
|
||||
#include </usr/include/sys/types.h>
|
||||
#include </usr/include/sys/time.h>
|
||||
#include <jack/jack.h>
|
||||
#include <jack/ringbuffer.h>
|
||||
#include <fst.h>
|
||||
#include <alsa/asoundlib.h>
|
||||
|
||||
typedef struct _JackVST JackVST;
|
||||
|
||||
struct _JackVST {
|
||||
jack_client_t *client;
|
||||
FSTHandle* handle;
|
||||
FST* fst;
|
||||
float **ins;
|
||||
float **outs;
|
||||
jack_port_t **inports;
|
||||
jack_port_t **outports;
|
||||
void* userdata;
|
||||
int bypassed;
|
||||
int muted;
|
||||
|
||||
int resume_called;
|
||||
/* For VST/i support */
|
||||
|
||||
pthread_t midi_thread;
|
||||
snd_seq_t* seq;
|
||||
int midiquit;
|
||||
jack_ringbuffer_t* event_queue;
|
||||
struct VstEvents* events;
|
||||
};
|
||||
|
||||
#endif /* __jack_vst_h__ */
|
||||
181
libs/fst/vsti.c
Normal file
181
libs/fst/vsti.c
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* VST instrument support
|
||||
*
|
||||
* Derived from code that was marked:
|
||||
* Copyright (C) Kjetil S. Matheussen 2004 (k.s.matheussen@notam02.no)
|
||||
* Alsa-seq midi-code made by looking at the jack-rack source made by Bob Ham.
|
||||
*
|
||||
* 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: vsti.c,v 1.2 2004/04/07 01:56:23 pauld Exp $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <jackvst.h>
|
||||
#include <vst/aeffectx.h>
|
||||
|
||||
snd_seq_t *
|
||||
create_sequencer (const char* client_name, bool isinput)
|
||||
{
|
||||
snd_seq_t * seq;
|
||||
int err;
|
||||
|
||||
if ((err = snd_seq_open (&seq, "default", SND_SEQ_OPEN_DUPLEX, 0)) != 0) {
|
||||
fst_error ("Could not open ALSA sequencer, aborting\n\n%s\n\n"
|
||||
"Make sure you have configure ALSA properly and that\n"
|
||||
"/proc/asound/seq/clients exists and contains relevant\n"
|
||||
"devices (%s).",
|
||||
snd_strerror (err));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snd_seq_set_client_name (seq, client_name);
|
||||
|
||||
if ((err = snd_seq_create_simple_port (seq, isinput? "Input" : "Output",
|
||||
(isinput? SND_SEQ_PORT_CAP_WRITE: SND_SEQ_PORT_CAP_READ)| SND_SEQ_PORT_CAP_DUPLEX |
|
||||
SND_SEQ_PORT_CAP_SUBS_READ|SND_SEQ_PORT_CAP_SUBS_WRITE,
|
||||
SND_SEQ_PORT_TYPE_APPLICATION|SND_SEQ_PORT_TYPE_SPECIFIC)) != 0) {
|
||||
fst_error ("Could not create ALSA port: %s", snd_strerror (err));
|
||||
snd_seq_close(seq);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return seq;
|
||||
}
|
||||
|
||||
static void
|
||||
queue_midi (JackVST *jvst, int val1, int val2, int val3)
|
||||
{
|
||||
struct VstMidiEvent *pevent;
|
||||
jack_ringbuffer_data_t vec[2];
|
||||
|
||||
jack_ringbuffer_get_write_vector (jvst->event_queue, vec);
|
||||
|
||||
if (vec[0].len < sizeof (struct VstMidiEvent)) {
|
||||
fst_error ("event queue has no write space");
|
||||
return;
|
||||
}
|
||||
|
||||
pevent = (struct VstMidiEevent *) vec[0].buf;
|
||||
|
||||
// printf("note: %d\n",note);
|
||||
|
||||
pevent->type = kVstMidiType;
|
||||
pevent->byteSize = 24;
|
||||
pevent->deltaFrames = 0;
|
||||
pevent->flags = 0;
|
||||
pevent->detune = 0;
|
||||
pevent->noteLength = 0;
|
||||
pevent->noteOffset = 0;
|
||||
pevent->reserved1 = 0;
|
||||
pevent->reserved2 = 0;
|
||||
pevent->noteOffVelocity = 0;
|
||||
pevent->midiData[0] = val1;
|
||||
pevent->midiData[1] = val2;
|
||||
pevent->midiData[2] = val3;
|
||||
pevent->midiData[3] = 0;
|
||||
|
||||
//printf("Sending: %x %x %x\n",val1,val2,val3);
|
||||
|
||||
jack_ringbuffer_write_advance (jvst->event_queue, sizeof (struct VstMidiEvent));
|
||||
}
|
||||
|
||||
void *midireceiver(void *arg)
|
||||
{
|
||||
snd_seq_event_t *event;
|
||||
JackVST *jvst = (JackVST* )arg;
|
||||
int val;
|
||||
|
||||
while (1) {
|
||||
|
||||
snd_seq_event_input (jvst->seq, &event);
|
||||
|
||||
if (jvst->midiquit) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch(event->type){
|
||||
case SND_SEQ_EVENT_NOTEON:
|
||||
queue_midi(jvst,0x90+event->data.note.channel,event->data.note.note,event->data.note.velocity);
|
||||
//printf("Noteon, channel: %d note: %d vol: %d\n",event->data.note.channel,event->data.note.note,event->data.note.velocity);
|
||||
break;
|
||||
case SND_SEQ_EVENT_NOTEOFF:
|
||||
queue_midi(jvst,0x80+event->data.note.channel,event->data.note.note,0);
|
||||
//printf("Noteoff, channel: %d note: %d vol: %d\n",event->data.note.channel,event->data.note.note,event->data.note.velocity);
|
||||
break;
|
||||
case SND_SEQ_EVENT_KEYPRESS:
|
||||
//printf("Keypress, channel: %d note: %d vol: %d\n",event->data.note.channel,event->data.note.note,event->data.note.velocity);
|
||||
queue_midi(jvst,0xa0+event->data.note.channel,event->data.note.note,event->data.note.velocity);
|
||||
break;
|
||||
case SND_SEQ_EVENT_CONTROLLER:
|
||||
queue_midi(jvst,0xb0+event->data.control.channel,event->data.control.param,event->data.control.value);
|
||||
//printf("Control: %d %d %d\n",event->data.control.channel,event->data.control.param,event->data.control.value);
|
||||
break;
|
||||
case SND_SEQ_EVENT_PITCHBEND:
|
||||
val=event->data.control.value + 0x2000;
|
||||
queue_midi(jvst,0xe0+event->data.control.channel,val&127,val>>7);
|
||||
//printf("Pitch: %d %d %d\n",event->data.control.channel,event->data.control.param,event->data.control.value);
|
||||
break;
|
||||
case SND_SEQ_EVENT_CHANPRESS:
|
||||
//printf("chanpress: %d %d %d\n",event->data.control.channel,event->data.control.param,event->data.control.value);
|
||||
queue_midi(jvst,0xd0+event->data.control.channel,event->data.control.value,0);
|
||||
break;
|
||||
case SND_SEQ_EVENT_PGMCHANGE:
|
||||
//printf("pgmchange: %d %d %d\n",event->data.control.channel,event->data.control.param,event->data.control.value);
|
||||
queue_midi(jvst,0xc0+event->data.control.channel,event->data.control.value,0);
|
||||
break;
|
||||
default:
|
||||
//printf("Unknown type: %d\n",event->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void stop_midireceiver (JackVST *jvst)
|
||||
{
|
||||
int err;
|
||||
snd_seq_event_t event;
|
||||
snd_seq_t *seq2 = create_sequencer ("jfstquit", true);
|
||||
|
||||
jvst->midiquit = 1;
|
||||
|
||||
snd_seq_connect_to (seq2, 0, snd_seq_client_id (jvst->seq),0);
|
||||
snd_seq_ev_clear (&event);
|
||||
snd_seq_ev_set_direct (&event);
|
||||
snd_seq_ev_set_subs (&event);
|
||||
snd_seq_ev_set_source (&event, 0);
|
||||
snd_seq_ev_set_controller (&event,1,0x80,50);
|
||||
|
||||
if ((err = snd_seq_event_output (seq2, &event)) < 0) {
|
||||
fst_error ("cannot send stop event to midi thread: %s\n",
|
||||
snd_strerror (err));
|
||||
}
|
||||
|
||||
snd_seq_drain_output (seq2);
|
||||
snd_seq_close (seq2);
|
||||
pthread_join (jvst->midi_thread,NULL);
|
||||
snd_seq_close (jvst->seq);
|
||||
}
|
||||
|
||||
|
||||
|
||||
583
libs/fst/vstwin.c
Normal file
583
libs/fst/vstwin.c
Normal file
|
|
@ -0,0 +1,583 @@
|
|||
#include <stdio.h>
|
||||
#include <libgen.h>
|
||||
#include <windows.h>
|
||||
#include <winnt.h>
|
||||
#include <wine/exception.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
|
||||
//#include <x11/xlib.h>
|
||||
//#include <x11/xresource.h>
|
||||
//#include <x11/xutil.h>
|
||||
//#include <x11/xatom.h>
|
||||
|
||||
#include "fst.h"
|
||||
|
||||
|
||||
struct ERect{
|
||||
short top;
|
||||
short left;
|
||||
short bottom;
|
||||
short right;
|
||||
};
|
||||
|
||||
static pthread_mutex_t plugin_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static FST* fst_first = NULL;
|
||||
|
||||
DWORD gui_thread_id = 0;
|
||||
|
||||
static char* message_name (int message)
|
||||
{
|
||||
switch (message) {
|
||||
case 0x0000:
|
||||
return "WM_NULL";
|
||||
|
||||
case 0x0001:
|
||||
return "WM_CREATE";
|
||||
|
||||
case 0x0002:
|
||||
return "WM_DESTROY";
|
||||
|
||||
case 0x0003:
|
||||
return "WM_MOVE";
|
||||
|
||||
case 0x0004:
|
||||
return "WM_SIZEWAIT";
|
||||
|
||||
case 0x0005:
|
||||
return "WM_SIZE";
|
||||
|
||||
case 0x0006:
|
||||
return "WM_ACTIVATE";
|
||||
|
||||
case 0x0007:
|
||||
return "WM_SETFOCUS";
|
||||
|
||||
case 0x0008:
|
||||
return "WM_KILLFOCUS";
|
||||
|
||||
case 0x0009:
|
||||
return "WM_SETVISIBLE";
|
||||
|
||||
case 0x000a:
|
||||
return "WM_ENABLE";
|
||||
|
||||
case 0x000b:
|
||||
return "WM_SETREDRAW";
|
||||
|
||||
case 0x000c:
|
||||
return "WM_SETTEXT";
|
||||
|
||||
case 0x000d:
|
||||
return "WM_GETTEXT";
|
||||
|
||||
case 0x000e:
|
||||
return "WM_GETTEXTLENGTH";
|
||||
|
||||
case 0x000f:
|
||||
return "WM_PAINT";
|
||||
|
||||
case 0x0010:
|
||||
return "WM_CLOSE";
|
||||
|
||||
case 0x0011:
|
||||
return "WM_QUERYENDSESSION";
|
||||
|
||||
case 0x0012:
|
||||
return "WM_QUIT";
|
||||
|
||||
case 0x0013:
|
||||
return "WM_QUERYOPEN";
|
||||
|
||||
case 0x0014:
|
||||
return "WM_ERASEBKGND";
|
||||
|
||||
case 0x0015:
|
||||
return "WM_SYSCOLORCHANGE";
|
||||
|
||||
case 0x0016:
|
||||
return "WM_ENDSESSION";
|
||||
|
||||
case 0x0017:
|
||||
return "WM_SYSTEMERROR";
|
||||
|
||||
case 0x0018:
|
||||
return "WM_SHOWWINDOW";
|
||||
|
||||
case 0x0019:
|
||||
return "WM_CTLCOLOR";
|
||||
|
||||
case 0x001a:
|
||||
return "WM_WININICHANGE";
|
||||
|
||||
case 0x001b:
|
||||
return "WM_DEVMODECHANGE";
|
||||
|
||||
case 0x001c:
|
||||
return "WM_ACTIVATEAPP";
|
||||
|
||||
case 0x001d:
|
||||
return "WM_FONTCHANGE";
|
||||
|
||||
case 0x001e:
|
||||
return "WM_TIMECHANGE";
|
||||
|
||||
case 0x001f:
|
||||
return "WM_CANCELMODE";
|
||||
|
||||
case 0x0020:
|
||||
return "WM_SETCURSOR";
|
||||
|
||||
case 0x0021:
|
||||
return "WM_MOUSEACTIVATE";
|
||||
|
||||
case 0x0022:
|
||||
return "WM_CHILDACTIVATE";
|
||||
|
||||
case 0x0023:
|
||||
return "WM_QUEUESYNC";
|
||||
|
||||
case 0x0024:
|
||||
return "WM_GETMINMAXINFO";
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "--- OTHER ---";
|
||||
}
|
||||
|
||||
static LRESULT WINAPI
|
||||
my_window_proc (HWND w, UINT msg, WPARAM wp, LPARAM lp)
|
||||
{
|
||||
FST* fst;
|
||||
|
||||
// if (msg != WM_TIMER) {
|
||||
// fst_error ("window callback handler, msg = 0x%x (%s) win=%p\n", msg, message_name (msg), w);
|
||||
// }
|
||||
|
||||
switch (msg) {
|
||||
case WM_KEYUP:
|
||||
case WM_KEYDOWN:
|
||||
break;
|
||||
|
||||
case WM_CLOSE:
|
||||
PostQuitMessage (0);
|
||||
|
||||
case WM_DESTROY:
|
||||
case WM_NCDESTROY:
|
||||
/* we should never get these */
|
||||
//return 0;
|
||||
break;
|
||||
|
||||
case WM_PAINT:
|
||||
if ((fst = GetPropA (w, "fst_ptr")) != NULL) {
|
||||
if (fst->window && !fst->been_activated) {
|
||||
fst->been_activated = TRUE;
|
||||
pthread_cond_signal (&fst->window_status_change);
|
||||
pthread_mutex_unlock (&fst->lock);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProcA (w, msg, wp, lp );
|
||||
}
|
||||
|
||||
static FST*
|
||||
fst_new ()
|
||||
{
|
||||
FST* fst = (FST*) calloc (1, sizeof (FST));
|
||||
|
||||
pthread_mutex_init (&fst->lock, NULL);
|
||||
pthread_cond_init (&fst->window_status_change, NULL);
|
||||
|
||||
return fst;
|
||||
}
|
||||
|
||||
static FSTHandle*
|
||||
fst_handle_new ()
|
||||
{
|
||||
FSTHandle* fst = (FSTHandle*) calloc (1, sizeof (FSTHandle));
|
||||
return fst;
|
||||
}
|
||||
|
||||
int
|
||||
fst_create_editor (FST* fst)
|
||||
{
|
||||
HMODULE hInst;
|
||||
HWND window;
|
||||
|
||||
/* "guard point" to trap errors that occur during plugin loading */
|
||||
|
||||
/* Note: fst->lock is held while this function is called */
|
||||
|
||||
if (!(fst->plugin->flags & effFlagsHasEditor)) {
|
||||
fst_error ("Plugin \"%s\" has no editor", fst->handle->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((hInst = GetModuleHandleA (NULL)) == NULL) {
|
||||
fst_error ("can't get module handle");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// if ((window = CreateWindowExA (WS_EX_TOOLWINDOW | WS_EX_TRAYWINDOW, "FST", fst->handle->name,
|
||||
if ((window = CreateWindowExA (0, "FST", fst->handle->name,
|
||||
(WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX),
|
||||
0, 0, 1, 1,
|
||||
NULL, NULL,
|
||||
hInst,
|
||||
NULL)) == NULL) {
|
||||
fst_error ("cannot create editor window");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!SetPropA (window, "fst_ptr", fst)) {
|
||||
fst_error ("cannot set fst_ptr on window");
|
||||
}
|
||||
|
||||
fst->window = window;
|
||||
fst->xid = (int) GetPropA (window, "__wine_x11_whole_window");
|
||||
|
||||
{
|
||||
struct ERect* er;
|
||||
|
||||
ShowWindow (fst->window, SW_SHOW);
|
||||
|
||||
fst->plugin->dispatcher (fst->plugin, effEditOpen, 0, 0, fst->window, 0 );
|
||||
fst->plugin->dispatcher (fst->plugin, effEditGetRect, 0, 0, &er, 0 );
|
||||
|
||||
fst->width = er->right-er->left;
|
||||
fst->height = er->bottom-er->top;
|
||||
|
||||
SetWindowPos (fst->window, 0, 0, 0, er->right-er->left+8, er->bottom-er->top+26, SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOZORDER);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
fst_destroy_editor (FST* fst)
|
||||
{
|
||||
pthread_mutex_lock (&fst->lock);
|
||||
if (fst->window) {
|
||||
fst->destroy = TRUE;
|
||||
if (!PostThreadMessageA (gui_thread_id, WM_USER, 0, 0)) {
|
||||
fst_error ("could not post message to gui thread");
|
||||
}
|
||||
pthread_cond_wait (&fst->window_status_change, &fst->lock);
|
||||
|
||||
}
|
||||
pthread_mutex_unlock (&fst->lock);
|
||||
}
|
||||
|
||||
void
|
||||
fst_event_loop_remove_plugin (FST* fst)
|
||||
{
|
||||
FST* p;
|
||||
FST* prev;
|
||||
|
||||
for (p = fst_first, prev = NULL; p->next; prev = p, p = p->next) {
|
||||
if (p == fst) {
|
||||
if (prev) {
|
||||
prev->next = p->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fst_first == fst) {
|
||||
fst_first = fst_first->next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void debreak( void ) { printf( "debreak\n" ); }
|
||||
|
||||
DWORD WINAPI gui_event_loop (LPVOID param)
|
||||
{
|
||||
MSG msg;
|
||||
FST* fst;
|
||||
HMODULE hInst;
|
||||
HWND window;
|
||||
|
||||
gui_thread_id = GetCurrentThreadId ();
|
||||
|
||||
/* create a dummy window for timer events */
|
||||
|
||||
if ((hInst = GetModuleHandleA (NULL)) == NULL) {
|
||||
fst_error ("can't get module handle");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((window = CreateWindowExA (0, "FST", "dummy",
|
||||
WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
NULL, NULL,
|
||||
hInst,
|
||||
NULL )) == NULL) {
|
||||
fst_error ("cannot create dummy timer window");
|
||||
}
|
||||
|
||||
if (!SetTimer (window, 1000, 100, NULL)) {
|
||||
fst_error ("cannot set timer on dummy window");
|
||||
}
|
||||
|
||||
while (GetMessageA (&msg, NULL, 0,0)) {
|
||||
|
||||
if( msg.message == WM_KEYDOWN ) debreak();
|
||||
TranslateMessage( &msg );
|
||||
DispatchMessageA (&msg);
|
||||
|
||||
/* handle window creation requests, destroy requests,
|
||||
and run idle callbacks
|
||||
*/
|
||||
|
||||
|
||||
if( msg.message == WM_TIMER ) {
|
||||
pthread_mutex_lock (&plugin_mutex);
|
||||
again:
|
||||
for (fst = fst_first; fst; fst = fst->next) {
|
||||
|
||||
if (fst->destroy) {
|
||||
if (fst->window) {
|
||||
fst->plugin->dispatcher( fst->plugin, effEditClose, 0, 0, NULL, 0.0 );
|
||||
CloseWindow (fst->window);
|
||||
fst->window = NULL;
|
||||
fst->destroy = FALSE;
|
||||
}
|
||||
fst_event_loop_remove_plugin (fst);
|
||||
fst->been_activated = FALSE;
|
||||
pthread_mutex_lock (&fst->lock);
|
||||
pthread_cond_signal (&fst->window_status_change);
|
||||
pthread_mutex_unlock (&fst->lock);
|
||||
goto again;
|
||||
}
|
||||
|
||||
if (fst->window == NULL) {
|
||||
pthread_mutex_lock (&fst->lock);
|
||||
if (fst_create_editor (fst)) {
|
||||
fst_error ("cannot create editor for plugin %s", fst->handle->name);
|
||||
fst_event_loop_remove_plugin (fst);
|
||||
pthread_cond_signal (&fst->window_status_change);
|
||||
pthread_mutex_unlock (&fst->lock);
|
||||
goto again;
|
||||
}
|
||||
/* condition/unlock handled when we receive WM_ACTIVATE */
|
||||
}
|
||||
|
||||
fst->plugin->dispatcher (fst->plugin, effEditIdle, 0, 0, NULL, 0);
|
||||
}
|
||||
pthread_mutex_unlock (&plugin_mutex);
|
||||
}
|
||||
}
|
||||
fst_error ("FST GUI event loop has quit!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
fst_init ()
|
||||
{
|
||||
WNDCLASSA wc;
|
||||
HMODULE hInst;
|
||||
|
||||
if ((hInst = GetModuleHandleA (NULL)) == NULL) {
|
||||
fst_error ("can't get module handle");
|
||||
return -1;
|
||||
}
|
||||
wc.style = 0;
|
||||
wc.lpfnWndProc = my_window_proc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = hInst;
|
||||
wc.hIcon = LoadIconA( hInst, "FST");
|
||||
wc.hCursor = LoadCursorA( NULL, IDI_APPLICATION );
|
||||
wc.hbrBackground = GetStockObject( BLACK_BRUSH );
|
||||
wc.lpszMenuName = "MENU_FST";
|
||||
wc.lpszClassName = "FST";
|
||||
|
||||
if (!RegisterClassA(&wc)){
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (CreateThread (NULL, 0, gui_event_loop, NULL, 0, NULL) == NULL) {
|
||||
fst_error ("could not create new thread proxy");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
fst_run_editor (FST* fst)
|
||||
{
|
||||
/* Add the FST to the list of all that should be handled by the GUI thread */
|
||||
|
||||
pthread_mutex_lock (&plugin_mutex);
|
||||
|
||||
if (fst_first == NULL) {
|
||||
fst_first = fst;
|
||||
} else {
|
||||
FST* p = fst_first;
|
||||
while (p->next) {
|
||||
p = p->next;
|
||||
}
|
||||
p->next = fst;
|
||||
}
|
||||
|
||||
if (!PostThreadMessageA (gui_thread_id, WM_USER, 0, 0)) {
|
||||
fst_error ("could not post message to gui thread");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock (&plugin_mutex);
|
||||
|
||||
/* wait for the plugin editor window to be created (or not) */
|
||||
|
||||
pthread_mutex_lock (&fst->lock);
|
||||
if (!fst->window) {
|
||||
pthread_cond_wait (&fst->window_status_change, &fst->lock);
|
||||
}
|
||||
pthread_mutex_unlock (&fst->lock);
|
||||
|
||||
if (!fst->window) {
|
||||
fst_error ("no window created for VST plugin editor");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
FSTHandle*
|
||||
fst_load (const char *path)
|
||||
{
|
||||
char* buf;
|
||||
FSTHandle* fhandle;
|
||||
char* period;
|
||||
|
||||
fhandle = fst_handle_new ();
|
||||
|
||||
// XXX: Would be nice to find the correct call for this.
|
||||
// if the user does not configure Z: to be / we are doomed :(
|
||||
|
||||
if (strstr (path, ".dll") == NULL) {
|
||||
|
||||
buf = (char *) malloc (strlen (path) + 7);
|
||||
|
||||
if( path[0] == '/' ) {
|
||||
sprintf (buf, "Z:%s.dll", path);
|
||||
} else {
|
||||
sprintf (buf, "%s.dll", path);
|
||||
}
|
||||
|
||||
fhandle->nameptr = strdup (path);
|
||||
|
||||
} else {
|
||||
|
||||
buf = (char *) malloc (strlen (path) + 3);
|
||||
|
||||
if( path[0] == '/' ) {
|
||||
sprintf (buf, "Z:%s", path);
|
||||
} else {
|
||||
sprintf (buf, "%s", path);
|
||||
}
|
||||
|
||||
fhandle->nameptr = strdup (path);
|
||||
}
|
||||
|
||||
fhandle->name = basename (fhandle->nameptr);
|
||||
|
||||
/* strip off .dll */
|
||||
|
||||
if ((period = strrchr (fhandle->name, '.')) != NULL) {
|
||||
*period = '\0';
|
||||
}
|
||||
|
||||
if ((fhandle->dll = LoadLibraryA (buf)) == NULL) {
|
||||
fst_unload (fhandle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((fhandle->main_entry = GetProcAddress (fhandle->dll, "main")) == NULL) {
|
||||
fst_unload (fhandle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return fhandle;
|
||||
}
|
||||
|
||||
int
|
||||
fst_unload (FSTHandle* fhandle)
|
||||
{
|
||||
if (fhandle->plugincnt) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fhandle->dll) {
|
||||
FreeLibrary (fhandle->dll);
|
||||
fhandle->dll = NULL;
|
||||
}
|
||||
|
||||
if (fhandle->nameptr) {
|
||||
free (fhandle->nameptr);
|
||||
fhandle->name = NULL;
|
||||
}
|
||||
|
||||
free (fhandle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
FST*
|
||||
fst_instantiate (FSTHandle* fhandle, audioMasterCallback amc, void* userptr)
|
||||
{
|
||||
FST* fst = fst_new ();
|
||||
|
||||
if( fhandle == NULL ) {
|
||||
fst_error( "the handle was NULL\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((fst->plugin = fhandle->main_entry (amc)) == NULL) {
|
||||
fst_error ("%s could not be instantiated\n", fhandle->name);
|
||||
free (fst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fst->handle = fhandle;
|
||||
fst->plugin->user = userptr;
|
||||
|
||||
if (fst->plugin->magic != kEffectMagic) {
|
||||
fst_error ("%s is not a VST plugin\n", fhandle->name);
|
||||
free (fst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fst->plugin->dispatcher (fst->plugin, effOpen, 0, 0, 0, 0);
|
||||
//fst->plugin->dispatcher (fst->plugin, effMainsChanged, 0, 0, NULL, 0);
|
||||
|
||||
fst->handle->plugincnt++;
|
||||
|
||||
return fst;
|
||||
}
|
||||
|
||||
void
|
||||
fst_close (FST* fst)
|
||||
{
|
||||
fst_destroy_editor (fst);
|
||||
|
||||
fst->plugin->dispatcher (fst->plugin, effMainsChanged, 0, 0, NULL, 0);
|
||||
fst->plugin->dispatcher (fst->plugin, effClose, 0, 0, 0, 0);
|
||||
|
||||
if (fst->handle->plugincnt) {
|
||||
--fst->handle->plugincnt;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
fst_get_XID (FST* fst)
|
||||
{
|
||||
return fst->xid;
|
||||
}
|
||||
|
|
@ -43,6 +43,7 @@
|
|||
using namespace Gtkmm2ext;
|
||||
using namespace Gtk;
|
||||
using namespace Glib;
|
||||
using namespace PBD;
|
||||
using std::map;
|
||||
|
||||
pthread_t UI::gui_thread;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
#include <gtkmm2ext/selector.h>
|
||||
#include <gtkmm2ext/utils.h>
|
||||
#include <pbd/pathscanner.h>
|
||||
#include <pbd/error.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Gtkmm2ext;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace MIDI;
|
||||
using namespace PBD;
|
||||
|
||||
string *FD_MidiPort::midi_dirpath = 0;
|
||||
string *FD_MidiPort::midi_filename_pattern = 0;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
using namespace sigc;
|
||||
using namespace MIDI;
|
||||
using namespace PBD;
|
||||
|
||||
Controllable::Controllable (Port *p, bool is_bistate)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace MIDI;
|
||||
using namespace PBD;
|
||||
|
||||
Manager *Manager::theManager = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
using namespace std;
|
||||
using namespace MIDI;
|
||||
using namespace PBD;
|
||||
|
||||
static std::map<int,string> mmc_cmd_map;
|
||||
static void build_mmc_cmd_map ()
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ TextReceiver text_receiver ("mmctest");
|
|||
#include "midi++/mmc.h"
|
||||
|
||||
using namespace MIDI;
|
||||
using namespace PBD;
|
||||
|
||||
Port *port;
|
||||
PortRequest midi_device;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ pbd3 = env.Copy()
|
|||
|
||||
domain = 'libpbd'
|
||||
|
||||
pbd3.Append(DOMAIN=domain,MAJOR=3,MINOR=2,MICRO=0)
|
||||
pbd3.Append(DOMAIN=domain,MAJOR=4,MINOR=0,MICRO=0)
|
||||
pbd3.Append(CXXFLAGS="-DPACKAGE=\\\"" + domain + "\\\"")
|
||||
pbd3.Append(CXXFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE")
|
||||
pbd3.Append(CXXFLAGS="-DLIBSIGC_DISABLE_DEPRECATED")
|
||||
|
|
@ -21,8 +21,8 @@ pbd3_files = Split("""
|
|||
basename.cc
|
||||
base_ui.cc
|
||||
convert.cc
|
||||
dirname.cc
|
||||
dmalloc.cc
|
||||
error.cc
|
||||
mountpoint.cc
|
||||
pathscanner.cc
|
||||
pool.cc
|
||||
|
|
@ -33,7 +33,6 @@ strsplit.cc
|
|||
textreceiver.cc
|
||||
transmitter.cc
|
||||
undo.cc
|
||||
unescape.cc
|
||||
version.cc
|
||||
whitespace.cc
|
||||
xml++.cc
|
||||
|
|
@ -46,7 +45,7 @@ if conf.CheckCHeader('execinfo.h'):
|
|||
conf.env.Append(CXXFLAGS="-DHAVE_EXECINFO")
|
||||
pbd3 = conf.Finish()
|
||||
|
||||
pbd3.Merge ([ libraries['sigc2'], libraries['xml'] ])
|
||||
pbd3.Merge ([ libraries['sigc2'], libraries['xml'], libraries['glibmm2'], libraries['glib2'] ])
|
||||
|
||||
pbd3.VersionBuild(['version.cc','pbd/version.h'], 'SConscript')
|
||||
|
||||
|
|
@ -60,7 +59,7 @@ if env['NLS']:
|
|||
env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libpbd3))
|
||||
|
||||
env.Alias('tarball', env.Distribute (env['DISTTREE'],
|
||||
[ 'SConscript', 'i18n.h' ] +
|
||||
[ 'SConscript', 'i18n.h', 'gettext.h', 'pbd/abstract_ui.cc' ] +
|
||||
pbd3_files +
|
||||
glob.glob('po/*.po') +
|
||||
glob.glob('pbd/*.h')))
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include "i18n.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace PBD;
|
||||
|
||||
uint32_t BaseUI::rt_bit = 1;
|
||||
BaseUI::RequestType BaseUI::CallSlot = BaseUI::new_request_type();
|
||||
|
|
|
|||
|
|
@ -2,37 +2,10 @@
|
|||
#include <string.h>
|
||||
#include <pbd/basename.h>
|
||||
|
||||
char *
|
||||
PBD::basename (const char *path)
|
||||
|
||||
{
|
||||
char *slash;
|
||||
|
||||
if ((slash = strrchr (path, '/')) == 0) {
|
||||
return strdup (path);
|
||||
}
|
||||
|
||||
if (*(slash+1) == '\0') {
|
||||
return strdup ("");
|
||||
}
|
||||
|
||||
return strdup (slash+1);
|
||||
}
|
||||
|
||||
// implement this using Glib::path_get_basename
|
||||
std::string
|
||||
PBD::basename (const std::string str)
|
||||
{
|
||||
std::string::size_type slash = str.find_last_of ('/');
|
||||
|
||||
if (slash == std::string::npos) {
|
||||
return str;
|
||||
}
|
||||
|
||||
return str.substr (slash+1);
|
||||
}
|
||||
|
||||
std::string
|
||||
PBD::basename_nosuffix (const std::string str)
|
||||
PBD::basename_nosuffix (const std::string& str)
|
||||
{
|
||||
std::string::size_type slash = str.find_last_of ('/');
|
||||
std::string noslash;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
#include <pbd/pathscanner.h>
|
||||
#include <pbd/stl_delete.h>
|
||||
|
||||
using namespace PBD;
|
||||
|
||||
vector<string *> *
|
||||
PathScanner::operator() (const string &dirpath, const string ®exp,
|
||||
bool match_fullpath, bool return_fullpath,
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ AbstractUI<RequestObject>::register_thread_with_request_count (pthread_t thread_
|
|||
RequestBuffer* b = new RequestBuffer (num_requests);
|
||||
|
||||
{
|
||||
PBD::LockMonitor lm (request_buffer_map_lock, __LINE__, __FILE__);
|
||||
Glib::Mutex::Lock lm (request_buffer_map_lock);
|
||||
request_buffers[thread_id] = b;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,8 +27,9 @@
|
|||
|
||||
#include <sigc++/sigc++.h>
|
||||
|
||||
#include <glibmm/thread.h>
|
||||
|
||||
#include <pbd/receiver.h>
|
||||
#include <pbd/lockmonitor.h>
|
||||
#include <pbd/ringbufferNPT.h>
|
||||
#include <pbd/base_ui.h>
|
||||
|
||||
|
|
@ -62,7 +63,7 @@ class AbstractUI : public BaseUI
|
|||
typedef typename RequestBuffer::rw_vector RequestBufferVector;
|
||||
typedef typename std::map<pthread_t,RequestBuffer*>::iterator RequestBufferMapIterator;
|
||||
|
||||
PBD::Lock request_buffer_map_lock;
|
||||
Glib::Mutex request_buffer_map_lock;
|
||||
typedef std::map<pthread_t,RequestBuffer*> RequestBufferMap;
|
||||
RequestBufferMap request_buffers;
|
||||
pthread_key_t thread_request_buffer_key;
|
||||
|
|
|
|||
|
|
@ -6,9 +6,7 @@
|
|||
namespace PBD
|
||||
{
|
||||
|
||||
extern char *basename (const char *);
|
||||
extern std::string basename (const std::string);
|
||||
extern std::string basename_nosuffix (const std::string);
|
||||
extern std::string basename_nosuffix (const std::string&);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 1998-99 Paul Barton-Davis
|
||||
Copyright (C) 1998-2006 Paul Davis
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -17,14 +17,16 @@
|
|||
|
||||
$Id$
|
||||
*/
|
||||
#ifndef __libmisc_error_h__
|
||||
#define __libmisc_error_h__
|
||||
#ifndef __libpbd_error_h__
|
||||
#define __libpbd_error_h__
|
||||
|
||||
#include "transmitter.h"
|
||||
|
||||
extern Transmitter error;
|
||||
extern Transmitter info;
|
||||
extern Transmitter warning;
|
||||
extern Transmitter fatal;
|
||||
namespace PBD {
|
||||
extern Transmitter error;
|
||||
extern Transmitter info;
|
||||
extern Transmitter warning;
|
||||
extern Transmitter fatal;
|
||||
}
|
||||
|
||||
#endif // __libmisc_error_h__
|
||||
#endif // __libpbd_error_h__
|
||||
|
|
|
|||
|
|
@ -23,7 +23,9 @@
|
|||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <glibmm/thread.h>
|
||||
|
||||
#include <pbd/ringbuffer.h>
|
||||
|
||||
class Pool
|
||||
|
|
@ -53,7 +55,7 @@ class SingleAllocMultiReleasePool : public Pool
|
|||
virtual void release (void *);
|
||||
|
||||
private:
|
||||
pthread_mutex_t lock;
|
||||
Glib::Mutex* m_lock;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -67,8 +69,7 @@ class MultiAllocSingleReleasePool : public Pool
|
|||
virtual void release (void *);
|
||||
|
||||
private:
|
||||
pthread_mutex_t lock;
|
||||
Glib::Mutex* m_lock;
|
||||
};
|
||||
|
||||
|
||||
#endif // __qm_pool_h__
|
||||
|
|
|
|||
|
|
@ -21,8 +21,9 @@
|
|||
#ifndef ringbuffer_h
|
||||
#define ringbuffer_h
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <pbd/atomic.h>
|
||||
//#include <sys/mman.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
template<class T>
|
||||
class RingBuffer
|
||||
|
|
@ -47,14 +48,14 @@ class RingBuffer
|
|||
|
||||
void reset () {
|
||||
/* !!! NOT THREAD SAFE !!! */
|
||||
atomic_set (&write_ptr, 0);
|
||||
atomic_set (&read_ptr, 0);
|
||||
g_atomic_int_set (&write_ptr, 0);
|
||||
g_atomic_int_set (&read_ptr, 0);
|
||||
}
|
||||
|
||||
void set (size_t r, size_t w) {
|
||||
/* !!! NOT THREAD SAFE !!! */
|
||||
atomic_set (&write_ptr, w);
|
||||
atomic_set (&read_ptr, r);
|
||||
g_atomic_int_set (&write_ptr, w);
|
||||
g_atomic_int_set (&read_ptr, r);
|
||||
}
|
||||
|
||||
size_t read (T *dest, size_t cnt);
|
||||
|
|
@ -69,22 +70,22 @@ class RingBuffer
|
|||
void get_write_vector (rw_vector *);
|
||||
|
||||
void decrement_read_ptr (size_t cnt) {
|
||||
atomic_set (&read_ptr, (atomic_read(&read_ptr) - cnt) & size_mask);
|
||||
g_atomic_int_set (&read_ptr, (g_atomic_int_get(&read_ptr) - cnt) & size_mask);
|
||||
}
|
||||
|
||||
void increment_read_ptr (size_t cnt) {
|
||||
atomic_set (&read_ptr, (atomic_read(&read_ptr) + cnt) & size_mask);
|
||||
g_atomic_int_set (&read_ptr, (g_atomic_int_get(&read_ptr) + cnt) & size_mask);
|
||||
}
|
||||
|
||||
void increment_write_ptr (size_t cnt) {
|
||||
atomic_set (&write_ptr, (atomic_read(&write_ptr) + cnt) & size_mask);
|
||||
g_atomic_int_set (&write_ptr, (g_atomic_int_get(&write_ptr) + cnt) & size_mask);
|
||||
}
|
||||
|
||||
size_t write_space () {
|
||||
size_t w, r;
|
||||
|
||||
w = atomic_read (&write_ptr);
|
||||
r = atomic_read (&read_ptr);
|
||||
w = g_atomic_int_get (&write_ptr);
|
||||
r = g_atomic_int_get (&read_ptr);
|
||||
|
||||
if (w > r) {
|
||||
return ((r - w + size) & size_mask) - 1;
|
||||
|
|
@ -98,8 +99,8 @@ class RingBuffer
|
|||
size_t read_space () {
|
||||
size_t w, r;
|
||||
|
||||
w = atomic_read (&write_ptr);
|
||||
r = atomic_read (&read_ptr);
|
||||
w = g_atomic_int_get (&write_ptr);
|
||||
r = g_atomic_int_get (&read_ptr);
|
||||
|
||||
if (w > r) {
|
||||
return w - r;
|
||||
|
|
@ -109,8 +110,8 @@ class RingBuffer
|
|||
}
|
||||
|
||||
T *buffer () { return buf; }
|
||||
size_t get_write_ptr () const { return atomic_read (&write_ptr); }
|
||||
size_t get_read_ptr () const { return atomic_read (&read_ptr); }
|
||||
size_t get_write_ptr () const { return g_atomic_int_get (&write_ptr); }
|
||||
size_t get_read_ptr () const { return g_atomic_int_get (&read_ptr); }
|
||||
size_t bufsize () const { return size; }
|
||||
|
||||
protected:
|
||||
|
|
@ -130,7 +131,7 @@ RingBuffer<T>::read (T *dest, size_t cnt)
|
|||
size_t n1, n2;
|
||||
size_t priv_read_ptr;
|
||||
|
||||
priv_read_ptr=atomic_read(&read_ptr);
|
||||
priv_read_ptr=g_atomic_int_get(&read_ptr);
|
||||
|
||||
if ((free_cnt = read_space ()) == 0) {
|
||||
return 0;
|
||||
|
|
@ -156,7 +157,7 @@ RingBuffer<T>::read (T *dest, size_t cnt)
|
|||
priv_read_ptr = n2;
|
||||
}
|
||||
|
||||
atomic_set(&read_ptr, priv_read_ptr);
|
||||
g_atomic_int_set(&read_ptr, priv_read_ptr);
|
||||
return to_read;
|
||||
}
|
||||
|
||||
|
|
@ -170,7 +171,7 @@ RingBuffer<T>::write (T *src, size_t cnt)
|
|||
size_t n1, n2;
|
||||
size_t priv_write_ptr;
|
||||
|
||||
priv_write_ptr=atomic_read(&write_ptr);
|
||||
priv_write_ptr=g_atomic_int_get(&write_ptr);
|
||||
|
||||
if ((free_cnt = write_space ()) == 0) {
|
||||
return 0;
|
||||
|
|
@ -196,7 +197,7 @@ RingBuffer<T>::write (T *src, size_t cnt)
|
|||
priv_write_ptr = n2;
|
||||
}
|
||||
|
||||
atomic_set(&write_ptr, priv_write_ptr);
|
||||
g_atomic_int_set(&write_ptr, priv_write_ptr);
|
||||
return to_write;
|
||||
}
|
||||
|
||||
|
|
@ -208,8 +209,8 @@ RingBuffer<T>::get_read_vector (RingBuffer<T>::rw_vector *vec)
|
|||
size_t cnt2;
|
||||
size_t w, r;
|
||||
|
||||
w = atomic_read (&write_ptr);
|
||||
r = atomic_read (&read_ptr);
|
||||
w = g_atomic_int_get (&write_ptr);
|
||||
r = g_atomic_int_get (&read_ptr);
|
||||
|
||||
if (w > r) {
|
||||
free_cnt = w - r;
|
||||
|
|
@ -248,8 +249,8 @@ RingBuffer<T>::get_write_vector (RingBuffer<T>::rw_vector *vec)
|
|||
size_t cnt2;
|
||||
size_t w, r;
|
||||
|
||||
w = atomic_read (&write_ptr);
|
||||
r = atomic_read (&read_ptr);
|
||||
w = g_atomic_int_get (&write_ptr);
|
||||
r = g_atomic_int_get (&read_ptr);
|
||||
|
||||
if (w > r) {
|
||||
free_cnt = ((r - w + size) & size_mask) - 1;
|
||||
|
|
|
|||
|
|
@ -21,12 +21,12 @@
|
|||
#ifndef ringbuffer_npt_h
|
||||
#define ringbuffer_npt_h
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <pbd/atomic.h>
|
||||
//#include <sys/mman.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
/* ringbuffer class where the element size is not required to be a power of two */
|
||||
|
||||
/** Ringbuffer class where the element size is not required to be a
|
||||
* power of two.
|
||||
*/
|
||||
template<class T>
|
||||
class RingBufferNPT
|
||||
{
|
||||
|
|
@ -44,14 +44,14 @@ class RingBufferNPT
|
|||
|
||||
void reset () {
|
||||
/* !!! NOT THREAD SAFE !!! */
|
||||
atomic_set (&write_ptr, 0);
|
||||
atomic_set (&read_ptr, 0);
|
||||
g_atomic_int_set (&write_ptr, 0);
|
||||
g_atomic_int_set (&read_ptr, 0);
|
||||
}
|
||||
|
||||
void set (size_t r, size_t w) {
|
||||
/* !!! NOT THREAD SAFE !!! */
|
||||
atomic_set (&write_ptr, w);
|
||||
atomic_set (&read_ptr, r);
|
||||
g_atomic_int_set (&write_ptr, w);
|
||||
g_atomic_int_set (&read_ptr, r);
|
||||
}
|
||||
|
||||
size_t read (T *dest, size_t cnt);
|
||||
|
|
@ -66,22 +66,22 @@ class RingBufferNPT
|
|||
void get_write_vector (rw_vector *);
|
||||
|
||||
void decrement_read_ptr (size_t cnt) {
|
||||
atomic_set (&read_ptr, (atomic_read(&read_ptr) - cnt) % size);
|
||||
g_atomic_int_set (&read_ptr, (g_atomic_int_get(&read_ptr) - cnt) % size);
|
||||
}
|
||||
|
||||
void increment_read_ptr (size_t cnt) {
|
||||
atomic_set (&read_ptr, (atomic_read(&read_ptr) + cnt) % size);
|
||||
g_atomic_int_set (&read_ptr, (g_atomic_int_get(&read_ptr) + cnt) % size);
|
||||
}
|
||||
|
||||
void increment_write_ptr (size_t cnt) {
|
||||
atomic_set (&write_ptr, (atomic_read(&write_ptr) + cnt) % size);
|
||||
g_atomic_int_set (&write_ptr, (g_atomic_int_get(&write_ptr) + cnt) % size);
|
||||
}
|
||||
|
||||
size_t write_space () {
|
||||
size_t w, r;
|
||||
|
||||
w = atomic_read (&write_ptr);
|
||||
r = atomic_read (&read_ptr);
|
||||
w = g_atomic_int_get (&write_ptr);
|
||||
r = g_atomic_int_get (&read_ptr);
|
||||
|
||||
if (w > r) {
|
||||
return ((r - w + size) % size) - 1;
|
||||
|
|
@ -95,8 +95,8 @@ class RingBufferNPT
|
|||
size_t read_space () {
|
||||
size_t w, r;
|
||||
|
||||
w = atomic_read (&write_ptr);
|
||||
r = atomic_read (&read_ptr);
|
||||
w = g_atomic_int_get (&write_ptr);
|
||||
r = g_atomic_int_get (&read_ptr);
|
||||
|
||||
if (w > r) {
|
||||
return w - r;
|
||||
|
|
@ -106,8 +106,8 @@ class RingBufferNPT
|
|||
}
|
||||
|
||||
T *buffer () { return buf; }
|
||||
size_t get_write_ptr () const { return atomic_read (&write_ptr); }
|
||||
size_t get_read_ptr () const { return atomic_read (&read_ptr); }
|
||||
size_t get_write_ptr () const { return g_atomic_int_get (&write_ptr); }
|
||||
size_t get_read_ptr () const { return g_atomic_int_get (&read_ptr); }
|
||||
size_t bufsize () const { return size; }
|
||||
|
||||
protected:
|
||||
|
|
@ -126,7 +126,7 @@ RingBufferNPT<T>::read (T *dest, size_t cnt)
|
|||
size_t n1, n2;
|
||||
size_t priv_read_ptr;
|
||||
|
||||
priv_read_ptr=atomic_read(&read_ptr);
|
||||
priv_read_ptr=g_atomic_int_get(&read_ptr);
|
||||
|
||||
if ((free_cnt = read_space ()) == 0) {
|
||||
return 0;
|
||||
|
|
@ -152,7 +152,7 @@ RingBufferNPT<T>::read (T *dest, size_t cnt)
|
|||
priv_read_ptr = n2;
|
||||
}
|
||||
|
||||
atomic_set(&read_ptr, priv_read_ptr);
|
||||
g_atomic_int_set(&read_ptr, priv_read_ptr);
|
||||
return to_read;
|
||||
}
|
||||
|
||||
|
|
@ -165,7 +165,7 @@ RingBufferNPT<T>::write (T *src, size_t cnt)
|
|||
size_t n1, n2;
|
||||
size_t priv_write_ptr;
|
||||
|
||||
priv_write_ptr=atomic_read(&write_ptr);
|
||||
priv_write_ptr=g_atomic_int_get(&write_ptr);
|
||||
|
||||
if ((free_cnt = write_space ()) == 0) {
|
||||
return 0;
|
||||
|
|
@ -191,7 +191,7 @@ RingBufferNPT<T>::write (T *src, size_t cnt)
|
|||
priv_write_ptr = n2;
|
||||
}
|
||||
|
||||
atomic_set(&write_ptr, priv_write_ptr);
|
||||
g_atomic_int_set(&write_ptr, priv_write_ptr);
|
||||
return to_write;
|
||||
}
|
||||
|
||||
|
|
@ -202,8 +202,8 @@ RingBufferNPT<T>::get_read_vector (RingBufferNPT<T>::rw_vector *vec)
|
|||
size_t cnt2;
|
||||
size_t w, r;
|
||||
|
||||
w = atomic_read (&write_ptr);
|
||||
r = atomic_read (&read_ptr);
|
||||
w = g_atomic_int_get (&write_ptr);
|
||||
r = g_atomic_int_get (&read_ptr);
|
||||
|
||||
if (w > r) {
|
||||
free_cnt = w - r;
|
||||
|
|
@ -241,8 +241,8 @@ RingBufferNPT<T>::get_write_vector (RingBufferNPT<T>::rw_vector *vec)
|
|||
size_t cnt2;
|
||||
size_t w, r;
|
||||
|
||||
w = atomic_read (&write_ptr);
|
||||
r = atomic_read (&read_ptr);
|
||||
w = g_atomic_int_get (&write_ptr);
|
||||
r = g_atomic_int_get (&read_ptr);
|
||||
|
||||
if (w > r) {
|
||||
free_cnt = ((r - w + size) % size) - 1;
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ endmsg (std::ostream &ostr)
|
|||
return ostr;
|
||||
}
|
||||
|
||||
|
||||
extern "C" { void pbd_c_error (const char *); }
|
||||
|
||||
#endif // __libmisc_transmitter_h__
|
||||
|
|
|
|||
|
|
@ -19,15 +19,13 @@
|
|||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <sys/mman.h>
|
||||
#include <vector>
|
||||
|
||||
#include <pbd/pool.h>
|
||||
#include <pbd/error.h>
|
||||
#include <pbd/stl_delete.h>
|
||||
#include <pbd/pthread_utils.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace PBD;
|
||||
|
||||
Pool::Pool (string n, unsigned long item_size, unsigned long nitems)
|
||||
{
|
||||
|
|
@ -84,32 +82,39 @@ Pool::release (void *ptr)
|
|||
/*---------------------------------------------*/
|
||||
|
||||
MultiAllocSingleReleasePool::MultiAllocSingleReleasePool (string n, unsigned long isize, unsigned long nitems)
|
||||
: Pool (n, isize, nitems)
|
||||
: Pool (n, isize, nitems),
|
||||
m_lock(0)
|
||||
{
|
||||
pthread_mutex_init (&lock, 0);
|
||||
}
|
||||
|
||||
MultiAllocSingleReleasePool::~MultiAllocSingleReleasePool ()
|
||||
{
|
||||
if(m_lock) delete m_lock;
|
||||
}
|
||||
|
||||
SingleAllocMultiReleasePool::SingleAllocMultiReleasePool (string n, unsigned long isize, unsigned long nitems)
|
||||
: Pool (n, isize, nitems)
|
||||
: Pool (n, isize, nitems),
|
||||
m_lock(0)
|
||||
{
|
||||
pthread_mutex_init (&lock, 0);
|
||||
}
|
||||
|
||||
SingleAllocMultiReleasePool::~SingleAllocMultiReleasePool ()
|
||||
{
|
||||
if(m_lock) delete m_lock;
|
||||
}
|
||||
|
||||
void*
|
||||
MultiAllocSingleReleasePool::alloc ()
|
||||
{
|
||||
void *ptr;
|
||||
pthread_mutex_lock (&lock);
|
||||
if(!m_lock) {
|
||||
m_lock = new Glib::Mutex();
|
||||
// umm, I'm not sure that this doesn't also allocate memory.
|
||||
if(!m_lock) error << "cannot create Glib::Mutex in pool.cc" << endmsg;
|
||||
}
|
||||
|
||||
Glib::Mutex::Lock guard(*m_lock);
|
||||
ptr = Pool::alloc ();
|
||||
pthread_mutex_unlock (&lock);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
|
@ -128,8 +133,12 @@ SingleAllocMultiReleasePool::alloc ()
|
|||
void
|
||||
SingleAllocMultiReleasePool::release (void* ptr)
|
||||
{
|
||||
pthread_mutex_lock (&lock);
|
||||
if(!m_lock) {
|
||||
m_lock = new Glib::Mutex();
|
||||
// umm, I'm not sure that this doesn't also allocate memory.
|
||||
if(!m_lock) error << "cannot create Glib::Mutex in pool.cc" << endmsg;
|
||||
}
|
||||
Glib::Mutex::Lock guard(*m_lock);
|
||||
Pool::release (ptr);
|
||||
pthread_mutex_unlock (&lock);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,17 +24,12 @@
|
|||
#include <string>
|
||||
|
||||
#include <pbd/transmitter.h>
|
||||
#include <pbd/error.h>
|
||||
|
||||
using std::string;
|
||||
using std::ios;
|
||||
|
||||
Transmitter error (Transmitter::Error);
|
||||
Transmitter info (Transmitter::Info);
|
||||
Transmitter fatal (Transmitter::Fatal);
|
||||
Transmitter warning (Transmitter::Warning);
|
||||
|
||||
Transmitter::Transmitter (Channel c)
|
||||
|
||||
{
|
||||
channel = c;
|
||||
switch (c) {
|
||||
|
|
@ -110,11 +105,11 @@ Transmitter::does_not_return ()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
extern "C" {
|
||||
void pbd_c_error (const char *str)
|
||||
|
||||
{
|
||||
extern Transmitter error;
|
||||
error << str << endmsg;
|
||||
PBD::error << str << endmsg;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ UndoCommand::clear ()
|
|||
void
|
||||
UndoCommand::undo ()
|
||||
{
|
||||
cerr << "Undo " << _name << endl;
|
||||
for (list<UndoAction>::reverse_iterator i = undo_actions.rbegin(); i != undo_actions.rend(); ++i) {
|
||||
(*i)();
|
||||
}
|
||||
|
|
@ -85,6 +86,7 @@ UndoCommand::undo ()
|
|||
void
|
||||
UndoCommand::redo ()
|
||||
{
|
||||
cerr << "Redo " << _name << endl;
|
||||
for (list<UndoAction>::iterator i = redo_actions.begin(); i != redo_actions.end(); ++i) {
|
||||
(*i)();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
using namespace ARDOUR;
|
||||
using namespace std;
|
||||
using namespace sigc;
|
||||
using namespace PBD;
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue