import errno
import time
import platform
+import string
from sets import Set
import SCons.Node.FS
env.Append (BUILDERS = {'Distribute' : dist_bld})
env.Append (BUILDERS = {'Tarball' : tarball_bld})
+#
+# Make sure they know what they are doing
+#
+
+if env['VST']:
+ sys.stdout.write ("Are you building Ardour for personal use (rather than distributiont to others)? [no]: ")
+ answer = sys.stdin.readline ()
+ answer = answer.rstrip().strip()
+ if answer != "yes" and answer != "y":
+ print 'You cannot build Ardour with VST support for distribution to others.\nIt is a violation of several different licenses. VST support disabled.'
+ env['VST'] = 0;
+ else:
+ print "OK, VST support will be enabled"
+
+
# ----------------------------------------------------------------------
# Construction environment setup
# ----------------------------------------------------------------------
config_prefix = '$DESTDIR' + final_config_prefix
+# For colorgcc ( so says the wiki, but it's still not working :/ anyone? )
+if os.environ.has_key('PATH'):
+ env['PATH'] = os.environ['PATH']
+if os.environ.has_key('TERM'):
+ env['TERM'] = os.environ['TERM']
+if os.environ.has_key('HOME'):
+ env['HOME'] = os.environ['HOME']
+
# SCons should really do this for us
libraries['ardour'],
libraries['ardour_cp'],
libraries['gtkmm2ext'],
-# libraries['flowcanvas'],
libraries['midi++2'],
libraries['pbd3'],
libraries['gtkmm2'],
connection_editor.cc
""")
+
gtkardour_files=Split("""
about.cc
actions.cc
waveview.cc
""")
+
fft_analysis_files=Split("""
analysis_window.cc
fft_graph.cc
using namespace std;
using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
#ifdef WITH_PAYMENT_OPTIONS
using namespace Gtk;
using namespace Glib;
using namespace sigc;
+using namespace PBD;
vector<RefPtr<Gtk::Action> > ActionManager::session_sensitive_actions;
vector<RefPtr<Gtk::Action> > ActionManager::region_list_selection_sensitive_actions;
using namespace Gtkmm2ext;
using namespace sigc;
using namespace std;
+using namespace PBD;
static const char* channel_setup_names[] = {
"Mono",
"6 Channels",
"8 Channels",
"Manual Setup",
+ "MIDI",
0
};
return track_button.get_active ();
}
+bool
+AddRouteDialog::midi ()
+{
+ const string str = channel_combo.get_active_text();
+ return (str == _("MIDI"));
+}
+
string
AddRouteDialog::name_template ()
{
string str = channel_combo.get_active_text();
int chns;
- if (str == _("Mono")) {
+ if (str == _("Mono") || str == _("MIDI")) {
return 1;
} else if (str == _("Stereo")) {
return 2;
~AddRouteDialog ();
bool track ();
+ bool midi ();
std::string name_template ();
int channels ();
int count ();
#include <gtkmm/treeiter.h>
#include <ardour/audioregion.h>
-#include <ardour/playlist.h>
+#include <ardour/audioplaylist.h>
#include <ardour/types.h>
#include "analysis_window.h"
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
AnalysisWindow::AnalysisWindow()
: ArdourDialog(_("analysis window")),
for (TrackSelection::iterator i = s.tracks.begin(); i != s.tracks.end(); ++i) {
- ARDOUR::Playlist *pl = (*i)->playlist();
+ ARDOUR::AudioPlaylist *pl
+ = dynamic_cast<ARDOUR::AudioPlaylist*>((*i)->playlist());
+
+ if (!pl)
+ continue;
+
RouteUI *rui = dynamic_cast<RouteUI *>(*i);
// Busses don't have playlists, so we need to check that we actually are working with a playlist
#include <ardour/session_diskstream.h>
#include <ardour/port.h>
#include <ardour/audio_track.h>
+#include <ardour/midi_track.h>
#include "actions.h"
#include "ardour_ui.h"
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtkmm2ext;
using namespace Gtk;
using namespace sigc;
void
-ARDOUR_UI::session_add_midi_track ()
+ARDOUR_UI::session_add_midi_route (bool disk)
{
- cerr << _("Patience is a virtue.\n");
+ Route* route;
+
+ if (session == 0) {
+ warning << _("You cannot add a track without a session already loaded.") << endmsg;
+ return;
+ }
+
+ try {
+ if (disk) {
+ if ((route = session->new_midi_track ()) == 0) {
+ error << _("could not create new MIDI track") << endmsg;
+ }
+ } else {
+ if ((route = session->new_midi_route ()) == 0) {
+ error << _("could not create new MIDI bus") << endmsg;
+ }
+ }
+#if 0
+#if CONTROLOUTS
+ if (need_control_room_outs) {
+ pan_t pans[2];
+
+ pans[0] = 0.5;
+ pans[1] = 0.5;
+
+ route->set_stereo_control_outs (control_lr_channels);
+ route->control_outs()->set_stereo_pan (pans, this);
+ }
+#endif /* CONTROLOUTS */
+#endif
+ }
+
+ catch (...) {
+ MessageDialog msg (*editor,
+ _("There are insufficient JACK ports available\n\
+to create a new track or bus.\n\
+You should save Ardour, exit and\n\
+restart JACK with more ports."));
+ msg.run ();
+ }
}
+
void
ARDOUR_UI::session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode)
{
}
void
-ARDOUR_UI::diskstream_added (AudioDiskstream* ds)
+ARDOUR_UI::diskstream_added (Diskstream* ds)
{
}
return;
}
- AudioDiskstream *ds;
+ Diskstream *ds;
if ((ds = session->diskstream_by_id (dstream)) != 0) {
- Port *port = ds->io()->input (0);
- port->request_monitor_input (!port->monitoring_input());
+ AudioDiskstream *ads = dynamic_cast<AudioDiskstream*>(ds);
+ if (ads) {
+ Port *port = ds->io()->input (0);
+ port->request_monitor_input (!port->monitoring_input());
+ }
}
}
return;
}
- AudioDiskstream *ds;
+ Diskstream *ds;
if ((ds = session->diskstream_by_id (dstream)) != 0) {
ds->set_record_enabled (!ds->record_enabled(), this);
/* XXX do something with name template */
while (count) {
- if (track) {
+ if (track && add_route_dialog->midi()) {
+ session_add_midi_track();
+ } else if (add_route_dialog->midi()) {
+ session_add_midi_bus();
+ } else if (track) {
session_add_audio_track (input_chan, output_chan, add_route_dialog->mode());
} else {
session_add_audio_bus (input_chan, output_chan);
session_add_audio_route (false, input_channels, output_channels, ARDOUR::Normal);
}
- void session_add_midi_track ();
+ void session_add_midi_track () {
+ session_add_midi_route (true);
+ }
+
+ void session_add_midi_bus () {
+ session_add_midi_route (false);
+ }
void set_engine (ARDOUR::AudioEngine&);
sigc::connection point_one_second_connection;
sigc::connection point_zero_one_second_connection;
- void diskstream_added (ARDOUR::AudioDiskstream*);
+ void diskstream_added (ARDOUR::Diskstream*);
gint session_menu (GdkEventButton *);
void session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode);
+ void session_add_midi_route (bool disk);
void add_diskstream_to_menu (ARDOUR::AudioDiskstream&);
void diskstream_selected (gint32);
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtkmm2ext;
using namespace Gtk;
using namespace Glib;
using namespace sigc;
using namespace Gtk;
+using namespace PBD;
namespace ARDOUR {
class Session;
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace Glib;
using namespace Gtk;
using namespace Gtkmm2ext;
shuttle_box.set_sensitive (true);
if (session->n_audio_diskstreams() == 0) {
- session->AudioDiskstreamAdded.connect (mem_fun(*this, &ARDOUR_UI::diskstream_added));
+ session->DiskstreamAdded.connect (mem_fun(*this, &ARDOUR_UI::diskstream_added));
}
if (connection_editor) {
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
using namespace Gtkmm2ext;
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_toggle_action (common_actions, X_("ToggleBigClock"), _("Big Clock"), mem_fun(*this, &ARDOUR_UI::toggle_big_clock_window));
ActionManager::session_sensitive_actions.push_back (act);
- ActionManager::register_action (common_actions, X_("About"), _("About"), mem_fun(*this, &ARDOUR_UI::show_splash));
+ act = ActionManager::register_action (common_actions, X_("About"), _("About"), mem_fun(*this, &ARDOUR_UI::show_splash));
act = ActionManager::register_toggle_action (common_actions, X_("ToggleColorManager"), _("Colors"), mem_fun(*this, &ARDOUR_UI::toggle_color_manager));
-
+ ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (common_actions, X_("AddAudioTrack"), _("Add Audio Track"), bind (mem_fun(*this, &ARDOUR_UI::session_add_audio_track), 1, 1, ARDOUR::Normal));
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (common_actions, X_("AddAudioBus"), _("Add Audio Bus"), bind (mem_fun(*this, &ARDOUR_UI::session_add_audio_bus), 1, 1));
ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (common_actions, X_("AddMIDITrack"), _("Add MIDI Track"), (mem_fun(*this, &ARDOUR_UI::session_add_midi_track)));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (common_actions, X_("AddMidiBus"), _("Add Midi Bus"), mem_fun(*this, &ARDOUR_UI::session_add_midi_bus));
+ ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (common_actions, X_("Save"), _("Save"), bind (mem_fun(*this, &ARDOUR_UI::save_state), string("")));
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (common_actions, X_("RemoveLastCapture"), _("Remove Last Capture"), mem_fun(*this, &ARDOUR_UI::remove_last_capture));
#include "mixer_ui.h"
using namespace ARDOUR;
+using namespace PBD;
int
ARDOUR_UI::create_mixer ()
using namespace Gtk;
using namespace Gtkmm2ext;
using namespace ARDOUR;
+using namespace PBD;
void
ARDOUR_UI::setup_config_options ()
fi
export LD_LIBRARY_PATH=../libs/ardour/.libs
-LDPRELOAD=./gprofhelper.so ./ardour $*
+LDPRELOAD=./gprofhelper.so ./ardev $*
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace sigc;
using namespace Gtk;
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace LADSPA;
using namespace Gtk;
using namespace Editing;
label_view ();
if (is_audio_track()) {
- set_playlist (get_diskstream()->playlist());
+ set_playlist (dynamic_cast<AudioPlaylist*>(get_diskstream()->playlist()));
}
}
AudioPlaylist *pl;
AudioDiskstream *ds;
- if (((ds = get_diskstream()) == 0) || ds->destructive() || ((pl = ds->playlist()) == 0)) {
+ if (((ds = get_diskstream()) == 0) || ds->destructive()
+ || ((pl = dynamic_cast<AudioPlaylist*>(ds->playlist())) == 0)) {
return;
}
AudioDiskstream *ds;
string name;
- if (((ds = get_diskstream()) == 0) || ds->destructive() || ((pl = ds->playlist()) == 0)) {
+ if (((ds = get_diskstream()) == 0) || ds->destructive()
+ || ((pl = dynamic_cast<AudioPlaylist*>(ds->playlist())) == 0)) {
return;
}
if (name.length()) {
ds->use_copy_playlist ();
- pl = ds->playlist();
+ pl = dynamic_cast<AudioPlaylist*>(ds->playlist());
pl->set_name (name);
}
}
AudioDiskstream *ds;
string name;
- if (((ds = get_diskstream()) == 0) || ds->destructive() || ((pl = ds->playlist()) == 0)) {
+ if (((ds = get_diskstream()) == 0) || ds->destructive()
+ || ((pl = dynamic_cast<AudioPlaylist*>(ds->playlist())) == 0)) {
return;
}
if (name.length()) {
ds->use_new_playlist ();
- pl = ds->playlist();
+ pl = dynamic_cast<AudioPlaylist*>(ds->playlist());
pl->set_name (name);
}
}
AudioDiskstream *ds;
if ((ds = get_diskstream()) != 0) {
- if ((pl = ds->playlist()) != 0) {
+ if ((pl = dynamic_cast<AudioPlaylist*>(ds->playlist())) != 0) {
editor.clear_playlist (*pl);
}
}
AudioDiskstream *ds;
if ((ds = get_diskstream()) != 0) {
- set_playlist (ds->playlist ());
+ set_playlist (dynamic_cast<AudioPlaylist*> (ds->playlist ()));
}
map_frozen ();
AudioTimeAxisView::find_next_region (jack_nframes_t pos, RegionPoint point, int32_t dir)
{
AudioDiskstream *stream;
- AudioPlaylist *playlist;
+ Playlist *playlist;
if ((stream = get_diskstream()) != 0 && (playlist = stream->playlist()) != 0) {
return playlist->find_next_region (pos, point, dir);
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
AutomationGainLine::AutomationGainLine (const string & name, Session& s, TimeAxisView& tv, ArdourCanvas::Group& parent, Curve& c)
using namespace std;
using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
using namespace Editing;
using namespace Gnome; // for Canvas
#include <ardour/session.h>
using namespace ARDOUR;
+using namespace PBD;
AutomationPanLine::AutomationPanLine (const string & name, Session& s, TimeAxisView& tv, ArdourCanvas::Group& parent, Curve& c)
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
using namespace Editing;
using namespace std;
using namespace Gtk;
+using namespace PBD;
/* the global color map */
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
using namespace sigc;
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
using namespace sigc;
using namespace Editing;
using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
using namespace Editing;
using namespace Gnome;
using namespace Canvas;
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
int
curvetest (string filename)
using namespace std;
using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
using namespace Glib;
using namespace Gtkmm2ext;
}
- if ((pl = ds->playlist()) != 0) {
+ if ((pl = dynamic_cast<AudioPlaylist*>(ds->playlist())) != 0) {
pl->get_equivalent_regions (basis->region, results);
}
continue;
}
- if ((pl = ds->playlist()) != 0) {
+ if ((pl = dynamic_cast<AudioPlaylist*>(ds->playlist())) != 0) {
pl->get_region_list_equivalent_regions (*region, results);
}
class AudioDiskstream;
class RouteGroup;
class Playlist;
+ class AudioPlaylist;
class Region;
class Location;
class TempoSection;
void external_edit_region ();
int write_audio_selection (TimeSelection&);
- bool write_audio_range (ARDOUR::Playlist&, uint32_t channels, list<ARDOUR::AudioRange>&);
+ bool write_audio_range (ARDOUR::AudioPlaylist&, uint32_t channels, list<ARDOUR::AudioRange>&);
void write_selection ();
using namespace std;
using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
using namespace Editing;
void
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
using namespace sigc;
using namespace Gtk;
using namespace Editing;
#include "selection.h"
using namespace ARDOUR;
+using namespace PBD;
void
Editor::set_route_loop_selection ()
using namespace std;
using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
using namespace Glib;
using namespace Gtkmm2ext;
using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
bool
if ((atv = dynamic_cast<AudioTimeAxisView*>(&tv)) != 0) {
if (atv->is_audio_track()) {
-
- AudioPlaylist* pl = atv->get_diskstream()->playlist();
- Playlist::RegionList* rl = pl->regions_at (event_frame (event));
- if (!rl->empty()) {
- DescendingRegionLayerSorter cmp;
- rl->sort (cmp);
+ AudioPlaylist* pl;
+ if ((pl = dynamic_cast<AudioPlaylist*> (atv->get_diskstream()->playlist())) != 0) {
+
+ Playlist::RegionList* rl = pl->regions_at (event_frame (event));
+
+ if (!rl->empty()) {
+ DescendingRegionLayerSorter cmp;
+ rl->sort (cmp);
- AudioRegionView* arv = atv->view->find_view (*(dynamic_cast<AudioRegion*> (rl->front())));
+ AudioRegionView* arv = atv->view->find_view (*(dynamic_cast<AudioRegion*> (rl->front())));
- /* proxy */
-
- delete rl;
+ /* proxy */
- return canvas_region_view_event (event, arv->get_canvas_group(), arv);
- }
+ delete rl;
+
+ return canvas_region_view_event (event, arv->get_canvas_group(), arv);
+ }
+ }
}
}
using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
Editor::Cursor::Cursor (Editor& ed, const string& color, bool (Editor::*callbck)(GdkEvent*,ArdourCanvas::Item*))
using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
void
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
void
if (atv->is_audio_track()) {
- Playlist* playlist = atv->get_diskstream()->playlist();
+ AudioPlaylist* playlist = dynamic_cast<AudioPlaylist*>(atv->get_diskstream()->playlist());
if (playlist && write_audio_range (*playlist, atv->get_diskstream()->n_channels(), ts) == 0) {
ret = -1;
}
bool
-Editor::write_audio_range (Playlist& playlist, uint32_t channels, list<AudioRange>& range)
+Editor::write_audio_range (AudioPlaylist& playlist, uint32_t channels, list<AudioRange>& range)
{
AudioFileSource* fs;
const jack_nframes_t chunk_size = 4096;
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
void
Editor::hscrollbar_allocate (Gtk::Allocation &alloc)
#include "public_editor.h"
using namespace Gtk;
+using namespace PBD;
/* <CMT Additions file="editor.cc"> */
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace sigc;
void
using namespace std;
using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
void
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
using namespace sigc;
using namespace Gtk;
using namespace Editing;
AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (&rv->get_time_axis_view());
if (atv && atv->is_audio_track()) {
- AudioPlaylist* pl = atv->get_diskstream()->playlist();
+ AudioPlaylist* pl = dynamic_cast<AudioPlaylist*>(atv->get_diskstream()->playlist());
if (pl) {
/* only freeze and capture state once */
using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
using namespace sigc;
using namespace Gtk;
using namespace Editing;
using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
using namespace Glib;
using namespace Editing;
using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
void
using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
using namespace Editing;
using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
using namespace Gtkmm2ext;
using namespace std;
using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
using namespace Gtkmm2ext;
using namespace Editing;
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace sigc;
using namespace Gtk;
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
using namespace sigc;
using namespace Gtk;
using namespace Gtk;
using namespace ARDOUR;
+using namespace PBD;
using namespace std;
ExportRangeMarkersDialog::ExportRangeMarkersDialog (PublicEditor& editor)
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
GainAutomationTimeAxisView::GainAutomationTimeAxisView (Session& s, Route& r, PublicEditor& e, TimeAxisView& parent, ArdourCanvas::Canvas& canvas, const string & n, ARDOUR::Curve& c)
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtkmm2ext;
using namespace Gtk;
using namespace sigc;
using namespace ardourvis ;
using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
ImageFrameSocketHandler* ImageFrameSocketHandler::_instance = 0 ;
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace sigc;
using namespace Gtk;
using namespace Glib;
using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtkmm2ext;
IOSelectorWindow::IOSelectorWindow (Session& sess, IO& ior, bool input, bool can_cancel)
#include "i18n.h"
+using namespace PBD;
+
#define KBD_DEBUG 1
bool debug_keyboard = false;
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
using namespace Gtkmm2ext;
using namespace Gtk;
using namespace GTK_ARDOUR;
using namespace ARDOUR;
+using namespace PBD;
using namespace sigc;
TextReceiver text_receiver ("ardour");
shutdown (1);
}
-static void
-handler2 (int sig, siginfo_t* ctxt, void* ignored)
-{
- handler (sig);
-}
-
static void *
signal_thread (void *arg)
{
return true;
}
+#ifdef VST_SUPPORT
+/* this is called from the entry point of a wine-compiled
+ executable that is linked against gtk2_ardour built
+ as a shared library.
+*/
+extern "C" {
+int ardour_main (int argc, char *argv[])
+#else
+int main (int argc, char *argv[])
+#endif
-int
-main (int argc, char *argv[])
{
ARDOUR::AudioEngine *engine;
vector<Glib::ustring> null_file_list;
try {
engine = new ARDOUR::AudioEngine (jack_client_name);
- ARDOUR::init (*engine, use_vst, try_hw_optimization, handler2);
+ ARDOUR::init (*engine, use_vst, try_hw_optimization);
ui->set_engine (*engine);
} catch (AudioEngine::NoBackendAvailable& err) {
gui_jack_error ();
ARDOUR::cleanup ();
shutdown (0);
- /* just another commit forcing change */
+ return 0;
}
+#ifdef VST_SUPPORT
+} // end of extern C block
+#endif
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace sigc;
using namespace Gtk;
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
using namespace sigc;
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
using namespace Gtkmm2ext;
using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
using namespace Gtkmm2ext;
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
using namespace Glib;
using namespace Gtkmm2ext;
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
using namespace Editing;
using namespace Gtkmm2ext;
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
PanAutomationTimeAxisView::PanAutomationTimeAxisView (Session& s, Route& r, PublicEditor& e, TimeAxisView& parent, Canvas& canvas, std::string n)
using namespace Gtk;
using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
Panner2d::Target::Target (float xa, float ya, const char *txt)
: x (xa), y (ya), text (txt ? strdup (txt) : 0)
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtkmm2ext;
using namespace Gtk;
using namespace sigc;
using namespace sigc;
using namespace Gtk;
using namespace ARDOUR;
+using namespace PBD;
PlaylistSelector::PlaylistSelector ()
: ArdourDialog ("playlist selector")
for (DSPL_Map::iterator x = dspl_map.begin(); x != dspl_map.end(); ++x) {
- AudioDiskstream* ds = session->diskstream_by_id (x->first);
+ Diskstream* ds = session->diskstream_by_id (x->first);
if (ds == 0) {
continue;
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
PluginSelector::PluginSelector (PluginManager *mgr)
added_list.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::added_list_selection_changed));
input_refiller ();
+#ifdef VST_SUPPORT
+ vst_refiller ();
+#endif
}
void
{
manager->refresh ();
input_refiller ();
+#ifdef VST_SUPPORT
+ vst_refiller ();
+#endif
}
#ifdef VST_SUPPORT
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtkmm2ext;
using namespace Gtk;
using namespace sigc;
Gtk::HBox preset_box;
Gtk::VBox vpacker;
- gboolean configure_handler (GdkEventConfigure*, Gtk::Socket*);
+ bool configure_handler (GdkEventConfigure*, Gtk::Socket*);
void save_plugin_setting ();
};
#endif
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
RedirectAutomationLine::RedirectAutomationLine (const string & name, Redirect& rd, uint32_t port, Session& s,
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
RedirectAutomationTimeAxisView::RedirectAutomationTimeAxisView (Session& s, Route& r, PublicEditor& e, TimeAxisView& parent, Canvas& canvas, std::string n,
using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
using namespace Glib;
using namespace Gtkmm2ext;
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace sigc;
using namespace std;
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
AudioRegionGainLine::AudioRegionGainLine (const string & name, Session& s, AudioRegionView& r, ArdourCanvas::Group& parent, Curve& c)
: AutomationLine (name, r.get_time_axis_view(), parent, c),
#include "region_selection.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace sigc;
using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
using namespace Editing;
using namespace ArdourCanvas;
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace Gtk;
using namespace sigc;
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace sigc;
RouteRedirectSelection&
using namespace Gtk;
using namespace Gtkmm2ext;
using namespace ARDOUR;
+using namespace PBD;
RouteUI::RouteUI (ARDOUR::Route& rt, ARDOUR::Session& sess, const char* m_name,
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace sigc;
struct AudioRangeComparator {
#include "gui_thread.h"
using namespace ARDOUR;
+using namespace PBD;
SendUI::SendUI (Send& s, Session& se)
: _send (s),
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace std;
SoundFileBox::SoundFileBox ()
#include "color.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace Editing;
StreamView::StreamView (AudioTimeAxisView& tv)
playlist_connections.push_back (ds->playlist()->RegionRemoved.connect (mem_fun (*this, &StreamView::remove_region_view)));
playlist_connections.push_back (ds->playlist()->StateChanged.connect (mem_fun (*this, &StreamView::playlist_state_changed)));
playlist_connections.push_back (ds->playlist()->Modified.connect (mem_fun (*this, &StreamView::playlist_modified)));
- playlist_connections.push_back (ds->playlist()->NewCrossfade.connect (mem_fun (*this, &StreamView::add_crossfade)));
+ AudioPlaylist* apl = dynamic_cast<AudioPlaylist*>(ds->playlist());
+ if (apl)
+ playlist_connections.push_back (apl->NewCrossfade.connect (mem_fun (*this, &StreamView::add_crossfade)));
}
void
if (_trackview.is_audio_track()) {
_trackview.get_diskstream()->playlist()->foreach_region (this, &StreamView::add_region_view);
- _trackview.get_diskstream()->playlist()->foreach_crossfade (this, &StreamView::add_crossfade);
+ AudioPlaylist* apl = dynamic_cast<AudioPlaylist*>(_trackview.get_diskstream()->playlist());
+ if (apl)
+ apl->foreach_crossfade (this, &StreamView::add_crossfade);
}
for (i = region_views.begin(); i != region_views.end(); ) {
using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
using namespace Editing;
using namespace ArdourCanvas;
using namespace Gtk;
using namespace Gtkmm2ext;
using namespace ARDOUR;
+using namespace PBD;
TempoDialog::TempoDialog (TempoMap& map, jack_nframes_t frame, const string & action)
: ArdourDialog ("tempo dialog"),
using namespace Gdk;
using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
using namespace Editing;
using namespace ArdourCanvas;
using namespace std;
using namespace Editing;
using namespace Glib;
+using namespace PBD;
//------------------------------------------------------------------------------
/** Initialize const static memeber data */
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
AudioRange&
TimeSelection::operator[] (uint32_t which)
using namespace Gtk;
using namespace sigc;
using namespace Glib;
+using namespace PBD;
ustring
fit_to_pixels (const ustring& str, int pixel_width, Pango::FontDescription& font, int& actual_width)
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace sigc;
using namespace Gtk;
*/
#include <fst.h>
-
+#include <gtk/gtksocket.h>
#include <ardour/insert.h>
#include <ardour/vst_plugin.h>
using namespace Gtk;
using namespace ARDOUR;
+using namespace PBD;
VSTPluginUI::VSTPluginUI (PluginInsert& pi, VSTPlugin& vp)
: PlugUIBase (pi),
int
VSTPluginUI::package (Gtk::Window& win)
{
- /* for GTK+2, remove this: you cannot add to a realized socket */
-
- //socket.realize ();
-
/* forward configure events to plugin window */
- win.signal_configure_event().connect (bind (mem_fun (*this, &VSTPluginUI::configure_handler), &socket));
+ win.signal_configure_event().connect (bind (mem_fun (*this, &VSTPluginUI::configure_handler), &socket), false);
- /* XXX in GTK2, use add_id() instead of steal, although add_id()
- assumes that the window's owner understands the XEmbed protocol.
+ /*
+ this assumes that the window's owner understands the XEmbed protocol.
*/
socket.add_id (fst_get_XID (vst.fst()));
return 0;
}
-gboolean
+bool
VSTPluginUI::configure_handler (GdkEventConfigure* ev, Gtk::Socket *socket)
{
XEvent event;
-
gint x, y;
+ GdkWindow* w;
- if (socket->gobj() == NULL) {
- return FALSE;
+ if (socket == 0 || ((w = socket->gobj()->plug_window) == 0)) {
+ return false;
}
event.xconfigure.type = ConfigureNotify;
- event.xconfigure.event = GDK_WINDOW_XWINDOW (socket->get_window()->gobj());
- event.xconfigure.window = GDK_WINDOW_XWINDOW (socket->get_window()->gobj());
+ event.xconfigure.event = GDK_WINDOW_XWINDOW (w);
+ event.xconfigure.window = GDK_WINDOW_XWINDOW (w);
/* The ICCCM says that synthetic events should have root relative
* coordinates. We still aren't really ICCCM compliant, since
* we don't send events when the real toplevel is moved.
*/
gdk_error_trap_push ();
- gdk_window_get_origin (socket->get_window()->gobj(), &x, &y);
+ gdk_window_get_origin (w, &x, &y);
gdk_error_trap_pop ();
event.xconfigure.x = x;
event.xconfigure.y = y;
- event.xconfigure.width = GTK_WIDGET(socket)->allocation.width;
- event.xconfigure.height = GTK_WIDGET(socket)->allocation.height;
+ event.xconfigure.width = GTK_WIDGET(socket->gobj())->allocation.width;
+ event.xconfigure.height = GTK_WIDGET(socket->gobj())->allocation.height;
event.xconfigure.border_width = 0;
event.xconfigure.above = None;
event.xconfigure.override_redirect = False;
gdk_error_trap_push ();
- XSendEvent (GDK_WINDOW_XDISPLAY (socket->get_window()->gobj()),
- GDK_WINDOW_XWINDOW (socket->get_window()->gobj()),
- False, StructureNotifyMask, &event);
- // gdk_display_sync (GDK_WINDOW_XDISPLAY (socket->plug_window));
+ XSendEvent (GDK_WINDOW_XDISPLAY (w), GDK_WINDOW_XWINDOW (w), False, StructureNotifyMask, &event);
gdk_error_trap_pop ();
- return FALSE;
+ return false;
}
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
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 ();
$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>
#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 {
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()) {
}
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;
}
}
- 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())
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);
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;
}
}
- 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;
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);
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);
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;
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 {
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;
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__ */
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);
void set_meter_point (MeterPoint, void* src);
protected:
- AudioDiskstream *diskstream;
+ AudioDiskstream *_diskstream;
MeterPoint _saved_meter_point;
TrackMode _mode;
#include <ardour/ardour.h>
#include <jack/jack.h>
#include <jack/transport.h>
+#include <ardour/buffer.h>
namespace ARDOUR {
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);
#include <ardour/utils.h>
#include <ardour/state_manager.h>
#include <ardour/curve.h>
+#include <ardour/buffer.h>
using std::string;
using std::vector;
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
{
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();
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; }
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);
id_t _id;
bool no_panner_reset;
XMLNode* deferred_state;
+ Buffer::Type _default_type;
virtual void set_deferred_state() {}
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;
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() {
}
std::string short_name() {
- return jack_port_short_name (port);
+ return jack_port_short_name (_port);
}
int set_name (std::string str);
}
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 {
}
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 () {
}
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);
}
bool monitoring_input () const {
- return jack_port_monitoring_input (port);
+ return jack_port_monitoring_input (_port);
}
bool can_monitor () const {
}
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
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:
/* engine isn't supposed to below here */
- Sample *_buffer;
+ Sample *_buffer;
/* cache these 3 from JACK so that we can
access them for reconnecting.
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 */
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 */
#include <ardour/io.h>
#include <ardour/session.h>
#include <ardour/redirect.h>
+#include <ardour/buffer.h>
namespace ARDOUR {
};
- 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();
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;
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;
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; }
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);
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&);
/* 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);
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 ();
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 */
Playlist *XMLPlaylistFactory (const XMLNode&);
void playlist_length_changed (Playlist *);
- void diskstream_playlist_changed (AudioDiskstream *);
+ void diskstream_playlist_changed (Diskstream *);
/* NAMED SELECTIONS */
typedef uint32_t layer_t;
typedef uint64_t id_t;
+ typedef unsigned char RawMidi;
+
enum IOChange {
NoChange = 0,
ConfigurationChanged = 0x1,
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 */
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);
use_destructive_playlist ();
}
- AudioDiskstreamCreated (this); /* EMIT SIGNAL */
+ DiskstreamCreated (this); /* EMIT SIGNAL */
}
void
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
{
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));
channels.clear();
}
-
+/*
void
AudioDiskstream::handle_input_change (IOChange change, void *src)
{
_session.request_input_change_handling ();
}
}
-
+*/
void
AudioDiskstream::non_realtime_input_change ()
{
}
int
-AudioDiskstream::use_playlist (AudioPlaylist* playlist)
+AudioDiskstream::use_playlist (Playlist* playlist)
{
+ assert(dynamic_cast<AudioPlaylist*>(playlist));
+
{
Glib::Mutex::Lock lm (state_lock);
_playlist->unref();
}
- _playlist = playlist;
+ _playlist = dynamic_cast<AudioPlaylist*>(playlist);
_playlist->ref();
if (!in_set_state && recordable()) {
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 ()
{
}
}
+
+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 ()
{
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 ()
{
}
}
-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)
{
return ret;
}
-void
-AudioDiskstream::recover ()
-{
- state_lock.unlock();
- _processed = false;
-}
-
bool
AudioDiskstream::commit (jack_nframes_t nframes)
{
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;
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)
{
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;
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);
}
}
-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 ()
{
}
}
-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 ()
{
(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)
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;
- }
- }
-}
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
static char* SOUNDFILE = "http://ardour.org/ontology/Soundfile";
using namespace ARDOUR;
using namespace sigc;
using namespace std;
+using namespace PBD;
AudioPlaylist::State::~State ()
{
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
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);
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;
AudioTrack::~AudioTrack ()
{
- if (diskstream) {
- diskstream->unref();
+ if (_diskstream) {
+ _diskstream->unref();
}
}
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);
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));
}
}
- 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 */
{
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;
}
{
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;
}
bool
AudioTrack::record_enabled () const
{
- return diskstream->record_enabled ();
+ return _diskstream->record_enabled ();
}
void
/* 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);
/* 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;
diskstream.
*/
- snprintf (buf, sizeof (buf), "%" PRIu64, diskstream->id());
+ snprintf (buf, sizeof (buf), "%" PRIu64, _diskstream->id());
root.add_property ("diskstream-id", buf);
return root;
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);
}
}
}
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
return 0;
}
- diskstream->check_record_status (start_frame, nframes, can_record);
+ _diskstream->check_record_status (start_frame, nframes, can_record);
bool send_silence;
send_silence = true;
}
} else {
- if (diskstream->record_enabled()) {
+ if (_diskstream->record_enabled()) {
if (Config->get_use_sw_monitoring()) {
send_silence = false;
} else {
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);
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)
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()
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;
}
/* 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()) {
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
return -1;
}
- if (diskstream->set_name (str, src)) {
+ if (_diskstream->set_name (str, src)) {
return -1;
}
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;
}
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);
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
AudioRegion* region;
string region_name;
- if ((_freeze_record.playlist = diskstream->playlist()) == 0) {
+ if ((_freeze_record.playlist = dynamic_cast<AudioPlaylist*>(_diskstream->playlist())) == 0) {
return;
}
(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 */
AudioTrack::unfreeze ()
{
if (_freeze_record.playlist) {
- diskstream->use_playlist (_freeze_record.playlist);
+ _diskstream->use_playlist (_freeze_record.playlist);
if (_freeze_record.have_mementos) {
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();
}
}
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)
{
*/
PBD::ThreadCreatedWithRequestSize (pthread_self(), X_("Audioengine"), 4096);
-
-#ifdef VST_SUPPORT
- if (Config->get_use_vst()) {
- fst_adopt_thread ();
- }
-#endif
}
int
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 ...
*/
}
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) {
}
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;
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;
return 0;
}
+
int
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) {
}
}
- int ret = jack_port_disconnect (_jack, port->port);
+ int ret = jack_port_disconnect (_jack, port->_port);
if (ret == 0) {
remove_connections_for (port);
}
string
-
AudioEngine::get_nth_physical (uint32_t n, int flag)
{
const char ** ports;
}
}
- return jack_port_get_total_latency (_jack, port.port);
+ return jack_port_get_total_latency (_jack, port._port);
}
void
if (_jack) {
for (Ports::iterator i = ports.begin(); i != ports.end(); ++i) {
- jack_port_unregister (_jack, (*i)->port);
+ jack_port_unregister (_jack, (*i)->_port);
}
}
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 {
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;
}
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
string AudioFileSource::peak_dir = "";
string AudioFileSource::search_path;
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
int
AudioFilter::make_new_sources (AudioRegion& region, AudioRegion::SourceList& nsrcs)
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 ();
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
}
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);
}
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);
}
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) {
using namespace std;
using namespace ARDOUR;
using namespace sigc;
+using namespace PBD;
#if 0
static void dumpit (const AutomationList& al, string prefix = "")
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.
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
Connection::Connection (const XMLNode& node)
{
#include <ardour/session.h>
#include <ardour/control_protocol_manager.h>
-
-
-
using namespace ARDOUR;
using namespace std;
+using namespace PBD;
#include "i18n.h"
#include <AudioToolbox/AudioFormat.h>
using namespace ARDOUR;
+using namespace PBD;
CoreAudioSource::CoreAudioSource (const XMLNode& node)
: AudioFileSource (node)
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();
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)
#include "i18n.h"
+using namespace PBD;
+
float CycleTimer::cycles_per_usec = 0;
float
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
gain_t* DestructiveFileSource::out_coefficient = 0;
gain_t* DestructiveFileSource::in_coefficient = 0;
using namespace ARDOUR;
using namespace std;
+using namespace PBD;
MIDI::Port *default_mmc_port = 0;
MIDI::Port *default_mtc_port = 0;
}
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;
#endif
#ifdef VST_SUPPORT
- if (Config->get_use_vst() && fst_init (sighandler)) {
+ if (Config->get_use_vst() && fst_init ()) {
return -1;
}
#endif
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
#define BLOCKSIZE 4096U
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)
using namespace std;
using namespace ARDOUR;
-//using namespace sigc;
+using namespace PBD;
+
static float current_automation_version_number = 1.0;
}
+/** 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),
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());
/* 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;
}
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());
/* 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;
}
/* Create a new input port */
+ // FIXME: of what type?
+
if (_input_maximum == 1) {
snprintf (buf, sizeof (buf), _("%s/in"), _name.c_str());
}
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;
}
/* create any necessary new ports */
+ // FIXME: of what type?
+
while (_ninputs < nin) {
char buf[64];
}
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;
}
}
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;
}
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;
}
#include <errno.h>
#include <jack/jack.h>
#include <jack/transport.h>
-#include <pbd/error.h>
#include <ardour/slave.h>
#include <ardour/session.h>
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)
using namespace std;
using namespace ARDOUR;
using namespace sigc;
+using namespace PBD;
Location::Location (const Location& other)
: _name (other._name),
using namespace ARDOUR;
using namespace sigc;
using namespace MIDI;
+using namespace PBD;
MTC_Slave::MTC_Slave (Session& s, MIDI::Port& p)
: session (s)
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
sigc::signal<void,NamedSelection*> NamedSelection::NamedSelectionCreated;
#include <pbd/mathfix.h>
-
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
float Panner::current_automation_version_number = 1.0;
using namespace std;
using namespace ARDOUR;
-//using namespace sigc;
+using namespace PBD;
sigc::signal<void,Playlist*> Playlist::PlaylistCreated;
+/*
+ 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>
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
Region*
ARDOUR::createRegion (const Region& region, jack_nframes_t start,
#include <locale.h>
using namespace ARDOUR;
+using namespace PBD;
Plugin::Plugin (AudioEngine& e, Session& s)
: _engine (e), _session (s)
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
PluginManager* PluginManager::_manager = 0;
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 ();
}
{
reset_buffer ();
- last_monitor = false;
- silent = false;
- metering = 0;
+ _last_monitor = false;
+ _silent = false;
+ _metering = 0;
reset_meters ();
}
{
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;
}
#include <ardour/utils.h>
#include "i18n.h"
-
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
int
ARDOUR::read_recent_sessions (RecentSessions& rs)
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;
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
Change Region::FadeChanged = ARDOUR::new_change ();
Change Region::SyncOffsetChanged = ARDOUR::new_change ();
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())
#include "i18n.h"
using namespace ARDOUR;
+using namespace PBD;
Send::Send (Session& s, Placement p)
: Redirect (s, s.next_send_name(), p)
#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>
#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>
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");
_midi_port (default_midi_port),
pending_events (2048),
//midi_requests (16),
+ _send_smpte_update (false),
main_outs (0)
{
/* 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
_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;
}
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;
}
void
-Session::diskstream_playlist_changed (AudioDiskstream* dstream)
+Session::diskstream_playlist_changed (Diskstream* dstream)
{
Playlist *playlist;
}
+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)
{
} 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"),
}
catch (failed_constructor &err) {
- error << _("Session: could not create new route.") << endmsg;
+ error << _("Session: could not create new audio route.") << endmsg;
return 0;
}
}
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);
set_dirty();
save_state (_current_snapshot_name);
- AudioDiskstreamAdded (dstream); /* EMIT SIGNAL */
+ DiskstreamAdded (dstream); /* EMIT SIGNAL */
}
void
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;
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;
using namespace std;
using namespace ARDOUR;
-//using namespace sigc;
+using namespace PBD;
static float _read_data_rate;
static float _write_data_rate;
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;
}
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) {
}
}
}
-
- 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 ();
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)) {
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)) {
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;
}
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
Pool Session::Click::pool ("click", sizeof (Click), 128);
#include "i18n.h"
using namespace ARDOUR;
-//using namespace sigc;
+using namespace PBD;
MultiAllocSingleReleasePool Session::Event::pool ("event", sizeof (Session::Event), 512);
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:
using namespace std;
using namespace ARDOUR;
-//using namespace sigc;
+using namespace PBD;
static int
convert_spec_to_info (AudioExportSpecification& spec, SF_INFO& sfinfo)
#include <glibmm/thread.h>
-#include <pbd/error.h>
#include <pbd/pthread_utils.h>
#include <ardour/configuration.h>
using namespace std;
using namespace ARDOUR;
-//using namespace sigc;
+using namespace PBD;
using namespace MIDI;
MachineControl::CommandSignature MMC_CommandSignature;
static bool step_queued = false;
void
-
Session::mmc_step (MIDI::MachineControl &mmc, int steps)
{
if (!mmc_control) {
#include "i18n.h"
using namespace ARDOUR;
-//using namespace sigc;
+using namespace PBD;
using namespace std;
void
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
void
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));
#include "i18n.h"
using namespace ARDOUR;
-//using namespace sigc;
+using namespace PBD;
/* BBT TIME*/
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
using namespace soundtouch;
AudioRegion*
using namespace std;
using namespace ARDOUR;
using namespace sigc;
+using namespace PBD;
void
Session::request_input_change_handling ()
}
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);
}
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);
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
SndFileSource::SndFileSource (const XMLNode& node)
: AudioFileSource (node)
using namespace ARDOUR;
using namespace std;
+using namespace PBD;
bool StateManager::_allow_save = true;
sigc::signal<void,const char*> StateManager::SaveAllowed;
#include "i18n.h"
+using namespace PBD;
+
Stateful::Stateful ()
{
_extra_xml = 0;
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
/* _default tempo is 4/4 qtr=120 */
using namespace ARDOUR;
using namespace std;
+using namespace PBD;
void
elapsed_time_to_str (char *buf, uint32_t seconds)
#include <locale.h>
using namespace ARDOUR;
+using namespace PBD;
using std::min;
using std::max;
--- /dev/null
+# -*- 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'] ))
+
--- /dev/null
+#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);
+}
+
+
--- /dev/null
+#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__ */
--- /dev/null
+
+#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 );
+}
+
+
--- /dev/null
+#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__ */
--- /dev/null
+/*
+ * 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);
+}
+
+
+
--- /dev/null
+#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;
+}
using namespace Gtkmm2ext;
using namespace Gtk;
using namespace Glib;
+using namespace PBD;
using std::map;
pthread_t UI::gui_thread;
#include <gtkmm2ext/selector.h>
#include <gtkmm2ext/utils.h>
#include <pbd/pathscanner.h>
-#include <pbd/error.h>
using namespace std;
using namespace Gtkmm2ext;
using namespace std;
using namespace MIDI;
+using namespace PBD;
string *FD_MidiPort::midi_dirpath = 0;
string *FD_MidiPort::midi_filename_pattern = 0;
using namespace sigc;
using namespace MIDI;
+using namespace PBD;
Controllable::Controllable (Port *p, bool is_bistate)
{
using namespace std;
using namespace MIDI;
+using namespace PBD;
Manager *Manager::theManager = 0;
using namespace std;
using namespace MIDI;
+using namespace PBD;
static std::map<int,string> mmc_cmd_map;
static void build_mmc_cmd_map ()
#include "midi++/mmc.h"
using namespace MIDI;
+using namespace PBD;
Port *port;
PortRequest midi_device;
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")
basename.cc
base_ui.cc
convert.cc
-dirname.cc
dmalloc.cc
+error.cc
mountpoint.cc
pathscanner.cc
pool.cc
textreceiver.cc
transmitter.cc
undo.cc
-unescape.cc
version.cc
whitespace.cc
xml++.cc
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')
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')))
#include "i18n.h"
using namespace std;
+using namespace PBD;
uint32_t BaseUI::rt_bit = 1;
BaseUI::RequestType BaseUI::CallSlot = BaseUI::new_request_type();
#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);
-}
-
-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);
-}
+// implement this using Glib::path_get_basename
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;
#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,
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;
}
#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>
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;
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&);
};
/*
- 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
$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__
#include <vector>
#include <string>
-#include <pthread.h>
+
+#include <glibmm/thread.h>
+
#include <pbd/ringbuffer.h>
class Pool
virtual void release (void *);
private:
- pthread_mutex_t lock;
+ Glib::Mutex* m_lock;
};
virtual void release (void *);
private:
- pthread_mutex_t lock;
+ Glib::Mutex* m_lock;
};
-
#endif // __qm_pool_h__
#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
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);
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;
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;
}
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:
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;
priv_read_ptr = n2;
}
- atomic_set(&read_ptr, priv_read_ptr);
+ g_atomic_int_set(&read_ptr, priv_read_ptr);
return to_read;
}
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;
priv_write_ptr = n2;
}
- atomic_set(&write_ptr, priv_write_ptr);
+ g_atomic_int_set(&write_ptr, priv_write_ptr);
return to_write;
}
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;
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;
#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
{
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);
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;
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;
}
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:
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;
priv_read_ptr = n2;
}
- atomic_set(&read_ptr, priv_read_ptr);
+ g_atomic_int_set(&read_ptr, priv_read_ptr);
return to_read;
}
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;
priv_write_ptr = n2;
}
- atomic_set(&write_ptr, priv_write_ptr);
+ g_atomic_int_set(&write_ptr, priv_write_ptr);
return to_write;
}
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;
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;
return ostr;
}
+
extern "C" { void pbd_c_error (const char *); }
#endif // __libmisc_transmitter_h__
*/
#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)
{
/*---------------------------------------------*/
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;
}
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);
}
#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) {
}
}
+
extern "C" {
void pbd_c_error (const char *str)
{
- extern Transmitter error;
- error << str << endmsg;
+ PBD::error << str << endmsg;
}
}
void
UndoCommand::undo ()
{
+ cerr << "Undo " << _name << endl;
for (list<UndoAction>::reverse_iterator i = undo_actions.rbegin(); i != undo_actions.rend(); ++i) {
(*i)();
}
void
UndoCommand::redo ()
{
+ cerr << "Redo " << _name << endl;
for (list<UndoAction>::iterator i = redo_actions.begin(); i != redo_actions.end(); ++i) {
(*i)();
}
using namespace ARDOUR;
using namespace std;
using namespace sigc;
+using namespace PBD;
#include "i18n.h"
--- /dev/null
+# -*- python -*-
+
+import os
+import os.path
+import glob
+
+Import('env install_prefix final_prefix config_prefix libraries')
+
+ardour_vst = env.Copy()
+
+sources = Split ("""
+winmain.c
+#libs/fst/fst.o
+#libs/fst/fstinfofile.o
+#libs/fst/vstwin.o
+#libs/fst/vsti.o
+"""
+)
+
+ardour_vst.Append (CCFLAGS="-DVST_SUPPORT", CPPPATH="#libs/fst", LIBPATH='#gtk2_ardour')
+ardour_vst.Append (LINKFLAGS='-L/usr/X11R6/lib -lasound -lardourgtk -lX11 -lpthread')
+ardour_vst["CC"] ="winegcc"
+ardour_vst["LINK"] ="wineg++ -mwindows"
+
+ardour_vst.Merge ([
+ libraries['ardour'],
+ libraries['ardour_cp'],
+ libraries['gtkmm2ext'],
+ libraries['midi++2'],
+ libraries['pbd3'],
+ libraries['gtkmm2'],
+ libraries['glib2'],
+ libraries['libgnomecanvas2'],
+ libraries['libgnomecanvasmm'],
+ libraries['sysmidi'],
+ libraries['sndfile'],
+ libraries['flac'],
+ libraries['lrdf'],
+ libraries['glibmm2'],
+ libraries['pangomm'],
+ libraries['atkmm'],
+ libraries['gdkmm2'],
+ libraries['sigc2'],
+ libraries['gtk2'],
+ libraries['xml'],
+ libraries['xslt'],
+ libraries['soundtouch'],
+ libraries['samplerate'],
+ libraries['jack']
+])
+
+wine_executable = ardour_vst.Program (target = 'ardour_vst', source = sources)
+
+Default(wine_executable)
--- /dev/null
+#include <limits.h>
+#include <unistd.h>
+#include <stdio.h>
+
+extern int ardour_main(int argc, char* argv[]);
+
+int
+main (int argc, char* argv[])
+{
+ // call the user specified main function
+
+ int result = ardour_main(argc, argv);
+ printf ("main returned %d\n", result);
+
+ return result;
+
+}