commandline session utilities
[ardour.git] / session_utils / common.cc
1 #include <iostream>
2 #include <cstdlib>
3
4
5 #include "pbd/debug.h"
6 #include "pbd/event_loop.h"
7 #include "pbd/error.h"
8 #include "pbd/failed_constructor.h"
9 #include "pbd/pthread_utils.h"
10
11 #include "ardour/audioengine.h"
12
13 #include "common.h"
14
15 using namespace std;
16 using namespace ARDOUR;
17 using namespace PBD;
18
19 static const char* localedir = LOCALEDIR;
20 TestReceiver test_receiver;
21
22 void
23 TestReceiver::receive (Transmitter::Channel chn, const char * str)
24 {
25         const char *prefix = "";
26
27         switch (chn) {
28         case Transmitter::Error:
29                 prefix = ": [ERROR]: ";
30                 break;
31         case Transmitter::Info:
32                 /* ignore */
33                 return;
34         case Transmitter::Warning:
35                 prefix = ": [WARNING]: ";
36                 break;
37         case Transmitter::Fatal:
38                 prefix = ": [FATAL]: ";
39                 break;
40         case Transmitter::Throw:
41                 /* this isn't supposed to happen */
42                 abort ();
43         }
44
45         /* note: iostreams are already thread-safe: no external
46            lock required.
47         */
48
49         std::cout << prefix << str << std::endl;
50
51         if (chn == Transmitter::Fatal) {
52                 ::exit (9);
53         }
54 }
55
56 /* temporarily required due to some code design confusion (Feb 2014) */
57
58 #include "ardour/vst_types.h"
59
60 int vstfx_init (void*) { return 0; }
61 void vstfx_exit () {}
62 void vstfx_destroy_editor (VSTState*) {}
63
64 class MyEventLoop : public sigc::trackable, public EventLoop
65 {
66         public:
67                 MyEventLoop (std::string const& name) : EventLoop (name) {
68                         run_loop_thread = Glib::Threads::Thread::self();
69                 }
70
71                 void call_slot (InvalidationRecord*, const boost::function<void()>& f) {
72                         if (Glib::Threads::Thread::self() == run_loop_thread) {
73                                 f ();
74                         }
75                 }
76
77                 Glib::Threads::Mutex& slot_invalidation_mutex() { return request_buffer_map_lock; }
78
79         private:
80                 Glib::Threads::Thread* run_loop_thread;
81                 Glib::Threads::Mutex   request_buffer_map_lock;
82 };
83
84 static MyEventLoop *event_loop;
85
86 void
87 SessionUtils::init ()
88 {
89         if (!ARDOUR::init (false, true, localedir)) {
90                 cerr << "Ardour failed to initialize\n" << endl;
91                 ::exit (1);
92         }
93
94         event_loop = new MyEventLoop ("util");
95         EventLoop::set_event_loop_for_thread (event_loop);
96         SessionEvent::create_per_thread_pool ("util", 512);
97
98         test_receiver.listen_to (error);
99         test_receiver.listen_to (info);
100         test_receiver.listen_to (fatal);
101         test_receiver.listen_to (warning);
102 }
103
104 static Session * _load_session (string dir, string state)
105 {
106         AudioEngine* engine = AudioEngine::create ();
107
108         if (!engine->set_backend ("None (Dummy)", "Unit-Test", "")) {
109                 std::cerr << "Cannot create Audio/MIDI engine\n";
110                 ::exit (EXIT_FAILURE);
111         }
112
113         init_post_engine ();
114
115         if (engine->start () != 0) {
116                 std::cerr << "Cannot start Audio/MIDI engine\n";
117                 ::exit (EXIT_FAILURE);
118         }
119
120         Session* session = new Session (*engine, dir, state);
121         engine->set_session (session);
122         return session;
123 }
124
125 Session *
126 SessionUtils::load_session (string dir, string state)
127 {
128         Session* s = 0;
129         try {
130                 s = _load_session (dir, state);
131         } catch (failed_constructor& e) {
132                 cerr << "failed_constructor: " << e.what() << "\n";
133                 exit (EXIT_FAILURE);
134         } catch (AudioEngine::PortRegistrationFailure& e) {
135                 cerr << "PortRegistrationFailure: " << e.what() << "\n";
136                 exit (EXIT_FAILURE);
137         } catch (exception& e) {
138                 cerr << "exception: " << e.what() << "\n";
139                 exit (EXIT_FAILURE);
140         } catch (...) {
141                 cerr << "unknown exception.\n";
142                 exit (EXIT_FAILURE);
143         }
144         return s;
145 }
146
147 void
148 SessionUtils::unload_session (Session *s)
149 {
150         delete s;
151         AudioEngine::instance()->stop ();
152         AudioEngine::destroy ();
153 }
154
155 void
156 SessionUtils::cleanup ()
157 {
158         ARDOUR::cleanup ();
159         delete event_loop;
160         pthread_cancel_all ();
161 }