ardour/gtk2_ardour/main.cc

500 lines
14 KiB
C++
Raw Normal View History

/*
* 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.
*/
#include <cstdlib>
#include <cerrno>
#include <vector>
#include <signal.h>
#include <locale.h>
#include <sigc++/bind.h>
#include <gtkmm/settings.h>
#include <curl/curl.h>
#include "pbd/error.h"
#include "pbd/file_utils.h"
#include "pbd/textreceiver.h"
#include "pbd/failed_constructor.h"
#include "pbd/pathexpand.h"
#include "pbd/pthread_utils.h"
2020-09-20 14:00:33 -04:00
#include "pbd/win_console.h"
#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
#include "pbd/boost_debug.h"
#endif
#include "ardour/revision.h"
#include "ardour/ardour.h"
#include "ardour/audioengine.h"
#include "ardour/session_utils.h"
#include "ardour/filesystem_paths.h"
#include <gtkmm/main.h>
#include <gtkmm/stock.h>
#include <gtkmm2ext/application.h>
#include <gtkmm2ext/utils.h>
#include "ardour_message.h"
#include "ardour_ui.h"
#include "ui_config.h"
#include "opts.h"
#include "enums.h"
#include "bundle_env.h"
#include "pbd/i18n.h"
#ifdef PLATFORM_WINDOWS
#include <windows.h> // CreateMutex
#include <fcntl.h> // Needed for '_fmode'
#include <shellapi.h> // console
#endif
#ifdef WAF_BUILD
#include "gtk2ardour-version.h"
#endif
2017-03-05 19:48:46 -05:00
#ifdef LXVST_SUPPORT
#include <gdk/gdkx.h>
#endif
using namespace std;
using namespace Gtk;
using namespace ARDOUR_COMMAND_LINE;
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;
TextReceiver text_receiver (PROGRAM_NAME);
extern int curvetest (string);
static ARDOUR_UI *ui = 0;
static string localedir (LOCALEDIR);
void
gui_jack_error ()
{
ArdourMessageDialog win (string_compose (_("%1 could not connect to the audio backend."), PROGRAM_NAME),
false,
Gtk::MESSAGE_INFO,
Gtk::BUTTONS_NONE);
win.add_button (Stock::QUIT, RESPONSE_CLOSE);
win.set_default_response (RESPONSE_CLOSE);
win.show_all ();
win.set_position (Gtk::WIN_POS_CENTER);
if (!no_splash) {
ui->hide_splash ();
}
/* we just don't care about the result, but we want to block */
win.run ();
}
#ifndef NDEBUG
static void ardour_g_log (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) {
g_log_default_handler (log_domain, log_level, message, NULL);
switch (log_level) {
case G_LOG_FLAG_FATAL:
fatal << "g_log: " << message << endmsg;
break;
case G_LOG_LEVEL_CRITICAL:
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
static gboolean
tell_about_backend_death (void* /* ignored */)
{
if (AudioEngine::instance()->processed_samples() == 0) {
/* died during startup */
ArdourMessageDialog msg (string_compose (_("The audio backend (%1) has failed, or terminated"), AudioEngine::instance()->current_backend_name()), false);
msg.set_position (Gtk::WIN_POS_CENTER);
msg.set_secondary_text (string_compose (_(
"%2 exited unexpectedly, and without notifying %1.\n\
\n\
This could be due to misconfiguration or to an error inside %2.\n\
\n\
Click OK to exit %1."), PROGRAM_NAME, AudioEngine::instance()->current_backend_name()));
msg.run ();
_exit (EXIT_SUCCESS);
} else {
/* engine has already run, so this is a mid-session backend death */
2015-03-12 13:02:20 -04:00
ArdourMessageDialog msg (string_compose (_("The audio backend (%1) has failed, or terminated"), AudioEngine::instance()->current_backend_name()), false);
msg.set_secondary_text (string_compose (_("%2 exited unexpectedly, and without notifying %1."),
PROGRAM_NAME, AudioEngine::instance()->current_backend_name()));
msg.run ();
}
return false; /* do not call again */
}
#if !(defined NDEBUG || defined PLATFORM_WINDOWS)
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
#ifndef PLATFORM_WINDOWS
static void
sigpipe_handler (int /*signal*/)
{
2015-03-12 13:02:20 -04:00
/* XXX fix this so that we do this again after a reconnect to the backend */
static bool done_the_backend_thing = false;
if (!done_the_backend_thing) {
AudioEngine::instance()->died ();
g_idle_add (tell_about_backend_death, 0);
done_the_backend_thing = true;
}
}
#endif
#if (!defined COMPILER_MSVC && defined PLATFORM_WINDOWS)
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.
Gtk::Main app(argc, argv); // Calls 'gtk_init()'
2015-03-12 13:02:20 -04: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);
dlgReportParseError.set_title (string_compose (_("An error was encountered while launching %1"), PROGRAM_NAME));
2015-03-12 13:02:20 -04:00
dlgReportParseError.run ();
}
#else
static void command_line_parse_error (int *argc, char** argv[]) {}
#endif
2014-04-14 11:59:28 -04:00
#if (defined(COMPILER_MSVC) && defined(NDEBUG) && !defined(RDC_BUILD))
/*
* Release build with MSVC uses ardour_main()
*/
int ardour_main (int argc, char *argv[])
#elif (defined WINDOWS_VST_SUPPORT && !defined PLATFORM_WINDOWS)
// prototype for function in windows_vst_plugin_ui.cc
extern int windows_vst_gui_init (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
/* 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" {
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[])
#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
{
console_madness_begin();
ARDOUR::check_for_old_configuration_files();
/* 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;
}
fixup_bundle_environment (argc, argv, localedir);
load_custom_fonts(); /* needs to happen before any gtk and pango init calls */
if (!Glib::thread_supported()) {
Glib::thread_init();
}
2017-03-05 19:48:46 -05:00
#ifdef LXVST_SUPPORT
XInitThreads ();
#endif
#if ENABLE_NLS
/* 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";
}
2022-10-09 02:26:52 -04:00
} else {
/* Force-disable localization if the user wishes so;
* just calling setlocale (...,"C") is not sufficient for this;
* it is probably the LANG env var which gets picked up later somewhere.
*/
Glib::setenv ("LC_ALL", "C", true);
Glib::setenv ("LC_MESSAGES", "C", true);
Glib::setenv ("LANG", "C", true);
2016-07-15 10:10:42 -04:00
}
#endif
#if (defined WINDOWS_VST_SUPPORT && !defined PLATFORM_WINDOWS)
/* 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
*/
windows_vst_gui_init (&argc, &argv);
#endif
#if ENABLE_NLS
#ifndef NDEBUG
cerr << "bind txt domain [" << PACKAGE << "] to " << localedir << endl;
#endif
(void) bindtextdomain (PACKAGE, localedir.c_str());
/* 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");
#endif
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
// catch error message system signals ();
text_receiver.listen_to (debug);
text_receiver.listen_to (info);
text_receiver.listen_to (warning);
text_receiver.listen_to (error);
text_receiver.listen_to (fatal);
#ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
if (g_getenv ("BOOST_DEBUG")) {
boost_debug_shared_ptr_show_live_debugging (true);
}
#endif
/* This is horrible, but ... we don't want to init GTK until it is
* really time (during a Gtkmm2ext::UI constructor. However, this will
* try to load GTK modules too, so do this only if it appears that need
* to do this.
*/
for (int n = 1; n < argc; ++n) {
if (!strncmp (argv[n], "--gtk", 5) || !strncmp (argv[n], "--gdk", 5)) {
gtk_parse_args (&argc, &argv);
break;
}
}
if (parse_opts (argc, argv)) {
command_line_parse_error (&argc, &argv);
exit (EXIT_FAILURE);
}
#if !(defined NDEBUG || defined PLATFORM_WINDOWS)
{
const char * adf;
if ((adf = g_getenv ("ARDOUR_DEBUG_FLAGS"))) {
if (!g_getenv ("ARDOUR_DEBUG_ON_SIGUSR1")) {
PBD::parse_debug_options (adf);
}
}
}
#endif
cout << PROGRAM_NAME
<< VERSIONSTRING
<< _(" (built using ")
<< revision
#ifdef __GNUC__
<< _(" and GCC version ") << __VERSION__
#endif
<< ')'
<< endl;
if (just_version) {
exit (EXIT_SUCCESS);
}
if (no_splash) {
2024-04-12 18:54:15 -04:00
cout << _("Copyright (C) 1999-2024 Paul Davis") << endl
<< _("Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker, Robin Gareus") << endl
<< endl
<< string_compose (_("%1 comes with ABSOLUTELY NO WARRANTY"), PROGRAM_NAME) << endl
<< _("not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.") << endl
<< _("This is free software, and you are welcome to redistribute it ") << endl
<< _("under certain conditions; see the source for copying conditions.")
<< endl;
}
#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
/* prevent missing libs popups */
UINT prev_error_mode = SetErrorMode (SEM_FAILCRITICALERRORS);
SetErrorMode (prev_error_mode | SEM_FAILCRITICALERRORS);
HMODULE exchndl = LoadLibraryA ("exchndl.dll");
if (exchndl) {
/* %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
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);
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
}
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)) {
error << string_compose (_("could not initialize %1."), PROGRAM_NAME) << endmsg;
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 ();
exit (EXIT_FAILURE);
}
#ifndef PLATFORM_WINDOWS
if (::signal (SIGPIPE, sigpipe_handler)) {
cerr << _("Cannot xinstall SIGPIPE error handler") << endl;
}
#endif
#if !(defined NDEBUG || defined PLATFORM_WINDOWS)
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
DEBUG_TRACE (DEBUG::Locale, string_compose ("main() locale '%1'\n", setlocale (LC_NUMERIC, NULL)));
setup_gtk_ardour_enums ();
if (UIConfiguration::instance().pre_gui_init ()) {
error << _("Could not complete pre-GUI initialization") << endmsg;
exit (EXIT_FAILURE);
}
2015-10-05 10:17:49 -04:00
try {
ui = new ARDOUR_UI (&argc, &argv, localedir.c_str());
} catch (failed_constructor& err) {
error << string_compose (_("could not create %1 GUI"), PROGRAM_NAME) << endmsg;
exit (EXIT_FAILURE);
}
#ifndef NDEBUG
g_log_set_default_handler (&ardour_g_log, NULL);
#endif
ui->run (text_receiver);
Gtkmm2ext::Application::instance()->cleanup();
delete ui;
ui = 0;
ARDOUR::cleanup ();
#ifndef NDEBUG
if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
Glib::usleep(100000);
sched_yield();
}
#endif
pthread_cancel_all ();
#ifndef NDEBUG
if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
Glib::usleep(100000);
sched_yield();
}
#endif
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;
}
#if (defined WINDOWS_VST_SUPPORT && !defined PLATFORM_WINDOWS)
} // 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