@@ -58,12 +58,14 @@ bool JackClient::Attach() | |||
cerr<<"Attach"<<endl; | |||
if (!(m_Client = jack_client_new("SSMJackPlugin"))) | |||
if (!(m_Client = jack_client_new("SSM"))) | |||
{ | |||
cerr<<"jack server not running?"<<endl; | |||
return false; | |||
} | |||
cerr<<"Register"<<endl; | |||
jack_set_process_callback(m_Client, JackClient::Process, 0); | |||
jack_set_buffer_size_callback(m_Client, JackClient::OnBufSizeChange, 0); | |||
jack_set_sample_rate_callback (m_Client, JackClient::OnSRateChange, 0); | |||
@@ -110,6 +112,9 @@ bool JackClient::Attach() | |||
cerr<<"connected to jack..."<<endl; | |||
ConnectOutput(0,"alsa_pcm:out_1"); | |||
ConnectOutput(1,"alsa_pcm:out_2"); | |||
return true; | |||
} | |||
@@ -131,19 +136,16 @@ void JackClient::Detach() | |||
///////////////////////////////////////////////////////////////////////////////////////////// | |||
int JackClient::Process(long unsigned int n, void *o) | |||
{ | |||
//cerr<<"process called "<<n<<endl; | |||
int JackClient::Process(jack_nframes_t nframes, void *o) | |||
{ | |||
for (int n=0; n<NUM_INPUTS; n++) | |||
{ | |||
if (m_InputPortMap[n]->Connected) | |||
{ | |||
if (m_InputPortMap[n]->Buf) | |||
{ | |||
sample_t *in = (sample_t *) jack_port_get_buffer(m_InputPortMap[n]->Port, m_BufferSize); | |||
sample_t *in = (sample_t *) jack_port_get_buffer(m_InputPortMap[n]->Port, nframes); | |||
memcpy (m_InputPortMap[n]->Buf, in, sizeof (sample_t) * m_BufferSize); | |||
//cerr<<"got "<<m_InputPortMap[n]->Buf[0]<<" from "<<m_InputPortMap[n]->Name<<endl; | |||
} | |||
} | |||
@@ -155,12 +157,12 @@ int JackClient::Process(long unsigned int n, void *o) | |||
{ | |||
if (m_OutputPortMap[n]->Buf) | |||
{ | |||
sample_t *out = (sample_t *) jack_port_get_buffer(m_OutputPortMap[n]->Port, m_BufferSize); | |||
sample_t *out = (sample_t *) jack_port_get_buffer(m_OutputPortMap[n]->Port, nframes); | |||
memcpy (out, m_OutputPortMap[n]->Buf, sizeof (sample_t) * m_BufferSize); | |||
} | |||
else // no output availible, clear | |||
{ | |||
sample_t *out = (sample_t *) jack_port_get_buffer(m_OutputPortMap[n]->Port, m_BufferSize); | |||
sample_t *out = (sample_t *) jack_port_get_buffer(m_OutputPortMap[n]->Port, nframes); | |||
memset (out, 0, sizeof (sample_t) * m_BufferSize); | |||
} | |||
} | |||
@@ -173,7 +175,7 @@ int JackClient::Process(long unsigned int n, void *o) | |||
RunCallback(RunContext, true); | |||
} | |||
return 1; | |||
return 0; | |||
} | |||
///////////////////////////////////////////////////////////////////////////////////////////// | |||
@@ -181,7 +183,7 @@ int JackClient::Process(long unsigned int n, void *o) | |||
int JackClient::OnBufSizeChange(long unsigned int n, void *o) | |||
{ | |||
m_BufferSize=n; | |||
return 1; | |||
return 0; | |||
} | |||
///////////////////////////////////////////////////////////////////////////////////////////// | |||
@@ -189,7 +191,7 @@ int JackClient::OnBufSizeChange(long unsigned int n, void *o) | |||
int JackClient::OnSRateChange(long unsigned int n, void *o) | |||
{ | |||
m_SampleRate=n; | |||
return 1; | |||
return 0; | |||
} | |||
///////////////////////////////////////////////////////////////////////////////////////////// | |||
@@ -238,7 +240,7 @@ void JackClient::GetPortNames(vector<string> &InputNames, vector<string> &Output | |||
} | |||
///////////////////////////////////////////////////////////////////////////////////////////// | |||
// Input means input of SSM, so this connects jack sources to the plugin outputs | |||
void JackClient::ConnectInput(int n, const string &JackPort) | |||
{ | |||
cerr<<"JackClient::ConnectInput: connecting source ["<<JackPort<<"] to dest ["<<m_InputPortMap[n]->Name<<"]"<<endl; | |||
@@ -251,7 +253,7 @@ void JackClient::ConnectInput(int n, const string &JackPort) | |||
} | |||
m_InputPortMap[n]->ConnectedTo = JackPort; | |||
if (jack_connect (m_Client, JackPort.c_str(), jack_port_name(m_InputPortMap[n]->Port))) | |||
cerr<<"JackClient::ConnectInput: cannot connect input port [" | |||
<<JackPort<<"] to ["<<m_InputPortMap[n]->Name<<"]"<<endl; | |||
@@ -260,7 +262,7 @@ void JackClient::ConnectInput(int n, const string &JackPort) | |||
} | |||
///////////////////////////////////////////////////////////////////////////////////////////// | |||
// Output means output of SSM, so this connects plugin inputs to a jack destination | |||
void JackClient::ConnectOutput(int n, const string &JackPort) | |||
{ | |||
cerr<<"JackClient::ConnectOutput: connecting source ["<<m_OutputPortMap[n]->Name<<"] to dest ["<<JackPort<<"]"<<endl; | |||
@@ -318,7 +320,8 @@ int GetID() | |||
/////////////////////////////////////////////////////// | |||
JackPlugin::JackPlugin() : | |||
m_UpdateNames(false) | |||
m_UpdateNames(false), | |||
m_Connected(false) | |||
{ | |||
m_RefCount++; | |||
@@ -342,8 +345,8 @@ m_UpdateNames(false) | |||
m_PluginInfo.PortTips.push_back(Temp); | |||
} | |||
m_AudioCH->Register("Num",&GUIArgs.Num); | |||
m_AudioCH->RegisterData("Port",ChannelHandler::INPUT,&GUIArgs.Port,sizeof(GUIArgs.Port)); | |||
m_AudioCH->Register("Num",&m_GUIArgs.Num); | |||
m_AudioCH->RegisterData("Port",ChannelHandler::INPUT,&m_GUIArgs.Port,sizeof(m_GUIArgs.Port)); | |||
m_AudioCH->Register("NumInputPortNames",&m_NumInputPortNames,ChannelHandler::OUTPUT); | |||
m_AudioCH->Register("NumOutputPortNames",&m_NumOutputPortNames,ChannelHandler::OUTPUT); | |||
m_AudioCH->RegisterData("InputPortNames",ChannelHandler::OUTPUT,&m_InputPortNames,sizeof(m_InputPortNames)); | |||
@@ -381,15 +384,19 @@ SpiralGUIType *JackPlugin::CreateGUI() | |||
void JackPlugin::Execute() | |||
{ | |||
} | |||
void JackPlugin::ExecuteCommands() | |||
{ | |||
// we want to process this whether we are connected to stuff or not | |||
for (int n=0; n<NUM_OUTPUTS; n++) | |||
{ | |||
GetOutputBuf(n)->Zero(); | |||
} | |||
JackClient* pJack=JackClient::Get(); | |||
((JackPluginGUI*)m_GUI)->SetAttached(pJack->IsAttached()); | |||
// connect the buffers up if we are plugged into something | |||
for (int n=0; n<NUM_OUTPUTS; n++) | |||
{ | |||
@@ -397,7 +404,10 @@ void JackPlugin::Execute() | |||
{ | |||
JackClient::Get()->SetOutputBuf(n,(float*)GetInput(n)->GetBuffer()); | |||
} | |||
else JackClient::Get()->SetOutputBuf(n,NULL); | |||
else | |||
{ | |||
JackClient::Get()->SetOutputBuf(n,NULL); | |||
} | |||
} | |||
// don't really want to do this all the time, as it only needs to | |||
@@ -407,29 +417,41 @@ void JackPlugin::Execute() | |||
pJack->SetInputBuf(n,(float*)GetOutputBuf(n)->GetBuffer()); | |||
} | |||
} | |||
void JackPlugin::ExecuteCommands() | |||
{ | |||
if (m_UpdateNames) | |||
if (m_AudioCH->IsCommandWaiting()) | |||
{ | |||
vector<string> InputNames,OutputNames; | |||
GetPortNames(InputNames,OutputNames); | |||
for (vector<string>::iterator i=InputNames.begin(); | |||
i!=InputNames.end(); ++i) | |||
switch (m_AudioCH->GetCommand()) | |||
{ | |||
strcpy(m_InputPortNames[n],i->c_str()); | |||
} | |||
case ATTACH : Attach(); break; | |||
case DETACH : Detach(); break; | |||
case CONNECTINPUT : ConnectInput(m_GUIArgs.Num,m_GUIArgs.Port); break; | |||
case CONNECTOUTPUT : ConnectOutput(m_GUIArgs.Num,m_GUIArgs.Port); break; | |||
case UPDATE_NAMES : | |||
{ | |||
int c=0; | |||
vector<string> InputNames,OutputNames; | |||
GetPortNames(InputNames,OutputNames); | |||
for (vector<string>::iterator i=InputNames.begin(); | |||
i!=InputNames.end(); ++i) | |||
{ | |||
strcpy(m_InputPortNames[c],i->c_str()); | |||
c++; | |||
} | |||
for (vector<string>::iterator i=OutputNames.begin(); | |||
i!=OutputNames.end(); ++i) | |||
{ | |||
strcpy(m_OutputPortNames[n],i->c_str()); | |||
} | |||
c=0; | |||
m_NumInputPortNames=InputNames.size(); | |||
m_NumOutputPortNames=OutputNames.size(); | |||
for (vector<string>::iterator i=OutputNames.begin(); | |||
i!=OutputNames.end(); ++i) | |||
{ | |||
strcpy(m_OutputPortNames[c],i->c_str()); | |||
c++; | |||
} | |||
m_UpdateNames=false; | |||
m_NumInputPortNames=InputNames.size(); | |||
m_NumOutputPortNames=OutputNames.size(); | |||
} | |||
break; | |||
} | |||
} | |||
m_Connected=JackClient::Get()->IsAttached(); | |||
} |
@@ -55,7 +55,7 @@ protected: | |||
JackClient(); | |||
~JackClient(); | |||
static int Process(long unsigned int n, void *o); | |||
static int Process(jack_nframes_t nframes, void *o); | |||
static int OnBufSizeChange(long unsigned int n, void *o); | |||
static int OnSRateChange(long unsigned int n, void *o); | |||
static void OnJackShutdown(void *o); | |||
@@ -98,10 +98,11 @@ public: | |||
virtual PluginInfo& Initialise(const HostInfo *Host); | |||
virtual SpiralGUIType* CreateGUI(); | |||
virtual void Execute(); | |||
virtual void ExecuteCommands(); | |||
virtual void StreamOut(ostream &s) {} | |||
virtual void StreamIn(istream &s) {} | |||
enum GUICommands{NONE,ATTACH,DETACH,CONNECTINPUT,CONNECTOUTPUT}; | |||
enum GUICommands{NONE,ATTACH,DETACH,CONNECTINPUT,CONNECTOUTPUT,UPDATE_NAMES}; | |||
struct GUIArgs | |||
{ | |||
int Num; | |||
@@ -80,7 +80,6 @@ SpiralPluginGUI(w,h,o,ch) | |||
{ | |||
for (int n=0; n<255; n++) Numbers[n]=n; | |||
m_Plugin=o; | |||
m_Indicator = new Fl_LED_Button(85,17,30,30,""); | |||
m_Indicator->value(0); | |||
m_Indicator->color(FL_RED); | |||
@@ -96,17 +95,6 @@ SpiralPluginGUI(w,h,o,ch) | |||
m_Detach->callback((Fl_Callback*)cb_Detach); | |||
int yoff=90; | |||
for (int n=0; n<NUM_INPUTS; n++) | |||
{ | |||
sprintf(m_InputName[n],"Input %d",n); | |||
m_InputLabel[n] = new Fl_Box(100,n*40+yoff,95,20,m_InputName[n]); | |||
m_InputLabel[n]->labelsize(10); | |||
m_InputLabel[n]->labeltype(FL_ENGRAVED_LABEL); | |||
m_InputButton[n] = new Fl_Button(100,n*40+yoff+20,95,20,"None yet"); | |||
m_InputButton[n]->labelsize(10); | |||
m_InputButton[n]->callback((Fl_Callback*)cb_InputConnect,&Numbers[n]); | |||
} | |||
for (int n=0; n<NUM_OUTPUTS; n++) | |||
{ | |||
@@ -118,6 +106,17 @@ SpiralPluginGUI(w,h,o,ch) | |||
m_OutputButton[n]->labelsize(10); | |||
m_OutputButton[n]->callback((Fl_Callback*)cb_OutputConnect,&Numbers[n]); | |||
} | |||
for (int n=0; n<NUM_INPUTS; n++) | |||
{ | |||
sprintf(m_InputName[n],"Input %d",n); | |||
m_InputLabel[n] = new Fl_Box(100,n*40+yoff,95,20,m_InputName[n]); | |||
m_InputLabel[n]->labelsize(10); | |||
m_InputLabel[n]->labeltype(FL_ENGRAVED_LABEL); | |||
m_InputButton[n] = new Fl_Button(100,n*40+yoff+20,95,20,"None yet"); | |||
m_InputButton[n]->labelsize(10); | |||
m_InputButton[n]->callback((Fl_Callback*)cb_InputConnect,&Numbers[n]); | |||
} | |||
end(); | |||
} | |||
@@ -126,53 +125,49 @@ void JackPluginGUI::UpdateValues(SpiralPlugin *o) | |||
{ | |||
} | |||
void JackPluginGUI::draw() | |||
{ | |||
SpiralPluginGUI::draw(); | |||
m_Indicator->value(m_GUICH->GetBool("Connected")); | |||
}; | |||
//// Callbacks //// | |||
inline void JackPluginGUI::cb_Attach_i(Fl_Button* o, void* v) | |||
{ | |||
m_Plugin->Attach(); | |||
m_GUICH->SetCommand(JackPlugin::ATTACH); | |||
} | |||
void JackPluginGUI::cb_Attach(Fl_Button* o, void* v) | |||
{ ((JackPluginGUI*)(o->parent()))->cb_Attach_i(o,v);} | |||
inline void JackPluginGUI::cb_Detach_i(Fl_Button* o, void* v) | |||
{ | |||
m_Plugin->Detach(); | |||
m_GUICH->SetCommand(JackPlugin::DETACH); | |||
} | |||
void JackPluginGUI::cb_Detach(Fl_Button* o, void* v) | |||
{ ((JackPluginGUI*)(o->parent()))->cb_Detach_i(o,v);} | |||
inline void JackPluginGUI::cb_OutputConnect_i(Fl_Button* o, void* v) | |||
{ | |||
cerr<<"cb_OutputConnect_i"<<endl; | |||
vector<string> Inputs,Outputs; | |||
m_GUICH->Set("UpdateNames",true); | |||
m_GUICH->SetCommand(JackPlugin::UPDATE_NAMES); | |||
m_GUICH->Wait(); | |||
// bit of a hack for multithreaded safety | |||
int ninputs=m_GUICH->GetInt("NumOutputPortNames"), | |||
int noutputs=m_GUICH->GetInt("NumOutputPortNames"); | |||
char **inputs = new char[MAX_INPUTPORTS][256]; | |||
char **outputs = new char[MAX_OUTPUTPORTS][256];; | |||
for (int n=0 n<m_GUICH->GetInt("NumInputPortNames"); n++) | |||
{ | |||
Inputs.push_back(inputs[n]); | |||
} | |||
for (int n=0 n<m_GUICH->GetInt("NumOutputPortNames"); n++) | |||
{ | |||
Inputs.push_back(outputs[n]); | |||
} | |||
delete[] inputs; | |||
delete[] outputs; | |||
// connect this plugin's output to a jack input | |||
int ninputs=m_GUICH->GetInt("NumOutputPortNames"); | |||
char inputs[MAX_INPUTPORTS][256]; | |||
m_GUICH->GetData("InputPortNames",inputs); | |||
vector<string> Inputs; | |||
for (int n=0; n<ninputs; n++) Inputs.push_back(inputs[n]); | |||
int choice=OptionsList(Inputs); | |||
// connect this plugin's output to a jack input | |||
if (choice>0) | |||
{ | |||
m_Plugin->ConnectOutput(*(int*)v,Inputs[choice-1]); | |||
o->label(Inputs[choice-1].c_str()); | |||
m_GUICH->Set("Num",(*(int*)v)); | |||
m_GUICH->SetData("Port",inputs[choice-1]); | |||
m_GUICH->SetCommand(JackPlugin::CONNECTOUTPUT); | |||
o->label(inputs[choice-1]); | |||
o->redraw(); | |||
} | |||
} | |||
@@ -181,16 +176,25 @@ void JackPluginGUI::cb_OutputConnect(Fl_Button* o, void* v) | |||
inline void JackPluginGUI::cb_InputConnect_i(Fl_Button* o, void* v) | |||
{ | |||
cerr<<"cb_InputConnect_i"<<endl; | |||
vector<string> Inputs,Outputs; | |||
m_Plugin->GetPortNames(Inputs,Outputs); | |||
m_GUICH->SetCommand(JackPlugin::UPDATE_NAMES); | |||
m_GUICH->Wait(); | |||
// connect this plugin's input to a jack output | |||
// bit of a hack for multithreaded safety | |||
int noutputs=m_GUICH->GetInt("NumOutputPortNames"); | |||
char outputs[MAX_OUTPUTPORTS][256]; | |||
m_GUICH->GetData("OutputPortNames",outputs); | |||
vector<string> Outputs; | |||
for (int n=0; n<noutputs; n++) Outputs.push_back(outputs[n]); | |||
int choice=OptionsList(Outputs); | |||
// connect this plugin's input to a jack output | |||
if (choice>0) | |||
{ | |||
m_Plugin->ConnectInput(*(int*)v,Outputs[choice-1]); | |||
o->label(Outputs[choice-1].c_str()); | |||
m_GUICH->Set("Num",(*(int*)v)); | |||
m_GUICH->SetData("Port",outputs[choice-1]); | |||
m_GUICH->SetCommand(JackPlugin::CONNECTINPUT); | |||
o->label(outputs[choice-1]); | |||
o->redraw(); | |||
} | |||
} | |||
@@ -38,7 +38,7 @@ public: | |||
JackPluginGUI(int w, int h, JackPlugin *o,ChannelHandler *ch,const HostInfo *Info); | |||
virtual void UpdateValues(SpiralPlugin *o); | |||
virtual void draw() { m_Indicator->value(m_GUICH->GetBool("Connected"); }; | |||
virtual void draw(); | |||
private: | |||
@@ -65,7 +65,7 @@ SOURCES = ../SpiralPlugin.C \ | |||
JackPluginGUI.C | |||
OBJECTS = ../SpiralPlugin.o \ | |||
../SpiralPluginGUI.o \ | |||
../ChannelHandler.o \ | |||
../../ChannelHandler.o \ | |||
../Widgets/Fl_Knob.o \ | |||
../Widgets/Fl_DragBar.o \ | |||
../Widgets/Fl_LED_Button.o \ | |||
@@ -1,367 +0,0 @@ | |||
/* | |||
Copyright (C) 2001 Paul Davis | |||
This program is free software; you can redistribute it and/or modify | |||
it under the terms of the GNU Lesser General Public License as published by | |||
the Free Software Foundation; either version 2.1 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU Lesser General Public License for more details. | |||
You should have received a copy of the GNU Lesser General Public License | |||
along with this program; if not, write to the Free Software | |||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
$Id: jack.h,v 1.1 2002-07-28 23:18:15 nebogeo Exp $ | |||
*/ | |||
#ifndef __jack_h__ | |||
#define __jack_h__ | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
#include <jack/types.h> | |||
#include <jack/error.h> | |||
jack_client_t *jack_client_new (const char *client_name); | |||
int jack_client_close (jack_client_t *client); | |||
/* register a function (and argument) to be called if and when the | |||
JACK server shuts down the client thread. the function must | |||
be written as if it were an asynchonrous POSIX signal | |||
handler - use only async-safe functions, and remember that it | |||
is executed from another thread. a typical function might | |||
set a flag or write to a pipe so that the rest of the | |||
application knows that the JACK client thread has shut | |||
down. | |||
NOTE: clients do not need to call this. it exists only | |||
to help more complex clients understand what is going | |||
on. if called, it must be called before jack_client_activate(). | |||
*/ | |||
void jack_on_shutdown (jack_client_t *, void (*function)(void *arg), void *arg); | |||
/* see simple_client.c to understand what these do. | |||
*/ | |||
int jack_set_process_callback (jack_client_t *, JackProcessCallback, void *arg); | |||
int jack_set_buffer_size_callback (jack_client_t *, JackBufferSizeCallback, void *arg); | |||
int jack_set_sample_rate_callback (jack_client_t *, JackSampleRateCallback, void *arg); | |||
int jack_set_port_registration_callback (jack_client_t *, JackPortRegistrationCallback, void *); | |||
int jack_activate (jack_client_t *client); | |||
int jack_deactivate (jack_client_t *client); | |||
/* this creates a new port for the client. | |||
a port is an object used for moving data in or out of the client. | |||
the data may be of any type. ports may be connected to each other | |||
in various ways. | |||
a port has a short name, which may be any non-NULL and non-zero | |||
length string, and is passed as the first argument. a port's full | |||
name is the name of the client concatenated with a colon (:) and | |||
then its short name. | |||
a port has a type, which may be any non-NULL and non-zero length | |||
string, and is passed as the second argument. for types that are | |||
not built into the jack API (currently just | |||
JACK_DEFAULT_AUDIO_TYPE) the client MUST supply a non-zero size | |||
for the buffer as the fourth argument. for builtin types, the | |||
fourth argument is ignored. | |||
a port has a set of flags, enumerated below and passed as the third | |||
argument in the form of a bitmask created by AND-ing together the | |||
desired flags. the flags "IsInput" and "IsOutput" are mutually | |||
exclusive and it is an error to use them both. | |||
*/ | |||
enum JackPortFlags { | |||
JackPortIsInput = 0x1, | |||
JackPortIsOutput = 0x2, | |||
JackPortIsPhysical = 0x4, /* refers to a physical connection */ | |||
/* if JackPortCanMonitor is set, then a call to | |||
jack_port_request_monitor() makes sense. | |||
Precisely what this means is dependent on the client. A typical | |||
result of it being called with TRUE as the second argument is | |||
that data that would be available from an output port (with | |||
JackPortIsPhysical set) is sent to a physical output connector | |||
as well, so that it can be heard/seen/whatever. | |||
Clients that do not control physical interfaces | |||
should never create ports with this bit set. | |||
*/ | |||
JackPortCanMonitor = 0x8, | |||
/* JackPortIsTerminal means: | |||
for an input port: the data received by the port | |||
will not be passed on or made | |||
available at any other port | |||
for an output port: the data available at the port | |||
does not originate from any | |||
other port | |||
Audio synthesizers, i/o h/w interface clients, HDR | |||
systems are examples of things that would set this | |||
flag for their ports. | |||
*/ | |||
JackPortIsTerminal = 0x10 | |||
}; | |||
#define JACK_DEFAULT_AUDIO_TYPE "32 bit float mono audio" | |||
jack_port_t * | |||
jack_port_register (jack_client_t *, | |||
const char *port_name, | |||
const char *port_type, | |||
unsigned long flags, | |||
unsigned long buffer_size); | |||
/* this removes the port from the client, disconnecting | |||
any existing connections at the same time. | |||
*/ | |||
int jack_port_unregister (jack_client_t *, jack_port_t *); | |||
/* a port is an opaque type. these help with a few things */ | |||
const char * jack_port_name (const jack_port_t *port); | |||
const char * jack_port_short_name (const jack_port_t *port); | |||
int jack_port_flags (const jack_port_t *port); | |||
const char * jack_port_type (const jack_port_t *port); | |||
/* this returns TRUE or FALSE to indicate if there are | |||
any connections to/from the port argument. | |||
*/ | |||
int jack_port_connected (const jack_port_t *port); | |||
/* this returns TRUE or FALSE if the port argument is | |||
DIRECTLY connected to the port with the name given in | |||
`portname' | |||
*/ | |||
int jack_port_connected_to (const jack_port_t *port, const char *portname); | |||
int jack_port_connected_to_port (const jack_port_t *port, const jack_port_t *other_port); | |||
/* this returns a null-terminated array of port names to | |||
which the argument port is connected. if there are no | |||
connections, it returns NULL. | |||
the caller is responsible for calling free(3) on any | |||
non-NULL returned value. | |||
*/ | |||
const char ** jack_port_get_connections (const jack_port_t *port); | |||
/* this modifies a port's name, and may be called at any | |||
time. | |||
*/ | |||
int jack_port_set_name (jack_port_t *port, const char *name); | |||
/* This returns a pointer to the memory area associated with the | |||
specified port. It can only be called from within the client's | |||
"process" callback. For an output port, it will be a memory area | |||
that can be written to; for an input port, it will be an area | |||
containing the data from the port's connection(s), or | |||
zero-filled. if there are multiple inbound connections, the data | |||
will be mixed appropriately. | |||
You may not cache the values returned across process() callbacks. | |||
There is no guarantee that the values will not change from | |||
process() callback to process() callback. | |||
*/ | |||
void *jack_port_get_buffer (jack_port_t *, nframes_t); | |||
/* these two functions establish and disestablish a connection | |||
between two ports. when a connection exists, data written | |||
to the source port will be available to be read at the destination | |||
port. | |||
the types of both ports must be identical to establish a connection. | |||
the flags of the source port must include PortIsOutput. | |||
the flags of the destination port must include PortIsInput. | |||
*/ | |||
int jack_connect (jack_client_t *, | |||
const char *source_port, | |||
const char *destination_port); | |||
int jack_disconnect (jack_client_t *, | |||
const char *source_port, | |||
const char *destination_port); | |||
/* these two functions perform the exact same function | |||
as the jack_connect() and jack_disconnect(), but they | |||
use port handles rather than names, which avoids | |||
the name lookup inherent in the name-based versions. | |||
it is envisaged that clients (dis)connecting their own | |||
ports will use these two, wherease generic connection | |||
clients (e.g. patchbays) will use the name-based | |||
versions | |||
*/ | |||
int jack_port_connect (jack_client_t *, jack_port_t *src, jack_port_t *dst); | |||
int jack_port_disconnect (jack_client_t *, jack_port_t *); | |||
/* A client may call this on a pair of its own ports to | |||
semi-permanently wire them together. This means that | |||
a client that wants to direct-wire an input port to | |||
an output port can call this and then no longer | |||
have to worry about moving data between them. Any data | |||
arriving at the input port will appear automatically | |||
at the output port. | |||
The `destination' port must be an output port. The `source' | |||
port must be an input port. Both ports must belong to | |||
the same client. You cannot use this to tie ports between | |||
clients. Thats what a connection is for. | |||
*/ | |||
int jack_port_tie (jack_port_t *src, jack_port_t *dst); | |||
/* This undoes the effect of jack_port_tie(). The port | |||
should be same as the `destination' port passed to | |||
jack_port_tie(). | |||
*/ | |||
int jack_port_untie (jack_port_t *port); | |||
/* a client may call this function to prevent other objects | |||
from changing the connection status of a port. the port | |||
must be owned by the calling client. | |||
*/ | |||
int jack_port_lock (jack_client_t *, jack_port_t *); | |||
int jack_port_unlock (jack_client_t *, jack_port_t *); | |||
/* returns the time (in frames) between data being available | |||
or delivered at/to a port, and the time at which it | |||
arrived at or is delivered to the "other side" of the port. | |||
e.g. for a physical audio output port, this is the time between | |||
writing to the port and when the audio will be audible. | |||
for a physical audio input port, this is the time between the sound | |||
being audible and the corresponding frames being readable from the | |||
port. | |||
*/ | |||
nframes_t jack_port_get_latency (jack_port_t *port); | |||
/* the port latency is zero by default. clients that control | |||
physical hardware with non-zero latency should call this | |||
to set the latency to its correct value. note that the value | |||
should include any systemic latency present "outside" the | |||
physical hardware controlled by the client. for example, | |||
for a client controlling a digital audio interface connected | |||
to an external digital converter, the latency setting should | |||
include both buffering by the audio interface *and* the converter. | |||
*/ | |||
void jack_port_set_latency (jack_port_t *, nframes_t); | |||
/* if JackPortCanMonitor is set for a port, then these 2 functions will | |||
turn on/off input monitoring for the port. if JackPortCanMonitor | |||
is not set, then these functions will have no effect. | |||
*/ | |||
int jack_port_request_monitor (jack_port_t *port, int onoff); | |||
int jack_port_request_monitor_by_name (jack_client_t *client, const char *port_name, int onoff); | |||
/* if JackPortCanMonitor is set for a port, then this function will | |||
turn on input monitoring if it was off, and will turn it off it | |||
only one request has been made to turn it on. if JackPortCanMonitor | |||
is not set, then this function will do nothing. | |||
*/ | |||
int jack_port_ensure_monitor (jack_port_t *port, int onoff); | |||
/* returns a true or false value depending on whether or not | |||
input monitoring has been requested for `port'. | |||
*/ | |||
int jack_port_monitoring_input (jack_port_t *port); | |||
/* this returns the sample rate of the jack system */ | |||
unsigned long jack_get_sample_rate (jack_client_t *); | |||
/* this returns the current maximum size that will | |||
ever be passed to the "process" callback. it should only | |||
be used *before* the client has been activated. after activation, | |||
the client will be notified of buffer size changes if it | |||
registers a buffer_size callback. | |||
*/ | |||
nframes_t jack_get_buffer_size (jack_client_t *); | |||
/* This function returns a NULL-terminated array of ports that match the | |||
specified arguments. | |||
port_name_pattern: a regular expression used to select ports by name. | |||
if NULL or of zero length, no selection based on | |||
name will be carried out. | |||
type_name_pattern: a regular expression used to select ports by type. | |||
if NULL or of zero length, no selection based on | |||
type will be carried out. | |||
flags: a value used to select ports by their flags. if | |||
zero, no selection based on flags will be carried out. | |||
The caller is responsible for calling free(3) any non-NULL returned | |||
value. | |||
*/ | |||
const char ** jack_get_ports (jack_client_t *, | |||
const char *port_name_pattern, | |||
const char *type_name_pattern, | |||
unsigned long flags); | |||
jack_port_t *jack_port_by_name (jack_client_t *, const char *portname); | |||
/* If a client is told (by the user) to become the timebase | |||
for the entire system, it calls this function. If it | |||
returns zero, then the client has the responsibility to | |||
call jack_update_time() at the end of its process() | |||
callback. Whatever time it provides (in frames since its | |||
reference zero time) becomes the current timebase for the | |||
entire system. | |||
*/ | |||
int jack_engine_takeover_timebase (jack_client_t *); | |||
void jack_update_time (jack_client_t *, nframes_t); | |||
/* this estimates the time that has passed since the | |||
start jack server started calling the process() | |||
callbacks of all its clients. | |||
*/ | |||
nframes_t jack_frames_since_cycle_start (jack_client_t *); | |||
#ifdef __cplusplus | |||
} | |||
#endif | |||
#endif /* __jack_h__ */ | |||
@@ -1,102 +0,0 @@ | |||
/* | |||
Copyright (C) 2001 Paul Davis | |||
This program is free software; you can redistribute it and/or modify | |||
it under the terms of the GNU Lesser General Public License as published by | |||
the Free Software Foundation; either version 2.1 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU Lesser General Public License for more details. | |||
You should have received a copy of the GNU Lesser General Public License | |||
along with this program; if not, write to the Free Software | |||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
$Id: port.h,v 1.1 2002-07-28 23:18:15 nebogeo Exp $ | |||
*/ | |||
#ifndef __jack_port_h__ | |||
#define __jack_port_h__ | |||
#include <pthread.h> | |||
#include <jack/types.h> | |||
typedef struct _jack_port_type_info { | |||
const char type_name[32]; /* what do you think ? */ | |||
void (*mixdown)(jack_port_t *, nframes_t); /* function to mixdown multiple inputs to a buffer. can be | |||
NULL, indicating that multiple input connections | |||
are not legal for this data type. | |||
*/ | |||
long buffer_scale_factor; /* If == 1, then a buffer to handle nframes worth of | |||
data is sizeof(sample_t) * nframes bytes large. | |||
If anything other than 1, the buffer allocated | |||
for input mixing will be this value times | |||
sizeof (sample_t) * nframes bytes in size. | |||
Obviously, for non-audio data types, it may have | |||
a different value. | |||
if < 0, then the value should be ignored, and | |||
port->shared->buffer_size should be used. | |||
*/ | |||
} jack_port_type_info_t; | |||
/* This is the data structure allocated in shared memory | |||
by the engine. | |||
*/ | |||
typedef struct _jack_port_shared { | |||
int shm_key; | |||
size_t offset; | |||
unsigned long flags; | |||
unsigned long buffer_size; | |||
jack_port_id_t id; | |||
char name[JACK_CLIENT_NAME_SIZE+JACK_PORT_NAME_SIZE+2]; | |||
jack_port_type_info_t type_info; | |||
jack_client_id_t client_id; | |||
nframes_t latency; | |||
unsigned char monitor_requests; | |||
char in_use : 1; | |||
char locked : 1; | |||
} jack_port_shared_t; | |||
/* This is the data structure allocated by the client | |||
in local memory. The `shared' pointer points | |||
the the corresponding structure in shared memory. | |||
*/ | |||
struct _jack_port { | |||
char *client_segment_base; | |||
struct _jack_port_shared *shared; | |||
pthread_mutex_t connection_lock; | |||
GSList *connections; | |||
struct _jack_port *tied; | |||
}; | |||
/* inline would be cleaner, but it needs to be fast even in non-optimized | |||
code. | |||
*/ | |||
#define jack_port_buffer(p) ((void *) ((p)->client_segment_base + (p)->shared->offset)) | |||
/* this is the structure allocated by the engine in local | |||
memory. | |||
*/ | |||
typedef struct _jack_port_internal { | |||
struct _jack_port_shared *shared; | |||
GSList *connections; | |||
void *buffer_info; | |||
} jack_port_internal_t; | |||
#endif /* __jack_port_h__ */ | |||