00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #if defined(HAVE_CONFIG_H)
00021 #include "config.h"
00022 #endif
00023
00024 #include "JackAlsaAdapter.h"
00025 #include "JackServerGlobals.h"
00026 #include "JackEngineControl.h"
00027
00028 namespace Jack
00029 {
00030
00031 JackAlsaAdapter::JackAlsaAdapter ( jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params ) :
00032 JackAudioAdapterInterface ( buffer_size, sample_rate ),
00033 fThread ( this ),
00034 fAudioInterface ( buffer_size, sample_rate )
00035 {
00036 const JSList* node;
00037 const jack_driver_param_t* param;
00038
00039 fCaptureChannels = 2;
00040 fPlaybackChannels = 2;
00041
00042 fAudioInterface.fPeriod = 2;
00043
00044 for ( node = params; node; node = jack_slist_next ( node ) )
00045 {
00046 param = ( const jack_driver_param_t* ) node->data;
00047
00048 switch ( param->character )
00049 {
00050 case 'i':
00051 fCaptureChannels = param->value.ui;
00052 break;
00053 case 'o':
00054 fPlaybackChannels = param->value.ui;
00055 break;
00056 case 'C':
00057 break;
00058 case 'P':
00059 break;
00060 case 'D':
00061 break;
00062 case 'n':
00063 fAudioInterface.fPeriod = param->value.ui;
00064 break;
00065 case 'd':
00066 fAudioInterface.fCardName = strdup ( param->value.str );
00067 break;
00068 case 'r':
00069 fAudioInterface.fFrequency = param->value.ui;
00070 SetAdaptedSampleRate ( param->value.ui );
00071 break;
00072 case 'p':
00073 fAudioInterface.fBuffering = param->value.ui;
00074 SetAdaptedBufferSize ( param->value.ui );
00075 break;
00076 case 'q':
00077 fQuality = param->value.ui;
00078 break;
00079 case 'g':
00080 fRingbufferCurSize = param->value.ui;
00081 fAdaptative = false;
00082 break;
00083 }
00084 }
00085
00086 fAudioInterface.setInputs ( fCaptureChannels );
00087 fAudioInterface.setOutputs ( fPlaybackChannels );
00088 }
00089
00090 int JackAlsaAdapter::Open()
00091 {
00092
00093 if ( fAudioInterface.open() )
00094 return -1;
00095
00096
00097 if ( fThread.StartSync() < 0 )
00098 {
00099 jack_error ( "Cannot start audioadapter thread" );
00100 return -1;
00101 }
00102
00103
00104 fAudioInterface.longinfo();
00105
00106
00107 fThread.AcquireRealTime ( JackServerGlobals::fInstance->GetEngineControl()->fClientPriority );
00108 return 0;
00109 }
00110
00111 int JackAlsaAdapter::Close()
00112 {
00113 #ifdef JACK_MONITOR
00114 fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize);
00115 #endif
00116 switch ( fThread.GetStatus() )
00117 {
00118
00119
00120 case JackThread::kStarting:
00121 case JackThread::kIniting:
00122 if ( fThread.Kill() < 0 )
00123 {
00124 jack_error ( "Cannot kill thread" );
00125 return -1;
00126 }
00127 break;
00128
00129
00130 case JackThread::kRunning:
00131 if ( fThread.Stop() < 0 )
00132 {
00133 jack_error ( "Cannot stop thread" );
00134 return -1;
00135 }
00136 break;
00137
00138 default:
00139 break;
00140 }
00141 return fAudioInterface.close();
00142 }
00143
00144 bool JackAlsaAdapter::Init()
00145 {
00146
00147 for ( unsigned int i = 0; i < fAudioInterface.fPeriod; i++ )
00148 fAudioInterface.write();
00149 return true;
00150 }
00151
00152 bool JackAlsaAdapter::Execute()
00153 {
00154
00155 if (fAudioInterface.read() < 0)
00156 return false;
00157
00158 PushAndPull(fAudioInterface.fInputSoftChannels, fAudioInterface.fOutputSoftChannels, fAdaptedBufferSize);
00159
00160
00161 if (fAudioInterface.write() < 0)
00162 return false;
00163
00164 return true;
00165 }
00166
00167 int JackAlsaAdapter::SetSampleRate ( jack_nframes_t sample_rate )
00168 {
00169 JackAudioAdapterInterface::SetHostSampleRate ( sample_rate );
00170 Close();
00171 return Open();
00172 }
00173
00174 int JackAlsaAdapter::SetBufferSize ( jack_nframes_t buffer_size )
00175 {
00176 JackAudioAdapterInterface::SetHostBufferSize ( buffer_size );
00177 Close();
00178 return Open();
00179 }
00180
00181 }
00182
00183 #ifdef __cplusplus
00184 extern "C"
00185 {
00186 #endif
00187
00188 SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor()
00189 {
00190 jack_driver_desc_t *desc;
00191 unsigned int i;
00192 desc = ( jack_driver_desc_t* ) calloc ( 1, sizeof ( jack_driver_desc_t ) );
00193
00194 strcpy ( desc->name, "audioadapter" );
00195 strcpy ( desc->desc, "netjack audio <==> net backend adapter" );
00196
00197 desc->nparams = 11;
00198 desc->params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) );
00199
00200 i = 0;
00201 strcpy ( desc->params[i].name, "capture" );
00202 desc->params[i].character = 'C';
00203 desc->params[i].type = JackDriverParamString;
00204 strcpy ( desc->params[i].value.str, "none" );
00205 strcpy ( desc->params[i].short_desc,
00206 "Provide capture ports. Optionally set device" );
00207 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00208
00209 i++;
00210 strcpy ( desc->params[i].name, "playback" );
00211 desc->params[i].character = 'P';
00212 desc->params[i].type = JackDriverParamString;
00213 strcpy ( desc->params[i].value.str, "none" );
00214 strcpy ( desc->params[i].short_desc,
00215 "Provide playback ports. Optionally set device" );
00216 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00217
00218 i++;
00219 strcpy ( desc->params[i].name, "device" );
00220 desc->params[i].character = 'd';
00221 desc->params[i].type = JackDriverParamString;
00222 strcpy ( desc->params[i].value.str, "hw:0" );
00223 strcpy ( desc->params[i].short_desc, "ALSA device name" );
00224 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00225
00226 i++;
00227 strcpy ( desc->params[i].name, "rate" );
00228 desc->params[i].character = 'r';
00229 desc->params[i].type = JackDriverParamUInt;
00230 desc->params[i].value.ui = 48000U;
00231 strcpy ( desc->params[i].short_desc, "Sample rate" );
00232 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00233
00234 i++;
00235 strcpy ( desc->params[i].name, "periodsize" );
00236 desc->params[i].character = 'p';
00237 desc->params[i].type = JackDriverParamUInt;
00238 desc->params[i].value.ui = 512U;
00239 strcpy ( desc->params[i].short_desc, "Period size" );
00240 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00241
00242 i++;
00243 strcpy ( desc->params[i].name, "nperiods" );
00244 desc->params[i].character = 'n';
00245 desc->params[i].type = JackDriverParamUInt;
00246 desc->params[i].value.ui = 2U;
00247 strcpy ( desc->params[i].short_desc, "Number of periods of playback latency" );
00248 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00249
00250 i++;
00251 strcpy ( desc->params[i].name, "duplex" );
00252 desc->params[i].character = 'D';
00253 desc->params[i].type = JackDriverParamBool;
00254 desc->params[i].value.i = true;
00255 strcpy ( desc->params[i].short_desc,
00256 "Provide both capture and playback ports" );
00257 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00258
00259 i++;
00260 strcpy ( desc->params[i].name, "inchannels" );
00261 desc->params[i].character = 'i';
00262 desc->params[i].type = JackDriverParamUInt;
00263 desc->params[i].value.i = 0;
00264 strcpy ( desc->params[i].short_desc,
00265 "Number of capture channels (defaults to hardware max)" );
00266 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00267
00268 i++;
00269 strcpy ( desc->params[i].name, "outchannels" );
00270 desc->params[i].character = 'o';
00271 desc->params[i].type = JackDriverParamUInt;
00272 desc->params[i].value.i = 0;
00273 strcpy ( desc->params[i].short_desc,
00274 "Number of playback channels (defaults to hardware max)" );
00275 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00276
00277 i++;
00278 strcpy(desc->params[i].name, "quality");
00279 desc->params[i].character = 'q';
00280 desc->params[i].type = JackDriverParamInt;
00281 desc->params[i].value.ui = 0;
00282 strcpy(desc->params[i].short_desc, "Resample algorithm quality (0 - 4)");
00283 strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
00284
00285 i++;
00286 strcpy(desc->params[i].name, "ring-buffer");
00287 desc->params[i].character = 'g';
00288 desc->params[i].type = JackDriverParamInt;
00289 desc->params[i].value.ui = 32768;
00290 strcpy(desc->params[i].short_desc, "Fixed ringbuffer size");
00291 strcpy(desc->params[i].long_desc, "Fixed ringbuffer size (if not set => automatic adaptative)");
00292
00293 return desc;
00294 }
00295
00296 #ifdef __cplusplus
00297 }
00298 #endif
00299