22 #include <jack/jack.h> 34 #define JACK_SERVER_NOT_FOUND_ERROR -10+JACK_ERROR_OFFSET 35 #define JACK_CLIENT_OPEN_ERROR -11+JACK_ERROR_OFFSET 36 #define JACK_SET_CALLBACK_ERROR -12+JACK_ERROR_OFFSET 37 #define JACK_INPUT_PORT_CREATION_ERROR -13+JACK_ERROR_OFFSET 38 #define JACK_OUTPUT_PORT_CREATION_ERROR -14+JACK_ERROR_OFFSET 39 #define JACK_ACTIVATE_ERROR -15+JACK_ERROR_OFFSET 40 #define JACK_HAS_NO_CAPTURE_PORTS_ERROR -16+JACK_ERROR_OFFSET 41 #define JACK_HAS_NO_PLAYBACK_PORTS_ERROR -17+JACK_ERROR_OFFSET 42 #define JACK_CLOSE_CLIENT_ERROR -18+JACK_ERROR_OFFSET 43 #define JACK_SET_BUFFER_SIZE_ERROR -19+JACK_ERROR_OFFSET 44 #define JACK_SET_BUFFSIZE_CALLBACK_ERROR -20+JACK_ERROR_OFFSET 45 #define JACK_DEACTIVATE_CLIENT_ERROR -21+JACK_ERROR_OFFSET 46 #define JACK_CLIENT_NULL_ERROR -22+JACK_ERROR_OFFSET 47 #define JACK_PORT_CALLBACK_SETUP_ERROR -23+JACK_ERROR_OFFSET 48 #define JACK_NOPORTS_ERROR -24+JACK_ERROR_OFFSET 49 #define JACK_PORT_CONNECT_ERROR -25+JACK_ERROR_OFFSET 50 #define JACK_PORTNAME_NOTFOUND_ERROR -26+JACK_ERROR_OFFSET 51 #define JACK_DRAG_OPTION_UNKNOWN_ERROR -27+JACK_ERROR_OFFSET 52 #define JACK_PORT_DISCONNECT_ERROR -28+JACK_ERROR_OFFSET 53 #define JACK_UNKNOWN_DND_TYPE_ERROR -29+JACK_ERROR_OFFSET 54 #define JACK_NETPORT_AUTOCONNECT_ERROR -30+JACK_ERROR_OFFSET 101 physicalInputPortCnt=physicalOutputPortCnt=0;
102 inputPorts.resize(0);
103 inputLatencies.resize(0);
104 outputPorts.resize(0);
105 outputLatencies.resize(0);
131 jack_latency_range_t range;
132 for (
unsigned int i=0; i < inputPorts.size(); i++) {
133 jack_port_get_latency_range(inputPorts[i], JackCaptureLatency, &range);
134 if (range.min != range.max) {
135 cout<<
"JackClient::determineLatencies : input : min = "<<range.min<<
" max = "<<range.max<<endl;
136 assert(
"don't know how to handle latencies which has a range which is different");
138 inputLatencies[i]=range.min;
139 cout<<
"input port "<<i<<
" latency = "<<inputLatencies[i]<<endl;
141 for (
unsigned int i=0; i < outputPorts.size(); i++) {
142 jack_port_get_latency_range(outputPorts[i], JackPlaybackLatency, &range);
143 if (range.min != range.max) {
144 cout<<
"JackClient::determineLatencies : output : min = "<<range.min<<
" max = "<<range.max<<endl;
145 assert(
"don't know how to handle latencies which has a range which is different");
147 outputLatencies[i]=range.min;
148 cout<<
"output port "<<i<<
" latency = "<<outputLatencies[i]<<endl;
159 int getPortListAndCount(JackPortFlags flags, vector<jack_port_t *> *ports,
const char *portNamePattern,
const char *typeNamePattern) {
162 const char **portsStrs = jack_get_ports(client, portNamePattern, typeNamePattern, flags);
163 for (cnt=0; portsStrs[cnt]!=NULL; cnt++)
165 ports->push_back(jack_port_by_name(client, portsStrs[cnt]));
179 int getPortListAndCount(JackPortFlags flags, vector<string> *ports,
const char *portNamePattern,
const char *typeNamePattern) {
182 const char **portsStrs = jack_get_ports(client, portNamePattern, typeNamePattern, flags);
184 for (cnt=0; portsStrs[cnt]!=NULL; cnt++)
186 ports->push_back(portsStrs[cnt]);
220 cout<<
"JackBase "<<clientName_<<endl;
222 int res=connect(clientName_);
226 cout<<
"JackBase connected"<<endl;
235 connect(clientName_, serverName);
246 if (jack_deactivate(client)!=0)
257 if (jack_client_close(client)!=0)
267 int fs=jack_get_sample_rate ( client );
277 virtual int createPorts(
string inName,
int inCnt,
string outName,
int outCnt) {
278 inputLatencies.resize(inCnt);
279 inputPorts.resize(inCnt);
280 for (
int i=0; i < inCnt; i++) {
281 ostringstream convert;
283 string portName=inName+convert.str();
284 inputPorts[i] = jack_port_register(client, portName.c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
285 if (inputPorts[i] == NULL)
289 outputLatencies.resize(outCnt);
290 outputPorts.resize(outCnt);
291 for (
int i=0; i < outCnt; i++) {
292 ostringstream convert;
294 string portName=outName+convert.str();
295 outputPorts[i] = jack_port_register(client, portName.c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
296 if (outputPorts[i] == NULL)
299 determineLatencies();
309 for (
int i=0; i<inputPorts.size(); i++){
311 jack_port_unregister(client, inputPorts[i]);
314 inputPorts.resize(0);
315 for (
int i=0; i<outputPorts.size(); i++){
317 jack_port_unregister(client, outputPorts[i]);
320 outputPorts.resize(0);
333 getPortListAndCount((JackPortFlags)(JackPortIsPhysical|JackPortIsInput), &inPorts, NULL, NULL);
335 getPortListAndCount((JackPortFlags)(JackPortIsPhysical|JackPortIsOutput), &outPorts, NULL, NULL);
348 in=getPortListAndCount((JackPortFlags)(JackPortIsPhysical|JackPortIsInput), (vector<jack_port_t *> *)NULL, NULL, NULL);
350 out=getPortListAndCount((JackPortFlags)(JackPortIsPhysical|JackPortIsOutput), (vector<jack_port_t *> *)NULL, NULL, NULL);
370 return connect(clientName_,
string());
379 virtual int connect(
const string &clientName_,
const string &serverName) {
380 clientName = clientName_;
387 jackOptions=JackNullOption;
388 if (serverName.length()>0) {
389 jackOptions=JackServerName;
390 client=jack_client_open(clientName.c_str(), jackOptions, &status, serverName.c_str());
392 client=jack_client_open(clientName.c_str(), jackOptions, &status);
394 cerr<<
"connect: jack_client_open() failed, status = 0x"<<hex<<status<<endl;
395 if ( status & JackServerFailed )
400 if (status & JackServerStarted)
401 cerr<<
"JACK server started"<<endl;
402 if ( status & JackNameNotUnique ) {
403 clientName = jack_get_client_name ( client );
404 cerr<<
"unique name '"<<clientName<<
"' assigned";
409 inputLatencies.resize(0);
410 outputLatencies.resize(0);
419 os<<
"JackBase : "<<inputPorts.size()<<
" input ports, "<<outputPorts.size()<<
" output ports.\n";
420 os<<
"Input ports : \t\t\t Output ports:\n";
421 for (
int i=0; i<max(inputPorts.size(), outputPorts.size()); i++) {
422 if (inputPorts.size()>i)
423 os<<
'\t'<<jack_port_name(inputPorts[i])<<
"\t\t";
426 if (outputPorts.size()>i)
427 os<<jack_port_name(outputPorts[i])<<
'\n';
453 return shortPortNameFromPortName(jack_port_name(jack_port_by_id(client, p)));
463 return shortPortNameFromPortName(jack_port_name(p));
472 return clientNameFromPort(jack_port_by_id(client, p));
482 return clientNameFromPortNames(jack_port_name(p), jack_port_short_name(p));
490 return fullPortName.substr(0, fullPortName.find(
':'));
499 fullPortName=fullPortName.substr(0, fullPortName.find(shortPortName)-1);
504 string res=fullPortName;
505 return res.substr(res.find(
":")+1, string::npos);
512 return clientName.find(cn)!=string::npos;
519 return inputPorts.size();
527 if (i<0 || i>inputPorts.size())
529 return inputPorts[i];
537 if (i<0 || i>outputPorts.size())
539 return outputPorts[i];
546 inputPorts.push_back(inP);
553 outputPorts.push_back(outP);
564 int populatInOutPorts(
const string &inName, vector<string> &inPorts,
const string &outName, vector<string> &outPorts) {
565 if (inName.find(
':')==string::npos)
566 getPortListAndCount((JackPortFlags)JackPortIsInput, &inPorts, inName.c_str(), NULL);
568 inPorts.push_back(inName);
569 if (outName.find(
':')==string::npos)
570 getPortListAndCount((JackPortFlags)JackPortIsOutput, &outPorts, outName.c_str(), NULL);
572 outPorts.push_back(outName);
575 if (inPorts.size()==0)
577 if (outPorts.size()==0)
597 vector<string> inPorts, outPorts;
598 if ((res=populatInOutPorts(inName, inPorts, outName, outPorts))!=
NO_ERROR)
602 vector<string>::iterator op=outPorts.begin();
603 for (vector<string>::iterator ip=inPorts.begin(); ip!=inPorts.end(); ++ip) {
604 for (; op!=outPorts.end(); ++op) {
605 if (!jack_port_connected_to(jack_port_by_name(client, (*op).c_str()), (*ip).c_str()))
606 if (jack_connect(client, (*op).c_str(), (*ip).c_str())<0)
613 if (connect1To1 && op==outPorts.end())
615 else if (!connect1To1)
630 cout<<
"JackBase::disconnectPorts : inName = "<<inName<<
" outName = "<<outName<<endl;
635 vector<string> inPorts, outPorts;
636 if ((res=populatInOutPorts(outName, outPorts, inName, inPorts))!=
NO_ERROR)
640 for (vector<string>::iterator ip=inPorts.begin(); ip!=inPorts.end(); ++ip)
641 for (vector<string>::iterator op=outPorts.begin(); op!=outPorts.end(); ++op)
642 if (jack_port_connected_to(jack_port_by_name(client, (*ip).c_str()), (*op).c_str()))
643 if (jack_disconnect(client, (*ip).c_str(), (*op).c_str())<0)
680 for (vector<jack_port_t *>::iterator
p=inputPorts.begin();
p!=inputPorts.end(); ++
p) {
681 const char**cons=jack_port_get_connections(*
p);
682 string thisPortName=jack_port_short_name(*
p);
683 inputPortNamesAndConnections[thisPortName]=map<string, vector<string> >();
686 for (
int i=0; cons[i]!=NULL; i++) {
687 string shortPN=shortPortNameFromPortName(cons[i]);
689 if (find(inputPortNamesAndConnections[thisPortName][clientNameFromPortNames(cons[i], shortPN)].begin(), inputPortNamesAndConnections[thisPortName][clientNameFromPortNames(cons[i], shortPN)].end(), shortPN)
690 == inputPortNamesAndConnections[thisPortName][clientNameFromPortNames(cons[i], shortPN)].end())
691 inputPortNamesAndConnections[thisPortName][clientNameFromPortNames(cons[i], shortPN)].push_back(shortPN);
699 #endif // JACKBASE_H_ int populatInOutPorts(const string &inName, vector< string > &inPorts, const string &outName, vector< string > &outPorts)
virtual ~JackBase()
Destructor.
#define JACK_PORT_CONNECT_ERROR
error when ports can't be connected
#define JACK_SERVER_NOT_FOUND_ERROR
The jack server wasn't found.
virtual void reSyncConnections(void)
virtual int createPorts(string inName, int inCnt, string outName, int outCnt)
int physicalOutputPortCnt
The number of physical input ports.
jack_port_t * getInputPort(int i)
#define JACK_UNKNOWN_DND_TYPE_ERROR
error when a GUI drop signals neither CONNECT_PORTS nor DISCONNECT_PORTS
virtual void determineLatencies()
JackBase(string clientName_, string serverName)
vector< string > outputPortNames
The output port names.
#define JACK_DEACTIVATE_CLIENT_ERROR
Couldn't deactivate the client.
string clientName
The name of this client.
virtual int disconnectPorts(const string &inName, const string &outName)
virtual int disconnect(void)
string clientNameFromPort(jack_port_id_t p)
string clientNameFromPort(jack_port_t *p)
#define JACK_CLIENT_NULL_ERROR
client is null
virtual int connect(string clientName_)
string clientNameFromPortName(string fullPortName)
#define JACK_PORT_DISCONNECT_ERROR
error when ports can't be connected
#define JACK_INPUT_PORT_CREATION_ERROR
The Client failed to register input ports.
int getPortListAndCount(JackPortFlags flags, vector< jack_port_t *> *ports, const char *portNamePattern, const char *typeNamePattern)
#define JACK_PORT_CALLBACK_SETUP_ERROR
error when trying to connect the port monitoring callbacks
virtual int evaluateError(int errorNum)
bool operator==(const string &cn)
jack_options_t jackOptions
Options for jack.
#define JACK_HAS_NO_CAPTURE_PORTS_ERROR
The server has no capture ports.
void getPhysicalPortCount(int &in, int &out)
#define JACK_SET_CALLBACK_ERROR
The Client failed to register its callback with the server.
vector< jack_nframes_t > outputLatencies
The output latencies, one for each port.
virtual void reSyncPorts(void)
string shortPortNameFromPortName(const string fullPortName)
#define NO_ERROR
There is no error.
jack_port_t * getOutputPort(int i)
#define JACK_CLIENT_OPEN_ERROR
The Client failed to start.
#define JACK_SET_BUFFER_SIZE_ERROR
Couldn't set the buffer size.
#define JACK_NOPORTS_ERROR
error when no ports are found matching a name
void addInputPort(jack_port_t *inP)
#define JACK_SET_BUFFSIZE_CALLBACK_ERROR
Couldn't set the buffer size callback.
#define JACK_NETPORT_AUTOCONNECT_ERROR
error when trying to connect network ports automatically.
#define JACK_PORTNAME_NOTFOUND_ERROR
error when the port name is not found
virtual int stopClient(void)
int getSampleRate(void) const
virtual int connect(const string &clientName_, const string &serverName)
jack_status_t status
The status of jack.
virtual void print(ostream &os)
vector< jack_nframes_t > inputLatencies
The input latencies, one for each port.
jack_client_t * client
The jack client.
string portNameFromPort(jack_port_id_t p)
#define JACK_HAS_NO_PLAYBACK_PORTS_ERROR
The server has no playback.
JackBase(string clientName_)
vector< jack_port_t * > inputPorts
The input ports.
bool connect1To1
When true, then connections are made in a 1 to 1 manner. When False, then connections are made in an ...
void getPhysicalPorts(vector< jack_port_t *> &inPorts, vector< jack_port_t *> &outPorts)
string clientNameFromPortNames(string fullPortName, string shortPortName)
void setClient(jack_client_t *c)
#define JACK_ACTIVATE_ERROR
Couldn't activate the client with the server.
int getPortListAndCount(JackPortFlags flags, vector< string > *ports, const char *portNamePattern, const char *typeNamePattern)
#define JACK_OUTPUT_PORT_CREATION_ERROR
The Client failed to register output ports.
virtual int destroyPorts()
void findInputConnections()
map< string, map< string, vector< string > > > inputPortNamesAndConnections
The input port names which map to a vector of the connected clients and each of their connected ports...
#define JACK_CLOSE_CLIENT_ERROR
Couldn't stop the client error.
#define JACK_DRAG_OPTION_UNKNOWN_ERROR
error when the the drag and drop drops to a widget which can't be found
vector< jack_port_t * > outputPorts
The output ports.
string portNameFromPort(jack_port_t *p)
int connectPorts(const string inName, const string outName)
virtual void setClientName(string cn)
void addOutputPort(jack_port_t *outP)
int physicalInputPortCnt
The number of physical input ports.