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)
24 #include "JackAlsaAdapter.h"
25 #include "JackGlobals.h"
26 #include "JackEngineControl.h"
31 JackAlsaAdapter::JackAlsaAdapter ( jack_nframes_t buffer_size
, jack_nframes_t sample_rate
, const JSList
* params
) :
32 JackAudioAdapterInterface ( buffer_size
, sample_rate
),
34 fAudioInterface ( buffer_size
, sample_rate
)
37 const jack_driver_param_t
* param
;
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
)
51 fCaptureChannels
= param
->value
.ui
;
54 fPlaybackChannels
= param
->value
.ui
;
57 if (strncmp(param
->value
.str
,"none",4) != 0) {
58 fAudioInterface
.fCaptureName
= strdup ( param
->value
.str
);
62 if (strncmp(param
->value
.str
,"none",4) != 0) {
63 fAudioInterface
.fPlaybackName
= strdup ( param
->value
.str
);
69 fAudioInterface
.fPeriod
= param
->value
.ui
;
72 fAudioInterface
.fCardName
= strdup ( param
->value
.str
);
75 fAudioInterface
.fFrequency
= param
->value
.ui
;
76 SetAdaptedSampleRate ( param
->value
.ui
);
79 fAudioInterface
.fBuffering
= param
->value
.ui
;
80 SetAdaptedBufferSize ( param
->value
.ui
);
83 fQuality
= param
->value
.ui
;
86 fRingbufferCurSize
= param
->value
.ui
;
92 fAudioInterface
.setInputs ( fCaptureChannels
);
93 fAudioInterface
.setOutputs ( fPlaybackChannels
);
96 int JackAlsaAdapter::Open()
98 //open audio interface
99 if ( fAudioInterface
.open() )
102 //start adapter thread
103 if ( fThread
.StartSync() < 0 )
105 jack_error ( "Cannot start audioadapter thread" );
110 fAudioInterface
.longinfo();
112 //turn the thread realtime
113 fThread
.AcquireRealTime(GetEngineControl()->fClientPriority
);
117 int JackAlsaAdapter::Close()
120 fTable
.Save(fHostBufferSize
, fHostSampleRate
, fAdaptedSampleRate
, fAdaptedBufferSize
);
122 switch ( fThread
.GetStatus() )
125 // Kill the thread in Init phase
126 case JackThread::kStarting
:
127 case JackThread::kIniting
:
128 if ( fThread
.Kill() < 0 )
130 jack_error ( "Cannot kill thread" );
135 // Stop when the thread cycle is finished
136 case JackThread::kRunning
:
137 if ( fThread
.Stop() < 0 )
139 jack_error ( "Cannot stop thread" );
147 return fAudioInterface
.close();
150 bool JackAlsaAdapter::Init()
152 //fill the hardware buffers
153 for ( unsigned int i
= 0; i
< fAudioInterface
.fPeriod
; i
++ )
154 fAudioInterface
.write();
158 bool JackAlsaAdapter::Execute()
160 //read data from audio interface
161 if (fAudioInterface
.read() < 0)
164 PushAndPull(fAudioInterface
.fInputSoftChannels
, fAudioInterface
.fOutputSoftChannels
, fAdaptedBufferSize
);
166 //write data to audio interface
167 if (fAudioInterface
.write() < 0)
173 int JackAlsaAdapter::SetSampleRate ( jack_nframes_t sample_rate
)
175 JackAudioAdapterInterface::SetHostSampleRate ( sample_rate
);
180 int JackAlsaAdapter::SetBufferSize ( jack_nframes_t buffer_size
)
182 JackAudioAdapterInterface::SetHostBufferSize ( buffer_size
);
194 SERVER_EXPORT jack_driver_desc_t
* jack_get_descriptor()
196 jack_driver_desc_t
* desc
;
197 jack_driver_desc_filler_t filler
;
198 jack_driver_param_value_t value
;
200 desc
= jack_driver_descriptor_construct("audioadapter", JackDriverNone
, "netjack audio <==> net backend adapter", &filler
);
202 strcpy(value
.str
, "none");
203 jack_driver_descriptor_add_parameter(desc
, &filler
, "capture", 'C', JackDriverParamString
, &value
, NULL
, "Provide capture ports. Optionally set device", NULL
);
204 jack_driver_descriptor_add_parameter(desc
, &filler
, "playback", 'P', JackDriverParamString
, &value
, NULL
, "Provide playback ports. Optionally set device", NULL
);
206 strcpy(value
.str
, "hw:0");
207 jack_driver_descriptor_add_parameter(desc
, &filler
, "device", 'd', JackDriverParamString
, &value
, NULL
, "ALSA device name", NULL
);
210 jack_driver_descriptor_add_parameter(desc
, &filler
, "rate", 'r', JackDriverParamUInt
, &value
, NULL
, "Sample rate", NULL
);
213 jack_driver_descriptor_add_parameter(desc
, &filler
, "periodsize", 'p', JackDriverParamUInt
, &value
, NULL
, "Period size", NULL
);
216 jack_driver_descriptor_add_parameter(desc
, &filler
, "nperiods", 'n', JackDriverParamUInt
, &value
, NULL
, "Number of periods of playback latency", NULL
);
219 jack_driver_descriptor_add_parameter(desc
, &filler
, "duplex", 'D', JackDriverParamBool
, &value
, NULL
, "Provide both capture and playback ports", NULL
);
222 jack_driver_descriptor_add_parameter(desc
, &filler
, "in-channels", 'i', JackDriverParamInt
, &value
, NULL
, "Number of capture channels (defaults to hardware max)", NULL
);
223 jack_driver_descriptor_add_parameter(desc
, &filler
, "out-channels", 'o', JackDriverParamInt
, &value
, NULL
, "Number of playback channels (defaults to hardware max)", NULL
);
226 jack_driver_descriptor_add_parameter(desc
, &filler
, "quality", 'q', JackDriverParamUInt
, &value
, NULL
, "Resample algorithm quality (0 - 4)", NULL
);
229 jack_driver_descriptor_add_parameter(desc
, &filler
, "ring-buffer", 'g', JackDriverParamUInt
, &value
, NULL
, "Fixed ringbuffer size", "Fixed ringbuffer size (if not set => automatic adaptative)");