* stderr.printf -> debug etc
[jackpanel.git] / jackpanel / JackpanelBase.vala
blobe548efd15cc5cc51810e1cf9d797af441e658b50
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 Configuration config;
17 protected string client_name;
18 protected jack_client_t* client;
19 protected jack_status_t status;
20 protected string time_in_frames;
21 protected string time_in_bbt;
22 protected string time_h_min_sec;
23 protected Pid jackd_pid;
25 construct {
26 config = new Configuration ();
27 if (!config.exists ()) {
28 debug ("Config not valid, initializing empty\n");
29 config.init ();
30 } else {
31 config.config_root = "default";
35 protected bool restart_jack () {
36 stop_jack_client ();
37 stop_jack ();
38 return initialize_jack ();
41 protected bool start_jack_client () {
42 client = jack_client_open (client_name, jack_options_t.JackNoStartServer, ref status);
44 if (client == null) {
45 critical ("jack_client_open() failed, status = 0x%2.0x\n", status);
46 if ((status & jack_status_t.JackServerFailed) != 0) {
47 critical ("Unable to connect to JACK server\n");
49 return false;
50 } else {
51 return true;
55 protected void stop_jack_client () {
56 if (client != null) {
57 jack_deactivate (client);
58 jack_client_close (client);
59 client = null;
63 protected void stop_jack () {
64 if (jackd_pid != (GLib.Pid)0) {
65 Posix.kill ((Posix.pid_t)jackd_pid, Posix.SIGTERM);
66 jackd_pid = (GLib.Pid)0;
70 protected bool start_jack () {
71 string cmdline;
73 if (!config.exists ()) {
74 string jackdrc_filename = Environment.get_home_dir () + Path.DIR_SEPARATOR_S + ".jackdrc";
75 if (FileUtils.test (jackdrc_filename, FileTest.EXISTS) &&
76 FileUtils.test (jackdrc_filename, FileTest.IS_REGULAR)) {
77 message ("importing settings from ~/.jackdrc\n");
78 string jackdrc;
79 FileUtils.get_contents (jackdrc_filename, out jackdrc);
80 config.from_command_line (jackdrc);
84 string [] argv;
85 cmdline = config.to_command_line();
86 debug ("Starting jack with command line: %s\n", cmdline);
87 Shell.parse_argv (cmdline, out argv);
89 for (int i = 0; i < argv.length; i++) {
90 debug ("argument: %d: %s\n", i, argv[i]);
93 bool jack_started = Process.spawn_async (null, argv, null, 0, null, out jackd_pid);
95 ChildWatch.add (jackd_pid, (pid, status) => {
96 debug ("Process %d with status %d\n", (int)pid, (int)status);
97 });
99 if (!jack_started) {
100 return false;
101 } else {
102 return true;
106 return false;
109 protected bool initialize_jack () {
111 if (!start_jack_client ()) {
112 if (start_jack ()) {
113 Thread.usleep (2000000);
115 if (!start_jack_client ()) {
116 return false;
118 } else {
119 return false;
123 if ((status & jack_status_t.JackServerStarted) != 0) {
124 debug ("JACK server started\n");
126 if ((status & jack_status_t.JackNameNotUnique) != 0) {
127 client_name = jack_get_client_name(client);
128 debug ("unique name `%s' assigned\n", client_name);
131 no_xruns = 0;
132 jack_set_xrun_callback (client, jackpanel_xrun_callback, (void *)this);
134 if (jack_activate (client) != 0) {
135 error ("cannot activate client");
136 return false;
139 return true;
142 protected abstract void on_transport_stopped ();
143 protected abstract void on_transport_rolling ();
145 protected void show_time (PanelDisplayBase display) {
146 jack_position_t current = jack_position_t ();
147 jack_transport_state_t transport_state;
148 jack_nframes_t frame_time;
150 transport_state = jack_transport_query (client, ref current);
151 frame_time = jack_frame_time (client);
153 uint32 time_seconds = (uint32)current.frame / (uint32)current.frame_rate;
154 time_h_min_sec = "%02u:%02u:%02u".printf (time_seconds / 3600, (time_seconds % 3600) / 60, time_seconds % 60);
155 time_in_frames = "%u".printf ((jack_nframes_t)current.frame);
157 switch (transport_state) {
158 case jack_transport_state_t.JackTransportStopped:
159 on_transport_stopped ();
160 break;
161 case jack_transport_state_t.JackTransportRolling:
162 on_transport_rolling ();
163 break;
164 case jack_transport_state_t.JackTransportStarting:
165 //debug ("state: Starting");
166 break;
167 default:
168 critical ("jack transport state: [unknown]");
169 break;
172 if ((current.valid & jack_position_bits_t.JackPositionBBT) != 0) {
173 time_in_bbt = "%3u|%u|%04u".printf (current.bar, current.beat, current.tick);
174 display.time_alt = time_in_bbt;
175 } else {
176 display.time_alt = time_in_frames;
179 display.time = time_h_min_sec;
183 } //namespace Jackpanel