Devin Anderson jackmp-fix-ffado-midi-2.diff patch.
[jack2.git] / linux / alsa / JackAlsaAdapter.cpp
bloba046e1f2c027348a823bc6bfc2d3d83cf9339555
1 /*
2 Copyright (C) 2008 Grame
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #if defined(HAVE_CONFIG_H)
21 #include "config.h"
22 #endif
24 #include "JackAlsaAdapter.h"
25 #include "JackServerGlobals.h"
26 #include "JackEngineControl.h"
28 namespace Jack
31 JackAlsaAdapter::JackAlsaAdapter ( jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params ) :
32 JackAudioAdapterInterface ( buffer_size, sample_rate ),
33 fThread ( this ),
34 fAudioInterface ( buffer_size, sample_rate )
36 const JSList* node;
37 const jack_driver_param_t* param;
39 fCaptureChannels = 2;
40 fPlaybackChannels = 2;
42 fAudioInterface.fPeriod = 2;
44 for ( node = params; node; node = jack_slist_next ( node ) )
46 param = ( const jack_driver_param_t* ) node->data;
48 switch ( param->character )
50 case 'i':
51 fCaptureChannels = param->value.ui;
52 break;
53 case 'o':
54 fPlaybackChannels = param->value.ui;
55 break;
56 case 'C':
57 break;
58 case 'P':
59 break;
60 case 'D':
61 break;
62 case 'n':
63 fAudioInterface.fPeriod = param->value.ui;
64 break;
65 case 'd':
66 fAudioInterface.fCardName = strdup ( param->value.str );
67 break;
68 case 'r':
69 fAudioInterface.fFrequency = param->value.ui;
70 SetAdaptedSampleRate ( param->value.ui );
71 break;
72 case 'p':
73 fAudioInterface.fBuffering = param->value.ui;
74 SetAdaptedBufferSize ( param->value.ui );
75 break;
76 case 'q':
77 fQuality = param->value.ui;
78 break;
79 case 'g':
80 fRingbufferCurSize = param->value.ui;
81 fAdaptative = false;
82 break;
86 fAudioInterface.setInputs ( fCaptureChannels );
87 fAudioInterface.setOutputs ( fPlaybackChannels );
90 int JackAlsaAdapter::Open()
92 //open audio interface
93 if ( fAudioInterface.open() )
94 return -1;
96 //start adapter thread
97 if ( fThread.StartSync() < 0 )
99 jack_error ( "Cannot start audioadapter thread" );
100 return -1;
103 //display card info
104 fAudioInterface.longinfo();
106 //turn the thread realtime
107 fThread.AcquireRealTime ( JackServerGlobals::fInstance->GetEngineControl()->fClientPriority );
108 return 0;
111 int JackAlsaAdapter::Close()
113 #ifdef JACK_MONITOR
114 fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize);
115 #endif
116 switch ( fThread.GetStatus() )
119 // Kill the thread in Init phase
120 case JackThread::kStarting:
121 case JackThread::kIniting:
122 if ( fThread.Kill() < 0 )
124 jack_error ( "Cannot kill thread" );
125 return -1;
127 break;
129 // Stop when the thread cycle is finished
130 case JackThread::kRunning:
131 if ( fThread.Stop() < 0 )
133 jack_error ( "Cannot stop thread" );
134 return -1;
136 break;
138 default:
139 break;
141 return fAudioInterface.close();
144 bool JackAlsaAdapter::Init()
146 //fill the hardware buffers
147 for ( unsigned int i = 0; i < fAudioInterface.fPeriod; i++ )
148 fAudioInterface.write();
149 return true;
152 bool JackAlsaAdapter::Execute()
154 //read data from audio interface
155 if (fAudioInterface.read() < 0)
156 return false;
158 PushAndPull(fAudioInterface.fInputSoftChannels, fAudioInterface.fOutputSoftChannels, fAdaptedBufferSize);
160 //write data to audio interface
161 if (fAudioInterface.write() < 0)
162 return false;
164 return true;
167 int JackAlsaAdapter::SetSampleRate ( jack_nframes_t sample_rate )
169 JackAudioAdapterInterface::SetHostSampleRate ( sample_rate );
170 Close();
171 return Open();
174 int JackAlsaAdapter::SetBufferSize ( jack_nframes_t buffer_size )
176 JackAudioAdapterInterface::SetHostBufferSize ( buffer_size );
177 Close();
178 return Open();
181 } // namespace
183 #ifdef __cplusplus
184 extern "C"
186 #endif
188 SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor()
190 jack_driver_desc_t *desc;
191 unsigned int i;
192 desc = ( jack_driver_desc_t* ) calloc ( 1, sizeof ( jack_driver_desc_t ) );
194 strcpy ( desc->name, "audioadapter" ); // size MUST be less then JACK_DRIVER_NAME_MAX + 1
195 strcpy ( desc->desc, "netjack audio <==> net backend adapter" ); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1
197 desc->nparams = 11;
198 desc->params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) );
200 i = 0;
201 strcpy ( desc->params[i].name, "capture" );
202 desc->params[i].character = 'C';
203 desc->params[i].type = JackDriverParamString;
204 strcpy ( desc->params[i].value.str, "none" );
205 strcpy ( desc->params[i].short_desc,
206 "Provide capture ports. Optionally set device" );
207 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
209 i++;
210 strcpy ( desc->params[i].name, "playback" );
211 desc->params[i].character = 'P';
212 desc->params[i].type = JackDriverParamString;
213 strcpy ( desc->params[i].value.str, "none" );
214 strcpy ( desc->params[i].short_desc,
215 "Provide playback ports. Optionally set device" );
216 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
218 i++;
219 strcpy ( desc->params[i].name, "device" );
220 desc->params[i].character = 'd';
221 desc->params[i].type = JackDriverParamString;
222 strcpy ( desc->params[i].value.str, "hw:0" );
223 strcpy ( desc->params[i].short_desc, "ALSA device name" );
224 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
226 i++;
227 strcpy ( desc->params[i].name, "rate" );
228 desc->params[i].character = 'r';
229 desc->params[i].type = JackDriverParamUInt;
230 desc->params[i].value.ui = 48000U;
231 strcpy ( desc->params[i].short_desc, "Sample rate" );
232 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
234 i++;
235 strcpy ( desc->params[i].name, "periodsize" );
236 desc->params[i].character = 'p';
237 desc->params[i].type = JackDriverParamUInt;
238 desc->params[i].value.ui = 512U;
239 strcpy ( desc->params[i].short_desc, "Period size" );
240 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
242 i++;
243 strcpy ( desc->params[i].name, "nperiods" );
244 desc->params[i].character = 'n';
245 desc->params[i].type = JackDriverParamUInt;
246 desc->params[i].value.ui = 2U;
247 strcpy ( desc->params[i].short_desc, "Number of periods of playback latency" );
248 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
250 i++;
251 strcpy ( desc->params[i].name, "duplex" );
252 desc->params[i].character = 'D';
253 desc->params[i].type = JackDriverParamBool;
254 desc->params[i].value.i = true;
255 strcpy ( desc->params[i].short_desc,
256 "Provide both capture and playback ports" );
257 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
259 i++;
260 strcpy ( desc->params[i].name, "inchannels" );
261 desc->params[i].character = 'i';
262 desc->params[i].type = JackDriverParamUInt;
263 desc->params[i].value.i = 0;
264 strcpy ( desc->params[i].short_desc,
265 "Number of capture channels (defaults to hardware max)" );
266 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
268 i++;
269 strcpy ( desc->params[i].name, "outchannels" );
270 desc->params[i].character = 'o';
271 desc->params[i].type = JackDriverParamUInt;
272 desc->params[i].value.i = 0;
273 strcpy ( desc->params[i].short_desc,
274 "Number of playback channels (defaults to hardware max)" );
275 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
277 i++;
278 strcpy(desc->params[i].name, "quality");
279 desc->params[i].character = 'q';
280 desc->params[i].type = JackDriverParamInt;
281 desc->params[i].value.ui = 0;
282 strcpy(desc->params[i].short_desc, "Resample algorithm quality (0 - 4)");
283 strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
285 i++;
286 strcpy(desc->params[i].name, "ring-buffer");
287 desc->params[i].character = 'g';
288 desc->params[i].type = JackDriverParamInt;
289 desc->params[i].value.ui = 32768;
290 strcpy(desc->params[i].short_desc, "Fixed ringbuffer size");
291 strcpy(desc->params[i].long_desc, "Fixed ringbuffer size (if not set => automatic adaptative)");
293 return desc;
296 #ifdef __cplusplus
298 #endif