/[dino]/glashctl/jackwrapper.cpp
ViewVC logotype

Contents of /glashctl/jackwrapper.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.4 - (show annotations) (download)
Thu Jul 19 21:50:05 2007 UTC (17 years, 3 months ago) by larsl
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +1 -1 lines
Upgraded to GPL version 3 or later

1 /****************************************************************************
2 GLASHCtl - a simple tray applet for controlling lashd
3
4 Copyright (C) 2006 Lars Luthman <lars.luthman@gmail.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software Foundation,
18 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 ****************************************************************************/
20
21 #include <iostream>
22
23 #include <glibmm.h>
24
25 #include "jackwrapper.hpp"
26
27
28 using namespace std;
29 using namespace Glib;
30 using namespace sigc;
31
32
33 JACKWrapper::JACKWrapper(const std::string& client_name)
34 : m_client(0) {
35
36 if (m_client = jack_client_open(client_name.c_str(), JackNullOption, 0)) {
37 sem_init(&m_portreg_sem, 0, 0);
38 signal_timeout().connect(mem_fun(*this, &JACKWrapper::check_portreg), 100);
39 jack_set_port_registration_callback(m_client,
40 &JACKWrapper::port_registration_callback,
41 this);
42 jack_set_graph_order_callback(m_client,
43 &JACKWrapper::graph_order_callback, this);
44 jack_activate(m_client);
45
46 signal_timeout().connect(mem_fun(*this, &JACKWrapper::force_check), 4000);
47 }
48
49 }
50
51
52 JACKWrapper::~JACKWrapper() {
53 if (m_client) {
54 jack_deactivate(m_client);
55 jack_client_close(m_client);
56 sem_destroy(&m_portreg_sem);
57 }
58 }
59
60
61 void JACKWrapper::connect(const std::string& output, const std::string& input) {
62 if (m_client)
63 jack_connect(m_client, output.c_str(), input.c_str());
64 }
65
66
67 void JACKWrapper::disconnect(const std::string& output,
68 const std::string& input) {
69 if (m_client)
70 jack_disconnect(m_client, output.c_str(), input.c_str());
71 }
72
73
74 bool JACKWrapper::force_check() {
75 if (m_client)
76 sem_post(&m_portreg_sem);
77 return true;
78 }
79
80
81 void JACKWrapper::port_registration_callback(jack_port_id_t, int, void* arg) {
82 sem_post(&static_cast<JACKWrapper*>(arg)->m_portreg_sem);
83 }
84
85
86 int JACKWrapper::graph_order_callback(void* arg) {
87 sem_post(&static_cast<JACKWrapper*>(arg)->m_portreg_sem);
88 }
89
90
91 bool JACKWrapper::check_portreg() {
92 if (!sem_trywait(&m_portreg_sem)) {
93
94 const char** ports = jack_get_ports(m_client, 0, 0, 0);
95 if (ports) {
96
97 // check for new or removed ports
98
99 // mark all old ones as gone
100 map<string, PortInfo>::iterator iter;
101 for (iter = m_ports.begin(); iter != m_ports.end(); ++iter)
102 iter->second.flag = false;
103
104 // add new ports to our map and mark old ones as still here
105 for (int i = 0; ports[i]; ++i) {
106 jack_port_t* port = jack_port_by_name(m_client, ports[i]);
107 PortInfo* pi = 0;
108 if (m_ports.find(ports[i]) == m_ports.end()) {
109 if (port) {
110 m_ports[ports[i]].type = jack_port_type(port);
111 if (jack_port_flags(port) & JackPortIsInput) {
112 signal_input_added(ports[i], m_ports[ports[i]].type);
113 m_ports[ports[i]].is_input = true;
114 }
115 else {
116 signal_output_added(ports[i], m_ports[ports[i]].type);
117 m_ports[ports[i]].is_input = false;
118 }
119 }
120 }
121 pi = &m_ports[ports[i]];
122 pi->flag = true;
123 }
124
125 // remove unregistered ports from our map
126 for (iter = m_ports.begin(); iter != m_ports.end(); ) {
127 if (iter->second.flag == false) {
128 map<string, PortInfo>::iterator iter2 = iter;
129 ++iter;
130 if (iter2->second.is_input)
131 signal_input_removed(iter2->first);
132 else
133 signal_output_removed(iter2->first);
134 m_ports.erase(iter2);
135 }
136 else
137 ++iter;
138 }
139
140
141 free(ports);
142 }
143
144
145 // check for new or removed connections for all output ports
146
147 map<string, PortInfo>::iterator piter;
148 for (piter = m_ports.begin(); piter != m_ports.end(); ++piter) {
149 if (!piter->second.is_input) {
150
151 jack_port_t* port = jack_port_by_name(m_client, piter->first.c_str());
152 if (port) {
153
154 const char** connections = jack_port_get_all_connections(m_client,
155 port);
156 if (connections) {
157
158 // mark all connections as gone
159 map<string, bool>::iterator pciter;
160 for (pciter = piter->second.connections.begin();
161 pciter != piter->second.connections.end(); ++pciter)
162 pciter->second = false;
163
164 // find new connections and mark old ones that are still here
165 for (int c = 0; connections[c]; ++c) {
166 if (piter->second.connections.find(connections[c]) ==
167 piter->second.connections.end()) {
168 signal_connected(piter->first, connections[c]);
169 }
170 piter->second.connections[connections[c]] = true;
171 }
172
173 // remove all connections that are not here anymore
174 for (pciter = piter->second.connections.begin();
175 pciter != piter->second.connections.end(); ) {
176 if (pciter->second == false) {
177 map<string, bool>::iterator tmp = pciter;
178 ++pciter;
179 signal_disconnected(piter->first, tmp->first);
180 piter->second.connections.erase(tmp);
181 }
182 else
183 ++pciter;
184 }
185
186 free(connections);
187 }
188
189 // if there are no connections, clear all old ones
190 else {
191 map<string, bool>::iterator pciter;
192 for (pciter = piter->second.connections.begin();
193 pciter != piter->second.connections.end(); ++pciter)
194 signal_disconnected(piter->first, pciter->first);
195 piter->second.connections.clear();
196 }
197
198 }
199 }
200 }
201
202
203
204 }
205 }
206
207
208

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26