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 SetAdaptedSampleRate ( param->value.ui );
00070 break;
00071 case 'p':
00072 SetAdaptedBufferSize ( param->value.ui );
00073 break;
00074 case 'q':
00075 fQuality = param->value.ui;
00076 break;
00077 }
00078 }
00079
00080 fAudioInterface.setInputs ( fCaptureChannels );
00081 fAudioInterface.setOutputs ( fPlaybackChannels );
00082 }
00083
00084 int JackAlsaAdapter::Open()
00085 {
00086
00087 if ( fAudioInterface.open() )
00088 return -1;
00089
00090
00091 if ( fThread.StartSync() < 0 )
00092 {
00093 jack_error ( "Cannot start audioadapter thread" );
00094 return -1;
00095 }
00096
00097
00098 fAudioInterface.longinfo();
00099
00100
00101 fThread.AcquireRealTime ( JackServerGlobals::fInstance->GetEngineControl()->fClientPriority );
00102
00103 return 0;
00104 }
00105
00106 int JackAlsaAdapter::Close()
00107 {
00108 #ifdef JACK_MONITOR
00109 fTable.Save();
00110 #endif
00111 switch ( fThread.GetStatus() )
00112 {
00113
00114
00115 case JackThread::kStarting:
00116 case JackThread::kIniting:
00117 if ( fThread.Kill() < 0 )
00118 {
00119 jack_error ( "Cannot kill thread" );
00120 return -1;
00121 }
00122 break;
00123
00124
00125 case JackThread::kRunning:
00126 if ( fThread.Stop() < 0 )
00127 {
00128 jack_error ( "Cannot stop thread" );
00129 return -1;
00130 }
00131 break;
00132
00133 default:
00134 break;
00135 }
00136 return fAudioInterface.close();
00137 }
00138
00139 bool JackAlsaAdapter::Init()
00140 {
00141
00142 for ( unsigned int i = 0; i < fAudioInterface.fPeriod; i++ )
00143 fAudioInterface.write();
00144 return true;
00145 }
00146
00147 bool JackAlsaAdapter::Execute()
00148 {
00149
00150 if ( fAudioInterface.read() < 0 )
00151 return false;
00152
00153 bool failure = false;
00154
00155
00156 jack_nframes_t time1, time2;
00157 ResampleFactor ( time1, time2 );
00158
00159
00160 for ( int i = 0; i < fCaptureChannels; i++ )
00161 {
00162 fCaptureRingBuffer[i]->SetRatio ( time1, time2 );
00163 if ( fCaptureRingBuffer[i]->WriteResample ( fAudioInterface.fInputSoftChannels[i], fAdaptedBufferSize ) < fAdaptedBufferSize )
00164 failure = true;
00165 }
00166
00167 for ( int i = 0; i < fPlaybackChannels; i++ )
00168 {
00169 fPlaybackRingBuffer[i]->SetRatio ( time2, time1 );
00170 if ( fPlaybackRingBuffer[i]->ReadResample ( fAudioInterface.fOutputSoftChannels[i], fAdaptedBufferSize ) < fAdaptedBufferSize )
00171 failure = true;
00172 }
00173
00174 #ifdef JACK_MONITOR
00175 fTable.Write ( time1, time2, double ( time1 ) / double ( time2 ), double ( time2 ) / double ( time1 ),
00176 fCaptureRingBuffer[0]->ReadSpace(), fPlaybackRingBuffer[0]->WriteSpace() );
00177 #endif
00178
00179
00180 if ( fAudioInterface.write() < 0 )
00181 return false;
00182
00183
00184 if ( failure )
00185 {
00186 jack_error ( "JackAlsaAdapter::Execute ringbuffer failure... reset" );
00187 ResetRingBuffers();
00188 }
00189
00190 return true;
00191 }
00192
00193 int JackAlsaAdapter::SetSampleRate ( jack_nframes_t sample_rate )
00194 {
00195 JackAudioAdapterInterface::SetHostSampleRate ( sample_rate );
00196 Close();
00197 return Open();
00198 }
00199
00200 int JackAlsaAdapter::SetBufferSize ( jack_nframes_t buffer_size )
00201 {
00202 JackAudioAdapterInterface::SetHostBufferSize ( buffer_size );
00203 Close();
00204 return Open();
00205 }
00206
00207 }
00208
00209 #ifdef __cplusplus
00210 extern "C"
00211 {
00212 #endif
00213
00214 SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor()
00215 {
00216 jack_driver_desc_t *desc;
00217 unsigned int i;
00218 desc = ( jack_driver_desc_t* ) calloc ( 1, sizeof ( jack_driver_desc_t ) );
00219
00220 strcpy ( desc->name, "audioadapter" );
00221 strcpy ( desc->desc, "netjack audio <==> net backend adapter" );
00222
00223 desc->nparams = 10;
00224 desc->params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) );
00225
00226 i = 0;
00227 strcpy ( desc->params[i].name, "capture" );
00228 desc->params[i].character = 'C';
00229 desc->params[i].type = JackDriverParamString;
00230 strcpy ( desc->params[i].value.str, "none" );
00231 strcpy ( desc->params[i].short_desc,
00232 "Provide capture ports. Optionally set device" );
00233 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00234
00235 i++;
00236 strcpy ( desc->params[i].name, "playback" );
00237 desc->params[i].character = 'P';
00238 desc->params[i].type = JackDriverParamString;
00239 strcpy ( desc->params[i].value.str, "none" );
00240 strcpy ( desc->params[i].short_desc,
00241 "Provide playback ports. Optionally set device" );
00242 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00243
00244 i++;
00245 strcpy ( desc->params[i].name, "device" );
00246 desc->params[i].character = 'd';
00247 desc->params[i].type = JackDriverParamString;
00248 strcpy ( desc->params[i].value.str, "hw:0" );
00249 strcpy ( desc->params[i].short_desc, "ALSA device name" );
00250 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00251
00252 i++;
00253 strcpy ( desc->params[i].name, "rate" );
00254 desc->params[i].character = 'r';
00255 desc->params[i].type = JackDriverParamUInt;
00256 desc->params[i].value.ui = 48000U;
00257 strcpy ( desc->params[i].short_desc, "Sample rate" );
00258 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00259
00260 i++;
00261 strcpy ( desc->params[i].name, "periodsize" );
00262 desc->params[i].character = 'p';
00263 desc->params[i].type = JackDriverParamUInt;
00264 desc->params[i].value.ui = 512U;
00265 strcpy ( desc->params[i].short_desc, "Period size" );
00266 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00267
00268 i++;
00269 strcpy ( desc->params[i].name, "nperiods" );
00270 desc->params[i].character = 'n';
00271 desc->params[i].type = JackDriverParamUInt;
00272 desc->params[i].value.ui = 2U;
00273 strcpy ( desc->params[i].short_desc, "Number of periods of playback latency" );
00274 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00275
00276 i++;
00277 strcpy ( desc->params[i].name, "duplex" );
00278 desc->params[i].character = 'D';
00279 desc->params[i].type = JackDriverParamBool;
00280 desc->params[i].value.i = 1;
00281 strcpy ( desc->params[i].short_desc,
00282 "Provide both capture and playback ports" );
00283 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00284
00285 i++;
00286 strcpy ( desc->params[i].name, "inchannels" );
00287 desc->params[i].character = 'i';
00288 desc->params[i].type = JackDriverParamUInt;
00289 desc->params[i].value.i = 0;
00290 strcpy ( desc->params[i].short_desc,
00291 "Number of capture channels (defaults to hardware max)" );
00292 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00293
00294 i++;
00295 strcpy ( desc->params[i].name, "outchannels" );
00296 desc->params[i].character = 'o';
00297 desc->params[i].type = JackDriverParamUInt;
00298 desc->params[i].value.i = 0;
00299 strcpy ( desc->params[i].short_desc,
00300 "Number of playback channels (defaults to hardware max)" );
00301 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00302
00303
00304 i++;
00305 strcpy(desc->params[i].name, "quality");
00306 desc->params[i].character = 'q';
00307 desc->params[i].type = JackDriverParamInt;
00308 desc->params[i].value.ui = 0;
00309 strcpy(desc->params[i].short_desc, "Resample algorithm quality (0 - 4)");
00310 strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
00311
00312 return desc;
00313 }
00314
00315 #ifdef __cplusplus
00316 }
00317 #endif
00318