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 "JackGlobals.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(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 jack_driver_desc_filler_t filler;
00192 jack_driver_param_value_t value;
00193
00194 desc = jack_driver_descriptor_construct("audioadapter", JackDriverNone, "netjack audio <==> net backend adapter", &filler);
00195
00196 strcpy(value.str, "none");
00197 jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamString, &value, NULL, "Provide capture ports. Optionally set device", NULL);
00198 jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamString, &value, NULL, "Provide playback ports. Optionally set device", NULL);
00199
00200 strcpy(value.str, "hw:0");
00201 jack_driver_descriptor_add_parameter(desc, &filler, "device", 'd', JackDriverParamString, &value, NULL, "ALSA device name", NULL);
00202
00203 value.ui = 48000U;
00204 jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL);
00205
00206 value.ui = 512U;
00207 jack_driver_descriptor_add_parameter(desc, &filler, "periodsize", 'p', JackDriverParamUInt, &value, NULL, "Period size", NULL);
00208
00209 value.ui = 2U;
00210 jack_driver_descriptor_add_parameter(desc, &filler, "nperiods", 'n', JackDriverParamUInt, &value, NULL, "Number of periods of playback latency", NULL);
00211
00212 value.i = true;
00213 jack_driver_descriptor_add_parameter(desc, &filler, "duplex", 'D', JackDriverParamBool, &value, NULL, "Provide both capture and playback ports", NULL);
00214
00215 value.i = 0;
00216 jack_driver_descriptor_add_parameter(desc, &filler, "in-channels", 'i', JackDriverParamInt, &value, NULL, "Number of capture channels (defaults to hardware max)", NULL);
00217 jack_driver_descriptor_add_parameter(desc, &filler, "out-channels", 'o', JackDriverParamInt, &value, NULL, "Number of playback channels (defaults to hardware max)", NULL);
00218
00219 value.ui = 0;
00220 jack_driver_descriptor_add_parameter(desc, &filler, "quality", 'q', JackDriverParamUInt, &value, NULL, "Resample algorithm quality (0 - 4)", NULL);
00221
00222 value.ui = 32768;
00223 jack_driver_descriptor_add_parameter(desc, &filler, "ring-buffer", 'g', JackDriverParamUInt, &value, NULL, "Fixed ringbuffer size", "Fixed ringbuffer size (if not set => automatic adaptative)");
00224
00225 return desc;
00226 }
00227
00228 #ifdef __cplusplus
00229 }
00230 #endif
00231