7 public static uint32 no_xruns
;
9 public static int jackpanel_xrun_callback (void *panel
) {
14 public abstract class JackpanelBase
: Alignment
{
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
;
26 config
= new
Configuration ();
27 if (!config
.exists ()) {
28 debug ("Config not valid, initializing empty\n");
31 config
.config_root
= "default";
35 protected bool restart_jack () {
38 return initialize_jack ();
41 protected bool start_jack_client () {
42 client
= jack_client_open (client_name
, jack_options_t
.JackNoStartServer
, ref status
);
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");
55 protected void stop_jack_client () {
57 jack_deactivate (client
);
58 jack_client_close (client
);
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 () {
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");
79 FileUtils
.get_contents (jackdrc_filename
, out jackdrc
);
80 config
.from_command_line (jackdrc
);
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
);
109 protected bool initialize_jack () {
111 if (!start_jack_client ()) {
113 Thread
.usleep (2000000);
115 if (!start_jack_client ()) {
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
);
132 jack_set_xrun_callback (client
, jackpanel_xrun_callback
, (void *)this
);
134 if (jack_activate (client
) != 0) {
135 error ("cannot activate client");
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 ();
161 case jack_transport_state_t
.JackTransportRolling
:
162 on_transport_rolling ();
164 case jack_transport_state_t
.JackTransportStarting
:
165 //debug ("state: Starting");
168 critical ("jack transport state: [unknown]");
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
;
176 display
.time_alt
= time_in_frames
;
179 display
.time
= time_h_min_sec
;
183 } //namespace Jackpanel