2005-09-25 14:42:24 -04:00
|
|
|
/*
|
2019-08-02 17:26:43 -04:00
|
|
|
* Copyright (C) 2005-2006 Taybin Rutkin <taybin@taybin.com>
|
|
|
|
* Copyright (C) 2005-2007 Doug McLain <doug@nostar.net>
|
|
|
|
* Copyright (C) 2005-2019 Paul Davis <paul@linuxaudiosystems.com>
|
|
|
|
* Copyright (C) 2006-2011 David Robillard <d@drobilla.net>
|
|
|
|
* Copyright (C) 2006-2015 Tim Mayberry <mojofunk@gmail.com>
|
|
|
|
* Copyright (C) 2006 Nick Mainsbridge <mainsbridge@gmail.com>
|
|
|
|
* Copyright (C) 2007-2012 Carl Hetherington <carl@carlh.net>
|
|
|
|
* Copyright (C) 2008-2009 Hans Baier <hansfbaier@googlemail.com>
|
|
|
|
* Copyright (C) 2013-2017 John Emmas <john@creativepost.co.uk>
|
|
|
|
* Copyright (C) 2013-2019 Robin Gareus <robin@gareus.org>
|
|
|
|
*
|
|
|
|
* 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.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*/
|
2005-09-25 14:42:24 -04:00
|
|
|
|
|
|
|
#include <cstdlib>
|
2010-11-03 22:40:07 -04:00
|
|
|
#include <cerrno>
|
2012-05-05 10:16:13 -04:00
|
|
|
#include <vector>
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2016-04-24 21:46:39 -04:00
|
|
|
#include <signal.h>
|
|
|
|
#include <locale.h>
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
#include <sigc++/bind.h>
|
2005-11-29 12:27:58 -05:00
|
|
|
#include <gtkmm/settings.h>
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2017-08-31 13:33:51 -04:00
|
|
|
#include <curl/curl.h>
|
|
|
|
|
2009-02-25 13:26:51 -05:00
|
|
|
#include "pbd/error.h"
|
|
|
|
#include "pbd/file_utils.h"
|
|
|
|
#include "pbd/textreceiver.h"
|
|
|
|
#include "pbd/failed_constructor.h"
|
2013-07-11 14:57:16 -04:00
|
|
|
#include "pbd/pathexpand.h"
|
2009-02-25 13:26:51 -05:00
|
|
|
#include "pbd/pthread_utils.h"
|
2020-09-20 14:00:33 -04:00
|
|
|
#include "pbd/win_console.h"
|
2011-02-10 12:44:33 -05:00
|
|
|
#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
|
|
|
|
#include "pbd/boost_debug.h"
|
|
|
|
#endif
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2013-03-17 09:53:30 -04:00
|
|
|
#include "ardour/revision.h"
|
2009-02-25 13:26:51 -05:00
|
|
|
#include "ardour/ardour.h"
|
|
|
|
#include "ardour/audioengine.h"
|
|
|
|
#include "ardour/session_utils.h"
|
|
|
|
#include "ardour/filesystem_paths.h"
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2005-09-25 16:33:00 -04:00
|
|
|
#include <gtkmm/main.h>
|
2017-07-16 22:55:52 -04:00
|
|
|
#include <gtkmm/stock.h>
|
|
|
|
|
2010-08-16 22:48:24 -04:00
|
|
|
#include <gtkmm2ext/application.h>
|
2005-09-25 16:33:00 -04:00
|
|
|
#include <gtkmm2ext/utils.h>
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2019-12-14 17:31:24 -05:00
|
|
|
#include "ardour_message.h"
|
2005-09-25 14:42:24 -04:00
|
|
|
#include "ardour_ui.h"
|
2015-01-04 10:58:46 -05:00
|
|
|
#include "ui_config.h"
|
2005-09-25 14:42:24 -04:00
|
|
|
#include "opts.h"
|
2007-01-09 18:24:54 -05:00
|
|
|
#include "enums.h"
|
2014-03-02 11:30:51 -05:00
|
|
|
#include "bundle_env.h"
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2016-07-14 14:44:52 -04:00
|
|
|
#include "pbd/i18n.h"
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2014-10-25 22:10:53 -04:00
|
|
|
#ifdef PLATFORM_WINDOWS
|
2021-07-06 14:59:15 -04:00
|
|
|
#include <windows.h> // CreateMutex
|
2014-04-15 06:01:48 -04:00
|
|
|
#include <fcntl.h> // Needed for '_fmode'
|
2015-01-05 20:04:12 -05:00
|
|
|
#include <shellapi.h> // console
|
2014-04-15 06:01:48 -04:00
|
|
|
#endif
|
2013-02-22 10:48:44 -05:00
|
|
|
|
2014-09-06 11:59:53 -04:00
|
|
|
#ifdef WAF_BUILD
|
|
|
|
#include "gtk2ardour-version.h"
|
|
|
|
#endif
|
|
|
|
|
2017-03-05 19:48:46 -05:00
|
|
|
#ifdef LXVST_SUPPORT
|
|
|
|
#include <gdk/gdkx.h>
|
|
|
|
#endif
|
|
|
|
|
2009-05-12 13:03:42 -04:00
|
|
|
using namespace std;
|
2005-09-25 14:42:24 -04:00
|
|
|
using namespace Gtk;
|
2007-10-11 18:07:47 -04:00
|
|
|
using namespace ARDOUR_COMMAND_LINE;
|
2005-09-25 14:42:24 -04:00
|
|
|
using namespace ARDOUR;
|
Large nasty commit in the form of a 5000 line patch chock-full of completely
unecessary changes. (Sorry, doing a "sprint" based thing, this is the end of the first one)
Achieved MIDI track and bus creation, associated Jack port and diskstream creation, and minimal GUI stuff for creating them. Should be set to start work on actually recording and playing midi to/from disk now.
Relevant (significant) changes:
- Creation of a Buffer class. Base class is type agnostic so things can point to a buffer but not care what kind it is (otherwise it'd be a template). Derived into AudioBuffer and MidiBuffer, with a type tag because checking type is necessary in parts of the code where dynamic_cast wouldn't be wise. Originally I considered this a hack, but passing around a type proved to be a very good solution to all the other problems (below). There is a 1:1 mapping between jack port data types and ardour Buffer types (with a conversion function), but that's easily removed if it ever becomes necessary. Having the type scoped in the Buffer class is maybe not the best spot for it, but whatever (this is proof of concept kinda stuff right now...)
- IO now has a "default" port type (passed to the constructor and stored as a member), used by ensure_io (and similar) to create n ports. IO::register_***_port has a type argument that defaults to the default type if not passed. Rationale: previous IO API is identical, no changes needed to existing code, but path is paved for multiple port types in one IO, which we will need for eg synth plugin inserts, among other things. This is not quite ideal (best would be to only have the two port register functions and have them take a type), but the alternative is a lot of work (namely destroying the 'ensure' functions and everything that uses them) for very little gain. (I am convinced after quite a few tries at the whiteboard that subclassing IO in any way is not a feasible option, look at it's inheritance diagram in Doxygen and you can see why)
- AudioEngine::register_audio_input_port is now register_input_port and takes a type argument. Ditto for output.
- (Most significant change) AudioDiskstream abstracted into Distream, and sibling MidiDiskstream created. Very much still a work in progress, but Diskstream is there to switch references over to (most already are), which is the important part. It is still unclear what the MIDI diskstream's relation to channels is, but I'm pretty sure they will be single channel only (so SMF Type 0) since noone can come up with a reason otherwise.
- MidiTrack creation. Same thing as AudioTrack but with a different default type basically. No big deal here.
- Random cleanups and variable renamings etc. because I have OCD and can't help myself. :)
Known broken: Loading of sessions containing MIDI tracks.
git-svn-id: svn://localhost/ardour2/branches/midi@641 d708f5d6-7413-0410-9779-e7cbd77b26cf
2006-06-26 12:01:34 -04:00
|
|
|
using namespace PBD;
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2018-12-08 19:31:27 -05:00
|
|
|
TextReceiver text_receiver (PROGRAM_NAME);
|
2005-09-25 14:42:24 -04:00
|
|
|
|
|
|
|
extern int curvetest (string);
|
|
|
|
|
|
|
|
static ARDOUR_UI *ui = 0;
|
2015-04-17 11:00:33 -04:00
|
|
|
static string localedir (LOCALEDIR);
|
2005-09-25 14:42:24 -04:00
|
|
|
|
|
|
|
void
|
|
|
|
gui_jack_error ()
|
|
|
|
{
|
2019-12-14 17:31:24 -05:00
|
|
|
ArdourMessageDialog win (string_compose (_("%1 could not connect to the audio backend."), PROGRAM_NAME),
|
|
|
|
false,
|
|
|
|
Gtk::MESSAGE_INFO,
|
|
|
|
Gtk::BUTTONS_NONE);
|
2006-04-19 16:42:17 -04:00
|
|
|
|
|
|
|
win.add_button (Stock::QUIT, RESPONSE_CLOSE);
|
|
|
|
win.set_default_response (RESPONSE_CLOSE);
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
win.show_all ();
|
2005-10-27 16:51:57 -04:00
|
|
|
win.set_position (Gtk::WIN_POS_CENTER);
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2006-08-30 22:28:42 -04:00
|
|
|
if (!no_splash) {
|
2006-11-19 11:45:16 -05:00
|
|
|
ui->hide_splash ();
|
2006-08-30 22:28:42 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* we just don't care about the result, but we want to block */
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2005-12-08 13:53:43 -05:00
|
|
|
win.run ();
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2015-07-30 13:05:12 -04:00
|
|
|
#ifndef NDEBUG
|
|
|
|
static void ardour_g_log (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) {
|
2021-09-19 22:16:09 -04:00
|
|
|
|
|
|
|
g_log_default_handler (log_domain, log_level, message, NULL);
|
|
|
|
|
2015-07-30 13:05:12 -04:00
|
|
|
switch (log_level) {
|
|
|
|
case G_LOG_FLAG_FATAL:
|
|
|
|
fatal << "g_log: " << message << endmsg;
|
|
|
|
break;
|
2021-09-09 15:21:30 -04:00
|
|
|
case G_LOG_LEVEL_CRITICAL:
|
2015-07-30 13:05:12 -04:00
|
|
|
case G_LOG_LEVEL_ERROR:
|
|
|
|
error << "g_log: " << message << endmsg;
|
|
|
|
break;
|
|
|
|
case G_LOG_LEVEL_WARNING:
|
|
|
|
warning << "g_log: " << message << endmsg;
|
|
|
|
break;
|
|
|
|
case G_LOG_LEVEL_MESSAGE:
|
|
|
|
case G_LOG_LEVEL_INFO:
|
|
|
|
default:
|
|
|
|
info << "g_log: " << message << endmsg;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-03-16 11:33:04 -04:00
|
|
|
static gboolean
|
2013-07-24 08:36:04 -04:00
|
|
|
tell_about_backend_death (void* /* ignored */)
|
2010-03-16 11:33:04 -04:00
|
|
|
{
|
2017-09-18 12:39:17 -04:00
|
|
|
if (AudioEngine::instance()->processed_samples() == 0) {
|
2010-03-16 11:33:04 -04:00
|
|
|
/* died during startup */
|
2019-12-14 17:31:24 -05:00
|
|
|
ArdourMessageDialog msg (string_compose (_("The audio backend (%1) has failed, or terminated"), AudioEngine::instance()->current_backend_name()), false);
|
2010-03-16 11:33:04 -04:00
|
|
|
msg.set_position (Gtk::WIN_POS_CENTER);
|
2010-08-16 20:28:20 -04:00
|
|
|
msg.set_secondary_text (string_compose (_(
|
2013-07-24 08:36:04 -04:00
|
|
|
"%2 exited unexpectedly, and without notifying %1.\n\
|
2010-03-16 11:33:04 -04:00
|
|
|
\n\
|
2013-07-24 08:36:04 -04:00
|
|
|
This could be due to misconfiguration or to an error inside %2.\n\
|
2010-03-16 11:33:04 -04:00
|
|
|
\n\
|
2013-07-24 08:36:04 -04:00
|
|
|
Click OK to exit %1."), PROGRAM_NAME, AudioEngine::instance()->current_backend_name()));
|
2011-04-04 18:46:48 -04:00
|
|
|
|
2010-03-16 11:33:04 -04:00
|
|
|
msg.run ();
|
2019-07-04 16:21:49 -04:00
|
|
|
_exit (EXIT_SUCCESS);
|
2011-04-04 18:46:48 -04:00
|
|
|
|
2010-03-16 11:33:04 -04:00
|
|
|
} else {
|
|
|
|
|
2013-07-24 08:36:04 -04:00
|
|
|
/* engine has already run, so this is a mid-session backend death */
|
2015-03-12 13:02:20 -04:00
|
|
|
|
2020-01-15 16:01:30 -05:00
|
|
|
ArdourMessageDialog msg (string_compose (_("The audio backend (%1) has failed, or terminated"), AudioEngine::instance()->current_backend_name()), false);
|
2013-07-30 23:26:46 -04:00
|
|
|
msg.set_secondary_text (string_compose (_("%2 exited unexpectedly, and without notifying %1."),
|
2013-07-24 08:36:04 -04:00
|
|
|
PROGRAM_NAME, AudioEngine::instance()->current_backend_name()));
|
2019-12-14 17:31:24 -05:00
|
|
|
msg.run ();
|
2010-03-16 11:33:04 -04:00
|
|
|
}
|
|
|
|
return false; /* do not call again */
|
|
|
|
}
|
|
|
|
|
2022-06-14 11:12:30 -04:00
|
|
|
#if !(defined NDEBUG || defined PLATFORM_WINDOWS)
|
2022-06-13 15:48:37 -04:00
|
|
|
static void
|
|
|
|
sigusr1_handler (int /* signal */)
|
|
|
|
{
|
|
|
|
cerr << "SIGUSR1 received in thread " << pthread_name() << endl;
|
|
|
|
char const * adf = g_getenv ("ARDOUR_DEBUG_FLAGS");
|
|
|
|
if (!adf) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
PBD::parse_debug_options (adf);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-11-23 16:04:32 -05:00
|
|
|
#ifndef PLATFORM_WINDOWS
|
2008-09-10 17:27:39 -04:00
|
|
|
static void
|
2010-11-13 00:14:48 -05:00
|
|
|
sigpipe_handler (int /*signal*/)
|
2008-09-10 17:27:39 -04:00
|
|
|
{
|
2015-03-12 13:02:20 -04:00
|
|
|
/* XXX fix this so that we do this again after a reconnect to the backend */
|
2011-04-04 18:46:48 -04:00
|
|
|
|
2013-07-24 08:36:04 -04:00
|
|
|
static bool done_the_backend_thing = false;
|
2010-03-16 11:33:04 -04:00
|
|
|
|
2013-07-24 08:36:04 -04:00
|
|
|
if (!done_the_backend_thing) {
|
2010-03-16 11:33:04 -04:00
|
|
|
AudioEngine::instance()->died ();
|
2013-07-24 08:36:04 -04:00
|
|
|
g_idle_add (tell_about_backend_death, 0);
|
|
|
|
done_the_backend_thing = true;
|
2010-03-16 11:33:04 -04:00
|
|
|
}
|
2008-09-10 17:27:39 -04:00
|
|
|
}
|
2014-11-23 16:04:32 -05:00
|
|
|
#endif
|
2008-09-10 17:27:39 -04:00
|
|
|
|
2015-01-05 20:07:58 -05:00
|
|
|
#if (!defined COMPILER_MSVC && defined PLATFORM_WINDOWS)
|
2015-03-12 09:46:38 -04:00
|
|
|
|
2015-03-12 12:56:06 -04:00
|
|
|
static void command_line_parse_error (int *argc, char** argv[]) {}
|
|
|
|
|
|
|
|
#elif (defined(COMPILER_MSVC) && defined(NDEBUG) && !defined(RDC_BUILD))
|
|
|
|
|
|
|
|
static void command_line_parse_error (int *argc, char** argv[]) {
|
2015-03-12 13:02:20 -04:00
|
|
|
// Since we don't ordinarily have access to stdout and stderr with
|
|
|
|
// an MSVC app, let the user know we encountered a parsing error.
|
2015-03-17 10:53:53 -04:00
|
|
|
Gtk::Main app(argc, argv); // Calls 'gtk_init()'
|
2015-03-12 13:02:20 -04:00
|
|
|
|
2019-12-14 17:31:24 -05:00
|
|
|
ArdourMessageDialog dlgReportParseError (string_compose (_("\n %1 could not understand your command line "), PROGRAM_NAME),
|
2015-03-12 13:02:20 -04:00
|
|
|
false, MESSAGE_ERROR, BUTTONS_CLOSE, true);
|
2015-03-29 04:43:57 -04:00
|
|
|
dlgReportParseError.set_title (string_compose (_("An error was encountered while launching %1"), PROGRAM_NAME));
|
2015-03-12 13:02:20 -04:00
|
|
|
dlgReportParseError.run ();
|
2015-03-12 09:46:38 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
static void command_line_parse_error (int *argc, char** argv[]) {}
|
2015-01-05 20:04:12 -05:00
|
|
|
#endif
|
|
|
|
|
2014-04-14 11:59:28 -04:00
|
|
|
#if (defined(COMPILER_MSVC) && defined(NDEBUG) && !defined(RDC_BUILD))
|
2014-04-14 11:54:21 -04:00
|
|
|
/*
|
|
|
|
* Release build with MSVC uses ardour_main()
|
|
|
|
*/
|
|
|
|
int ardour_main (int argc, char *argv[])
|
2014-04-14 10:54:32 -04:00
|
|
|
|
2014-04-14 11:54:21 -04:00
|
|
|
#elif (defined WINDOWS_VST_SUPPORT && !defined PLATFORM_WINDOWS)
|
|
|
|
|
|
|
|
// prototype for function in windows_vst_plugin_ui.cc
|
2011-11-21 12:42:29 -05:00
|
|
|
extern int windows_vst_gui_init (int* argc, char** argv[]);
|
2009-02-27 12:11:21 -05:00
|
|
|
|
Large nasty commit in the form of a 5000 line patch chock-full of completely
unecessary changes. (Sorry, doing a "sprint" based thing, this is the end of the first one)
Achieved MIDI track and bus creation, associated Jack port and diskstream creation, and minimal GUI stuff for creating them. Should be set to start work on actually recording and playing midi to/from disk now.
Relevant (significant) changes:
- Creation of a Buffer class. Base class is type agnostic so things can point to a buffer but not care what kind it is (otherwise it'd be a template). Derived into AudioBuffer and MidiBuffer, with a type tag because checking type is necessary in parts of the code where dynamic_cast wouldn't be wise. Originally I considered this a hack, but passing around a type proved to be a very good solution to all the other problems (below). There is a 1:1 mapping between jack port data types and ardour Buffer types (with a conversion function), but that's easily removed if it ever becomes necessary. Having the type scoped in the Buffer class is maybe not the best spot for it, but whatever (this is proof of concept kinda stuff right now...)
- IO now has a "default" port type (passed to the constructor and stored as a member), used by ensure_io (and similar) to create n ports. IO::register_***_port has a type argument that defaults to the default type if not passed. Rationale: previous IO API is identical, no changes needed to existing code, but path is paved for multiple port types in one IO, which we will need for eg synth plugin inserts, among other things. This is not quite ideal (best would be to only have the two port register functions and have them take a type), but the alternative is a lot of work (namely destroying the 'ensure' functions and everything that uses them) for very little gain. (I am convinced after quite a few tries at the whiteboard that subclassing IO in any way is not a feasible option, look at it's inheritance diagram in Doxygen and you can see why)
- AudioEngine::register_audio_input_port is now register_input_port and takes a type argument. Ditto for output.
- (Most significant change) AudioDiskstream abstracted into Distream, and sibling MidiDiskstream created. Very much still a work in progress, but Diskstream is there to switch references over to (most already are), which is the important part. It is still unclear what the MIDI diskstream's relation to channels is, but I'm pretty sure they will be single channel only (so SMF Type 0) since noone can come up with a reason otherwise.
- MidiTrack creation. Same thing as AudioTrack but with a different default type basically. No big deal here.
- Random cleanups and variable renamings etc. because I have OCD and can't help myself. :)
Known broken: Loading of sessions containing MIDI tracks.
git-svn-id: svn://localhost/ardour2/branches/midi@641 d708f5d6-7413-0410-9779-e7cbd77b26cf
2006-06-26 12:01:34 -04:00
|
|
|
/* 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" {
|
2014-04-14 11:54:21 -04:00
|
|
|
|
Large nasty commit in the form of a 5000 line patch chock-full of completely
unecessary changes. (Sorry, doing a "sprint" based thing, this is the end of the first one)
Achieved MIDI track and bus creation, associated Jack port and diskstream creation, and minimal GUI stuff for creating them. Should be set to start work on actually recording and playing midi to/from disk now.
Relevant (significant) changes:
- Creation of a Buffer class. Base class is type agnostic so things can point to a buffer but not care what kind it is (otherwise it'd be a template). Derived into AudioBuffer and MidiBuffer, with a type tag because checking type is necessary in parts of the code where dynamic_cast wouldn't be wise. Originally I considered this a hack, but passing around a type proved to be a very good solution to all the other problems (below). There is a 1:1 mapping between jack port data types and ardour Buffer types (with a conversion function), but that's easily removed if it ever becomes necessary. Having the type scoped in the Buffer class is maybe not the best spot for it, but whatever (this is proof of concept kinda stuff right now...)
- IO now has a "default" port type (passed to the constructor and stored as a member), used by ensure_io (and similar) to create n ports. IO::register_***_port has a type argument that defaults to the default type if not passed. Rationale: previous IO API is identical, no changes needed to existing code, but path is paved for multiple port types in one IO, which we will need for eg synth plugin inserts, among other things. This is not quite ideal (best would be to only have the two port register functions and have them take a type), but the alternative is a lot of work (namely destroying the 'ensure' functions and everything that uses them) for very little gain. (I am convinced after quite a few tries at the whiteboard that subclassing IO in any way is not a feasible option, look at it's inheritance diagram in Doxygen and you can see why)
- AudioEngine::register_audio_input_port is now register_input_port and takes a type argument. Ditto for output.
- (Most significant change) AudioDiskstream abstracted into Distream, and sibling MidiDiskstream created. Very much still a work in progress, but Diskstream is there to switch references over to (most already are), which is the important part. It is still unclear what the MIDI diskstream's relation to channels is, but I'm pretty sure they will be single channel only (so SMF Type 0) since noone can come up with a reason otherwise.
- MidiTrack creation. Same thing as AudioTrack but with a different default type basically. No big deal here.
- Random cleanups and variable renamings etc. because I have OCD and can't help myself. :)
Known broken: Loading of sessions containing MIDI tracks.
git-svn-id: svn://localhost/ardour2/branches/midi@641 d708f5d6-7413-0410-9779-e7cbd77b26cf
2006-06-26 12:01:34 -04:00
|
|
|
int ardour_main (int argc, char *argv[])
|
2014-04-14 10:54:32 -04:00
|
|
|
|
2016-03-20 15:52:12 -04:00
|
|
|
#elif defined NOMAIN
|
|
|
|
int nomain (int argc, char *argv[])
|
Large nasty commit in the form of a 5000 line patch chock-full of completely
unecessary changes. (Sorry, doing a "sprint" based thing, this is the end of the first one)
Achieved MIDI track and bus creation, associated Jack port and diskstream creation, and minimal GUI stuff for creating them. Should be set to start work on actually recording and playing midi to/from disk now.
Relevant (significant) changes:
- Creation of a Buffer class. Base class is type agnostic so things can point to a buffer but not care what kind it is (otherwise it'd be a template). Derived into AudioBuffer and MidiBuffer, with a type tag because checking type is necessary in parts of the code where dynamic_cast wouldn't be wise. Originally I considered this a hack, but passing around a type proved to be a very good solution to all the other problems (below). There is a 1:1 mapping between jack port data types and ardour Buffer types (with a conversion function), but that's easily removed if it ever becomes necessary. Having the type scoped in the Buffer class is maybe not the best spot for it, but whatever (this is proof of concept kinda stuff right now...)
- IO now has a "default" port type (passed to the constructor and stored as a member), used by ensure_io (and similar) to create n ports. IO::register_***_port has a type argument that defaults to the default type if not passed. Rationale: previous IO API is identical, no changes needed to existing code, but path is paved for multiple port types in one IO, which we will need for eg synth plugin inserts, among other things. This is not quite ideal (best would be to only have the two port register functions and have them take a type), but the alternative is a lot of work (namely destroying the 'ensure' functions and everything that uses them) for very little gain. (I am convinced after quite a few tries at the whiteboard that subclassing IO in any way is not a feasible option, look at it's inheritance diagram in Doxygen and you can see why)
- AudioEngine::register_audio_input_port is now register_input_port and takes a type argument. Ditto for output.
- (Most significant change) AudioDiskstream abstracted into Distream, and sibling MidiDiskstream created. Very much still a work in progress, but Diskstream is there to switch references over to (most already are), which is the important part. It is still unclear what the MIDI diskstream's relation to channels is, but I'm pretty sure they will be single channel only (so SMF Type 0) since noone can come up with a reason otherwise.
- MidiTrack creation. Same thing as AudioTrack but with a different default type basically. No big deal here.
- Random cleanups and variable renamings etc. because I have OCD and can't help myself. :)
Known broken: Loading of sessions containing MIDI tracks.
git-svn-id: svn://localhost/ardour2/branches/midi@641 d708f5d6-7413-0410-9779-e7cbd77b26cf
2006-06-26 12:01:34 -04:00
|
|
|
#else
|
|
|
|
int main (int argc, char *argv[])
|
|
|
|
#endif
|
2005-09-25 14:42:24 -04:00
|
|
|
{
|
2020-09-29 10:46:00 -04:00
|
|
|
console_madness_begin();
|
|
|
|
|
2015-03-23 13:31:55 -04:00
|
|
|
ARDOUR::check_for_old_configuration_files();
|
|
|
|
|
2017-08-31 13:33:51 -04:00
|
|
|
/* global init is not thread safe.*/
|
|
|
|
if (curl_global_init (CURL_GLOBAL_DEFAULT)) {
|
|
|
|
cerr << "curl_global_init() failed. The web is gone. We're all doomed." << endl;
|
|
|
|
}
|
|
|
|
|
2015-04-17 11:00:33 -04:00
|
|
|
fixup_bundle_environment (argc, argv, localedir);
|
2007-10-11 18:07:47 -04:00
|
|
|
|
2014-04-14 10:54:32 -04:00
|
|
|
load_custom_fonts(); /* needs to happen before any gtk and pango init calls */
|
2013-01-29 10:25:30 -05:00
|
|
|
|
2011-02-10 12:44:33 -05:00
|
|
|
if (!Glib::thread_supported()) {
|
2009-10-27 14:00:45 -04:00
|
|
|
Glib::thread_init();
|
2011-04-04 18:46:48 -04:00
|
|
|
}
|
2009-10-27 14:00:45 -04:00
|
|
|
|
2017-03-05 19:48:46 -05:00
|
|
|
#ifdef LXVST_SUPPORT
|
|
|
|
XInitThreads ();
|
|
|
|
#endif
|
|
|
|
|
2018-09-21 13:04:06 -04:00
|
|
|
#if ENABLE_NLS
|
2017-04-20 16:12:18 -04:00
|
|
|
/* initialize C locale to user preference */
|
2016-12-28 06:39:43 -05:00
|
|
|
if (ARDOUR::translations_are_enabled ()) {
|
2020-05-01 14:28:52 -04:00
|
|
|
if (!setlocale (LC_ALL, "")) {
|
|
|
|
std::cerr << "localization call failed, " << PROGRAM_NAME << " will not be translated\n";
|
|
|
|
}
|
2016-07-15 10:10:42 -04:00
|
|
|
}
|
2013-01-23 11:09:10 -05:00
|
|
|
#endif
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2014-04-15 06:01:48 -04:00
|
|
|
#if (defined WINDOWS_VST_SUPPORT && !defined PLATFORM_WINDOWS)
|
2014-04-14 11:54:21 -04:00
|
|
|
/* this does some magic that is needed to make GTK and X11 client interact properly.
|
|
|
|
* the platform dependent code is in windows_vst_plugin_ui.cc
|
|
|
|
*/
|
2011-11-21 12:42:29 -05:00
|
|
|
windows_vst_gui_init (&argc, &argv);
|
2009-02-27 12:11:21 -05:00
|
|
|
#endif
|
|
|
|
|
2018-09-21 13:04:06 -04:00
|
|
|
#if ENABLE_NLS
|
2020-03-25 13:39:32 -04:00
|
|
|
|
|
|
|
#ifndef NDEBUG
|
2014-04-14 10:54:32 -04:00
|
|
|
cerr << "bind txt domain [" << PACKAGE << "] to " << localedir << endl;
|
2020-03-25 13:39:32 -04:00
|
|
|
#endif
|
2013-01-21 22:29:28 -05:00
|
|
|
|
2015-04-17 11:00:33 -04:00
|
|
|
(void) bindtextdomain (PACKAGE, localedir.c_str());
|
2007-01-28 12:44:13 -05:00
|
|
|
/* our i18n translations are all in UTF-8, so make sure
|
|
|
|
that even if the user locale doesn't specify UTF-8,
|
|
|
|
we use that when handling them.
|
|
|
|
*/
|
|
|
|
(void) bind_textdomain_codeset (PACKAGE,"UTF-8");
|
2013-01-21 22:29:28 -05:00
|
|
|
#endif
|
2005-09-25 14:42:24 -04:00
|
|
|
|
|
|
|
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
|
|
|
|
|
2007-01-09 18:24:54 -05:00
|
|
|
// catch error message system signals ();
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2020-10-13 15:51:39 -04:00
|
|
|
text_receiver.listen_to (debug);
|
2005-09-25 14:42:24 -04:00
|
|
|
text_receiver.listen_to (info);
|
|
|
|
text_receiver.listen_to (warning);
|
2020-10-13 15:51:39 -04:00
|
|
|
text_receiver.listen_to (error);
|
|
|
|
text_receiver.listen_to (fatal);
|
2005-09-25 14:42:24 -04:00
|
|
|
|
2011-02-10 12:44:33 -05:00
|
|
|
#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
|
2013-07-11 11:37:25 -04:00
|
|
|
if (g_getenv ("BOOST_DEBUG")) {
|
2011-04-04 18:46:48 -04:00
|
|
|
boost_debug_shared_ptr_show_live_debugging (true);
|
|
|
|
}
|
2011-02-10 12:44:33 -05:00
|
|
|
#endif
|
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
if (parse_opts (argc, argv)) {
|
2015-03-12 09:46:38 -04:00
|
|
|
command_line_parse_error (&argc, &argv);
|
2019-07-04 16:21:49 -04:00
|
|
|
exit (EXIT_FAILURE);
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2022-06-14 11:12:30 -04:00
|
|
|
#if !(defined NDEBUG || defined PLATFORM_WINDOWS)
|
2019-12-13 15:06:31 -05:00
|
|
|
{
|
2022-06-13 15:48:37 -04:00
|
|
|
const char * adf;
|
2019-12-13 15:06:31 -05:00
|
|
|
if ((adf = g_getenv ("ARDOUR_DEBUG_FLAGS"))) {
|
2022-06-13 15:48:37 -04:00
|
|
|
if (!g_getenv ("ARDOUR_DEBUG_ON_SIGUSR1")) {
|
|
|
|
PBD::parse_debug_options (adf);
|
|
|
|
}
|
2019-12-13 15:06:31 -05:00
|
|
|
}
|
|
|
|
}
|
2022-06-14 11:12:30 -04:00
|
|
|
#endif
|
2019-12-13 15:06:31 -05:00
|
|
|
|
2010-03-14 22:31:27 -04:00
|
|
|
cout << PROGRAM_NAME
|
2005-09-25 14:42:24 -04:00
|
|
|
<< VERSIONSTRING
|
The great audio processing overhaul.
The vast majority of Route signal processing is now simply in the list of
processors. There are definitely regressions here, but there's also
a lot of things fixed. It's far too much work to let diverge anymore
regardless, so here it is.
The basic model is: A route has a fixed set of input channels (matching
its JACK input ports and diskstream). The first processor takes this
as input. The next processor is configured using the first processor's
output as input, and is allowed to choose whatever output it wants
given that input... and so on, and so on. Finally, the last processor's
requested output is used to set up the panner and create whatever Jack
ports are needed to output the data.
All 'special' internal processors (meter, fader, amp, insert, send) are
currently transparent: they read any input, and return the same set
of channels back (unmodified, except for amp).
User visible changes:
* LV2 Instrument support (tracks with both MIDI and audio channels)
* MIDI in/out plugin support
* Generic plugin replication (for MIDI plugins, MIDI/audio plugins)
* Movable meter point
Known Bugs:
* Things seem to get weird on loaded sessions
* Output delivery is sketchy
* 2.0 session loading was probably already broken...
but it's definitely broken now :)
Please test this and file bugs if you have any time...
git-svn-id: svn://localhost/ardour2/branches/3.0@5055 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-05-07 02:30:50 -04:00
|
|
|
<< _(" (built using ")
|
2013-03-17 09:53:30 -04:00
|
|
|
<< revision
|
2005-09-25 14:42:24 -04:00
|
|
|
#ifdef __GNUC__
|
2009-10-14 12:10:01 -04:00
|
|
|
<< _(" and GCC version ") << __VERSION__
|
2005-09-25 14:42:24 -04:00
|
|
|
#endif
|
|
|
|
<< ')'
|
|
|
|
<< endl;
|
2009-10-14 12:10:01 -04:00
|
|
|
|
2005-09-25 14:42:24 -04:00
|
|
|
if (just_version) {
|
2019-07-04 16:21:49 -04:00
|
|
|
exit (EXIT_SUCCESS);
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (no_splash) {
|
2022-01-01 06:46:31 -05:00
|
|
|
cout << _("Copyright (C) 1999-2022 Paul Davis") << endl
|
2012-11-13 10:11:07 -05:00
|
|
|
<< _("Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker, Robin Gareus") << endl
|
2005-09-25 14:42:24 -04:00
|
|
|
<< endl
|
2010-03-14 22:31:27 -04:00
|
|
|
<< string_compose (_("%1 comes with ABSOLUTELY NO WARRANTY"), PROGRAM_NAME) << endl
|
2019-04-13 11:48:27 -04:00
|
|
|
<< _("not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.") << endl
|
2005-09-25 14:42:24 -04:00
|
|
|
<< _("This is free software, and you are welcome to redistribute it ") << endl
|
|
|
|
<< _("under certain conditions; see the source for copying conditions.")
|
|
|
|
<< endl;
|
|
|
|
}
|
|
|
|
|
2021-07-06 14:59:15 -04:00
|
|
|
#ifdef PLATFORM_WINDOWS
|
|
|
|
CreateMutexA (0, 1, string_compose ("%1%2", PROGRAM_NAME, PROGRAM_VERSION).c_str ());
|
|
|
|
if (GetLastError() == ERROR_ALREADY_EXISTS) {
|
|
|
|
Gtk::Main main (argc, argv);
|
|
|
|
Gtk::MessageDialog msg (string_compose (_("%1 is already running."), PROGRAM_NAME),
|
|
|
|
false, Gtk::MESSAGE_ERROR , Gtk::BUTTONS_OK, true);
|
|
|
|
msg.run ();
|
|
|
|
exit (EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2020-09-28 23:48:25 -04:00
|
|
|
#ifdef HAVE_DRMINGW
|
2021-01-02 17:19:40 -05:00
|
|
|
/* prevent missing libs popups */
|
|
|
|
UINT prev_error_mode = SetErrorMode (SEM_FAILCRITICALERRORS);
|
|
|
|
SetErrorMode (prev_error_mode | SEM_FAILCRITICALERRORS);
|
|
|
|
HMODULE exchndl = LoadLibraryA ("exchndl.dll");
|
|
|
|
|
|
|
|
if (exchndl) {
|
2020-09-29 10:42:27 -04:00
|
|
|
/* %localappdata%\Ardour<X>\CrashLog\ */
|
|
|
|
string crash_dir = Glib::build_filename (Glib::get_user_data_dir (), string_compose ("%1%2", PROGRAM_NAME, PROGRAM_VERSION), "CrashLog");
|
|
|
|
g_mkdir_with_parents (crash_dir.c_str(), 0700);
|
2020-09-28 23:48:25 -04:00
|
|
|
|
2020-09-29 10:42:27 -04:00
|
|
|
Glib::DateTime tm (g_date_time_new_now_local ());
|
2020-09-29 11:34:21 -04:00
|
|
|
string crash_file = string_compose ("%1-%2-crash-%3.txt", PROGRAM_NAME, VERSIONSTRING, tm.format ("%s"));
|
2020-09-28 23:48:25 -04:00
|
|
|
string crash_path = Glib::build_filename (crash_dir, crash_file);
|
|
|
|
|
2021-01-02 17:19:40 -05:00
|
|
|
typedef void (*exc_init_fn_t) (void);
|
|
|
|
typedef bool (*exc_path_fn_t) (const char *);
|
|
|
|
|
|
|
|
exc_init_fn_t exchndl_init = (exc_init_fn_t) GetProcAddress (exchndl, "ExcHndlInit");
|
|
|
|
exc_path_fn_t exchndl_path = (exc_path_fn_t) GetProcAddress (exchndl, "ExcHndlSetLogFileNameA");
|
|
|
|
|
|
|
|
if (exchndl_init && exchndl_path) {
|
|
|
|
exchndl_init ();
|
|
|
|
exchndl_path (crash_path.c_str());
|
|
|
|
cout << "Crash Log: " << crash_path << endl;
|
|
|
|
} else {
|
|
|
|
cout << "Cannot initialize crash reporter" << endl;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
cout << "Crash reporter is not compatible with this system" << endl;
|
2020-09-28 23:48:25 -04:00
|
|
|
}
|
2021-01-02 17:19:40 -05:00
|
|
|
SetErrorMode (prev_error_mode);
|
2020-09-28 23:48:25 -04:00
|
|
|
#endif
|
|
|
|
|
2021-08-12 12:06:24 -04:00
|
|
|
if (!ARDOUR::init (ARDOUR_COMMAND_LINE::try_hw_optimization, localedir.c_str(), true)) {
|
2013-08-09 07:47:16 -04:00
|
|
|
error << string_compose (_("could not initialize %1."), PROGRAM_NAME) << endmsg;
|
2017-07-03 08:44:03 -04:00
|
|
|
Gtk::Main main (argc, argv);
|
|
|
|
Gtk::MessageDialog msg (string_compose (_("Could not initialize %1 (likely due to corrupt config files).\n"
|
|
|
|
"Run %1 from a commandline for more information."), PROGRAM_NAME),
|
|
|
|
false, Gtk::MESSAGE_ERROR , Gtk::BUTTONS_OK, true);
|
|
|
|
msg.run ();
|
2019-07-04 16:21:49 -04:00
|
|
|
exit (EXIT_FAILURE);
|
2013-08-09 07:47:16 -04:00
|
|
|
}
|
|
|
|
|
2013-10-14 12:00:28 -04:00
|
|
|
#ifndef PLATFORM_WINDOWS
|
2008-09-10 17:27:39 -04:00
|
|
|
if (::signal (SIGPIPE, sigpipe_handler)) {
|
2010-09-20 11:12:44 -04:00
|
|
|
cerr << _("Cannot xinstall SIGPIPE error handler") << endl;
|
2008-09-10 17:27:39 -04:00
|
|
|
}
|
2013-07-11 22:34:59 -04:00
|
|
|
#endif
|
2008-09-10 17:27:39 -04:00
|
|
|
|
2022-06-14 11:12:30 -04:00
|
|
|
#if !(defined NDEBUG || defined PLATFORM_WINDOWS)
|
2022-06-13 15:48:37 -04:00
|
|
|
if (g_getenv ("ARDOUR_DEBUG_ON_SIGUSR1")) {
|
|
|
|
if (::signal (SIGUSR1, sigusr1_handler)) {
|
|
|
|
cerr << _("Cannot install SIGUSR1 error handler") << endl;
|
|
|
|
} else {
|
|
|
|
cerr << _("Installed SIGUSR1 debug handler") << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-05-07 06:19:41 -04:00
|
|
|
DEBUG_TRACE (DEBUG::Locale, string_compose ("main() locale '%1'\n", setlocale (LC_NUMERIC, NULL)));
|
|
|
|
|
2015-01-02 09:44:54 -05:00
|
|
|
if (UIConfiguration::instance().pre_gui_init ()) {
|
2015-05-28 12:46:31 -04:00
|
|
|
error << _("Could not complete pre-GUI initialization") << endmsg;
|
2019-07-04 16:21:49 -04:00
|
|
|
exit (EXIT_FAILURE);
|
2015-05-28 12:46:31 -04:00
|
|
|
}
|
2015-10-05 10:17:49 -04:00
|
|
|
|
2009-10-27 14:00:45 -04:00
|
|
|
try {
|
2015-01-02 09:44:54 -05:00
|
|
|
ui = new ARDOUR_UI (&argc, &argv, localedir.c_str());
|
2006-08-30 22:28:42 -04:00
|
|
|
} catch (failed_constructor& err) {
|
2013-02-05 13:18:35 -05:00
|
|
|
error << string_compose (_("could not create %1 GUI"), PROGRAM_NAME) << endmsg;
|
2019-07-04 16:21:49 -04:00
|
|
|
exit (EXIT_FAILURE);
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
|
|
|
|
2015-07-30 13:05:12 -04:00
|
|
|
#ifndef NDEBUG
|
2021-06-02 18:10:25 -04:00
|
|
|
g_log_set_default_handler (&ardour_g_log, NULL);
|
2015-07-30 13:05:12 -04:00
|
|
|
#endif
|
|
|
|
|
2007-10-11 18:07:47 -04:00
|
|
|
ui->run (text_receiver);
|
2011-04-04 18:46:48 -04:00
|
|
|
Gtkmm2ext::Application::instance()->cleanup();
|
2013-10-07 20:28:20 -04:00
|
|
|
delete ui;
|
2007-10-11 18:07:47 -04:00
|
|
|
ui = 0;
|
2007-03-18 02:07:08 -04:00
|
|
|
|
2007-10-11 18:07:47 -04:00
|
|
|
ARDOUR::cleanup ();
|
2017-01-20 07:31:24 -05:00
|
|
|
#ifndef NDEBUG
|
|
|
|
if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
|
|
|
|
Glib::usleep(100000);
|
|
|
|
sched_yield();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-12-09 13:37:06 -05:00
|
|
|
pthread_cancel_all ();
|
2009-12-08 22:05:14 -05:00
|
|
|
|
2017-01-20 07:31:24 -05:00
|
|
|
#ifndef NDEBUG
|
|
|
|
if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
|
|
|
|
Glib::usleep(100000);
|
|
|
|
sched_yield();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-03-12 09:46:38 -04:00
|
|
|
console_madness_end ();
|
2015-03-12 13:02:20 -04:00
|
|
|
|
Large nasty commit in the form of a 5000 line patch chock-full of completely
unecessary changes. (Sorry, doing a "sprint" based thing, this is the end of the first one)
Achieved MIDI track and bus creation, associated Jack port and diskstream creation, and minimal GUI stuff for creating them. Should be set to start work on actually recording and playing midi to/from disk now.
Relevant (significant) changes:
- Creation of a Buffer class. Base class is type agnostic so things can point to a buffer but not care what kind it is (otherwise it'd be a template). Derived into AudioBuffer and MidiBuffer, with a type tag because checking type is necessary in parts of the code where dynamic_cast wouldn't be wise. Originally I considered this a hack, but passing around a type proved to be a very good solution to all the other problems (below). There is a 1:1 mapping between jack port data types and ardour Buffer types (with a conversion function), but that's easily removed if it ever becomes necessary. Having the type scoped in the Buffer class is maybe not the best spot for it, but whatever (this is proof of concept kinda stuff right now...)
- IO now has a "default" port type (passed to the constructor and stored as a member), used by ensure_io (and similar) to create n ports. IO::register_***_port has a type argument that defaults to the default type if not passed. Rationale: previous IO API is identical, no changes needed to existing code, but path is paved for multiple port types in one IO, which we will need for eg synth plugin inserts, among other things. This is not quite ideal (best would be to only have the two port register functions and have them take a type), but the alternative is a lot of work (namely destroying the 'ensure' functions and everything that uses them) for very little gain. (I am convinced after quite a few tries at the whiteboard that subclassing IO in any way is not a feasible option, look at it's inheritance diagram in Doxygen and you can see why)
- AudioEngine::register_audio_input_port is now register_input_port and takes a type argument. Ditto for output.
- (Most significant change) AudioDiskstream abstracted into Distream, and sibling MidiDiskstream created. Very much still a work in progress, but Diskstream is there to switch references over to (most already are), which is the important part. It is still unclear what the MIDI diskstream's relation to channels is, but I'm pretty sure they will be single channel only (so SMF Type 0) since noone can come up with a reason otherwise.
- MidiTrack creation. Same thing as AudioTrack but with a different default type basically. No big deal here.
- Random cleanups and variable renamings etc. because I have OCD and can't help myself. :)
Known broken: Loading of sessions containing MIDI tracks.
git-svn-id: svn://localhost/ardour2/branches/midi@641 d708f5d6-7413-0410-9779-e7cbd77b26cf
2006-06-26 12:01:34 -04:00
|
|
|
return 0;
|
2005-09-25 14:42:24 -04:00
|
|
|
}
|
2014-04-14 11:54:21 -04:00
|
|
|
#if (defined WINDOWS_VST_SUPPORT && !defined PLATFORM_WINDOWS)
|
2014-04-14 10:54:32 -04:00
|
|
|
} // end of extern "C" block
|
Large nasty commit in the form of a 5000 line patch chock-full of completely
unecessary changes. (Sorry, doing a "sprint" based thing, this is the end of the first one)
Achieved MIDI track and bus creation, associated Jack port and diskstream creation, and minimal GUI stuff for creating them. Should be set to start work on actually recording and playing midi to/from disk now.
Relevant (significant) changes:
- Creation of a Buffer class. Base class is type agnostic so things can point to a buffer but not care what kind it is (otherwise it'd be a template). Derived into AudioBuffer and MidiBuffer, with a type tag because checking type is necessary in parts of the code where dynamic_cast wouldn't be wise. Originally I considered this a hack, but passing around a type proved to be a very good solution to all the other problems (below). There is a 1:1 mapping between jack port data types and ardour Buffer types (with a conversion function), but that's easily removed if it ever becomes necessary. Having the type scoped in the Buffer class is maybe not the best spot for it, but whatever (this is proof of concept kinda stuff right now...)
- IO now has a "default" port type (passed to the constructor and stored as a member), used by ensure_io (and similar) to create n ports. IO::register_***_port has a type argument that defaults to the default type if not passed. Rationale: previous IO API is identical, no changes needed to existing code, but path is paved for multiple port types in one IO, which we will need for eg synth plugin inserts, among other things. This is not quite ideal (best would be to only have the two port register functions and have them take a type), but the alternative is a lot of work (namely destroying the 'ensure' functions and everything that uses them) for very little gain. (I am convinced after quite a few tries at the whiteboard that subclassing IO in any way is not a feasible option, look at it's inheritance diagram in Doxygen and you can see why)
- AudioEngine::register_audio_input_port is now register_input_port and takes a type argument. Ditto for output.
- (Most significant change) AudioDiskstream abstracted into Distream, and sibling MidiDiskstream created. Very much still a work in progress, but Diskstream is there to switch references over to (most already are), which is the important part. It is still unclear what the MIDI diskstream's relation to channels is, but I'm pretty sure they will be single channel only (so SMF Type 0) since noone can come up with a reason otherwise.
- MidiTrack creation. Same thing as AudioTrack but with a different default type basically. No big deal here.
- Random cleanups and variable renamings etc. because I have OCD and can't help myself. :)
Known broken: Loading of sessions containing MIDI tracks.
git-svn-id: svn://localhost/ardour2/branches/midi@641 d708f5d6-7413-0410-9779-e7cbd77b26cf
2006-06-26 12:01:34 -04:00
|
|
|
#endif
|