* Support for restarting jack server
[jackpanel.git] / jackpanel / JackpanelBase.vala
blobc5518a09a16a9cb50eb192b9021fbe6a24e9d5b6
1 using Gtk;
2 using Gdk;
3 using Prolooks;
5 namespace Jackpanel {
7 public static uint32 no_xruns;
9 public static int jackpanel_xrun_callback (void *panel) {
10 no_xruns++;
11 return 0;
14 public abstract class JackpanelBase : Alignment {
15 // state
16 protected string client_name;
17 protected jack_client_t* client;
18 protected jack_status_t status;
19 protected string time_in_frames;
20 protected string time_in_bbt;
21 protected string time_h_min_sec;
22 protected Pid jackd_pid;
24 protected bool restart_jack () {
25 bool success = false;
26 stop_jack_client ();
27 stop_jack ();
28 return initialize_jack ();
31 protected bool start_jack_client () {
32 client = jack_client_open (client_name, jack_options_t.JackNoStartServer, ref status);
34 if (client == null) {
35 stderr.printf ("jack_client_open() failed, status = 0x%2.0x\n", status);
36 if ((status & jack_status_t.JackServerFailed) != 0) {
37 stderr.printf ("Unable to connect to JACK server\n");
39 return false;
40 } else {
41 return true;
45 protected void stop_jack_client () {
46 if (client != null) {
47 jack_deactivate (client);
48 jack_client_close (client);
49 client = null;
53 protected void stop_jack () {
54 if (jackd_pid != (GLib.Pid)0) {
55 Posix.kill (jackd_pid, Posix.SIGTERM);
56 jackd_pid = (GLib.Pid)0;
60 protected bool start_jack () {
61 string jackdrc_filename = Environment.get_home_dir () + Path.DIR_SEPARATOR_S + ".jackdrc";
62 string jackdrc;
63 if (FileUtils.test (jackdrc_filename, FileTest.EXISTS) &&
64 FileUtils.test (jackdrc_filename, FileTest.IS_REGULAR)) {
65 FileUtils.get_contents (jackdrc_filename, out jackdrc);
67 string [] argv;
68 Shell.parse_argv (jackdrc, out argv);
70 for (int i = 0; i < argv.length; i++) {
71 stdout.printf ("argument: %d: %s\n", i, argv[i]);
74 bool jack_started = Process.spawn_async (null, argv, null, 0, null, out jackd_pid);
76 ChildWatch.add (jackd_pid, (pid, status) => {
77 stdout.printf ("Process %d with status %d\n", (int)pid, (int)status);
78 });
80 if (!jack_started) {
81 return false;
82 } else {
83 return true;
87 return false;
90 protected bool initialize_jack () {
92 if (!start_jack_client ()) {
93 if (start_jack ()) {
94 Thread.usleep (2000000);
96 if (!start_jack_client ()) {
97 return false;
99 } else {
100 return false;
104 if ((status & jack_status_t.JackServerStarted) != 0) {
105 stderr.printf ("JACK server started\n");
107 if ((status & jack_status_t.JackNameNotUnique) != 0) {
108 client_name = jack_get_client_name(client);
109 stderr.printf ("unique name `%s' assigned\n", client_name);
112 no_xruns = 0;
113 jack_set_xrun_callback (client, jackpanel_xrun_callback, (void *)this);
115 if (jack_activate (client) != 0) {
116 stderr.printf ("cannot activate client");
117 return false;
120 return true;
123 protected abstract void on_transport_stopped ();
124 protected abstract void on_transport_rolling ();
126 protected void show_time (PanelDisplayBase display) {
127 jack_position_t current = jack_position_t ();
128 jack_transport_state_t transport_state;
129 jack_nframes_t frame_time;
131 transport_state = jack_transport_query (client, ref current);
132 frame_time = jack_frame_time (client);
134 var time_seconds = (int)current.frame / (int)current.frame_rate;
135 time_h_min_sec = "%02d:%02d:%02d".printf (time_seconds / 3600, (time_seconds % 3600) / 60, time_seconds % 60);
136 time_in_frames = "%u".printf ((jack_nframes_t)current.frame);
138 switch (transport_state) {
139 case jack_transport_state_t.JackTransportStopped:
140 on_transport_stopped ();
141 break;
142 case jack_transport_state_t.JackTransportRolling:
143 on_transport_rolling ();
144 break;
145 case jack_transport_state_t.JackTransportStarting:
146 //stdout.printf ("state: Starting");
147 break;
148 default:
149 stderr.printf ("jack transport state: [unknown]");
150 break;
153 if ((current.valid & jack_position_bits_t.JackPositionBBT) != 0) {
154 time_in_bbt = "%3u|%u|%04u".printf (current.bar, current.beat, current.tick);
155 display.time_alt = time_in_bbt;
156 } else {
157 display.time_alt = time_in_frames;
160 display.time = time_h_min_sec;
164 } //namespace Jackpanel