00001 /* 00002 Copyright (C) 2001 Paul Davis 00003 Copyright (C) 2004-2006 Grame 00004 00005 This program is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program; if not, write to the Free Software 00017 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00018 00019 */ 00020 00021 #ifdef WIN32 00022 #pragma warning (disable : 4786) 00023 #endif 00024 00025 #include "JackLoopbackDriver.h" 00026 #include "JackEngineControl.h" 00027 #include "JackGraphManager.h" 00028 #include <iostream> 00029 #include <assert.h> 00030 00031 namespace Jack 00032 { 00033 00034 int JackLoopbackDriver::Process() 00035 { 00036 assert(fCaptureChannels == fPlaybackChannels); 00037 00038 // Loopback copy 00039 for (int i = 0; i < fCaptureChannels; i++) { 00040 memcpy(GetInputBuffer(i), GetOutputBuffer(i), sizeof(float) * fEngineControl->fBufferSize); 00041 } 00042 00043 fGraphManager->ResumeRefNum(fClientControl, fSynchroTable); // Signal all clients 00044 if (fEngineControl->fSyncMode) { 00045 if (fGraphManager->SuspendRefNum(fClientControl, fSynchroTable, fEngineControl->fTimeOutUsecs) < 0) 00046 jack_error("JackLoopbackDriver::ProcessSync SuspendRefNum error"); 00047 } 00048 return 0; 00049 } 00050 00051 void JackLoopbackDriver::PrintState() 00052 { 00053 int i; 00054 jack_port_id_t port_index; 00055 00056 std::cout << "JackLoopbackDriver state" << std::endl; 00057 std::cout << "Input ports" << std::endl; 00058 00059 for (i = 0; i < fPlaybackChannels; i++) { 00060 port_index = fCapturePortList[i]; 00061 JackPort* port = fGraphManager->GetPort(port_index); 00062 std::cout << port->GetName() << std::endl; 00063 if (fGraphManager->GetConnectionsNum(port_index)) {} 00064 } 00065 00066 std::cout << "Output ports" << std::endl; 00067 00068 for (i = 0; i < fCaptureChannels; i++) { 00069 port_index = fPlaybackPortList[i]; 00070 JackPort* port = fGraphManager->GetPort(port_index); 00071 std::cout << port->GetName() << std::endl; 00072 if (fGraphManager->GetConnectionsNum(port_index)) {} 00073 } 00074 } 00075 00076 } // end of namespace 00077 00078 /* 00079 #ifdef __cplusplus 00080 extern "C" { 00081 #endif 00082 00083 jack_driver_desc_t * driver_get_descriptor () 00084 { 00085 jack_driver_desc_t * desc; 00086 jack_driver_param_desc_t * params; 00087 unsigned int i; 00088 00089 desc = (jack_driver_desc_t*)calloc (1, sizeof (jack_driver_desc_t)); 00090 strcpy (desc->name, "dummy"); 00091 desc->nparams = 5; 00092 00093 params = (jack_driver_param_desc_t*)calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); 00094 00095 i = 0; 00096 strcpy (params[i].name, "capture"); 00097 params[i].character = 'C'; 00098 params[i].type = JackDriverParamUInt; 00099 params[i].value.ui = 2U; 00100 strcpy (params[i].short_desc, "Number of capture ports"); 00101 strcpy (params[i].long_desc, params[i].short_desc); 00102 00103 i++; 00104 strcpy (params[i].name, "playback"); 00105 params[i].character = 'P'; 00106 params[i].type = JackDriverParamUInt; 00107 params[1].value.ui = 2U; 00108 strcpy (params[i].short_desc, "Number of playback ports"); 00109 strcpy (params[i].long_desc, params[i].short_desc); 00110 00111 i++; 00112 strcpy (params[i].name, "rate"); 00113 params[i].character = 'r'; 00114 params[i].type = JackDriverParamUInt; 00115 params[i].value.ui = 48000U; 00116 strcpy (params[i].short_desc, "Sample rate"); 00117 strcpy (params[i].long_desc, params[i].short_desc); 00118 00119 i++; 00120 strcpy (params[i].name, "period"); 00121 params[i].character = 'p'; 00122 params[i].type = JackDriverParamUInt; 00123 params[i].value.ui = 1024U; 00124 strcpy (params[i].short_desc, "Frames per period"); 00125 strcpy (params[i].long_desc, params[i].short_desc); 00126 00127 i++; 00128 strcpy (params[i].name, "wait"); 00129 params[i].character = 'w'; 00130 params[i].type = JackDriverParamUInt; 00131 params[i].value.ui = 21333U; 00132 strcpy (params[i].short_desc, 00133 "Number of usecs to wait between engine processes"); 00134 strcpy (params[i].long_desc, params[i].short_desc); 00135 00136 desc->params = params; 00137 00138 return desc; 00139 } 00140 00141 Jack::JackDriverClientInterface* driver_initialize(Jack::JackEngine* engine, Jack::JackSynchro** table, const JSList* params) 00142 { 00143 jack_nframes_t sample_rate = 48000; 00144 jack_nframes_t period_size = 1024; 00145 unsigned int capture_ports = 2; 00146 unsigned int playback_ports = 2; 00147 const JSList * node; 00148 const jack_driver_param_t * param; 00149 00150 for (node = params; node; node = jack_slist_next (node)) { 00151 param = (const jack_driver_param_t *) node->data; 00152 00153 switch (param->character) { 00154 00155 case 'C': 00156 capture_ports = param->value.ui; 00157 break; 00158 00159 case 'P': 00160 playback_ports = param->value.ui; 00161 break; 00162 00163 case 'r': 00164 sample_rate = param->value.ui; 00165 break; 00166 00167 case 'p': 00168 period_size = param->value.ui; 00169 break; 00170 00171 } 00172 } 00173 Jack::JackDriverClientInterface* driver = new Jack::JackLoopbackDriver("loopback", engine, table); 00174 if (driver->Open(period_size, sample_rate, 1, 1, capture_ports, playback_ports, "loopback") == 0) { 00175 return driver; 00176 } else { 00177 delete driver; 00178 return NULL; 00179 } 00180 } 00181 00182 #ifdef __cplusplus 00183 } 00184 #endif 00185 */ 00186