1 /***************************************************************************
2  *                                                                         *
3  *   LinuxSampler - modular, streaming capable sampler                     *
4  *                                                                         *
5  *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
6  *   Copyright (C) 2005 - 2014 Christian Schoenebeck                       *
7  *                                                                         *
8  *   This program is free software; you can redistribute it and/or modify  *
9  *   it under the terms of the GNU General Public License as published by  *
10  *   the Free Software Foundation; either version 2 of the License, or     *
11  *   (at your option) any later version.                                   *
12  *                                                                         *
13  *   This program is distributed in the hope that it will be useful,       *
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
16  *   GNU General Public License for more details.                          *
17  *                                                                         *
18  *   You should have received a copy of the GNU General Public License     *
19  *   along with this program; if not, write to the Free Software           *
20  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
21  *   MA  02111-1307  USA                                                   *
22  ***************************************************************************/
23 
24 #ifndef __LS_AUDIOOUTPUTDEVICEJACK_H__
25 #define __LS_AUDIOOUTPUTDEVICEJACK_H__
26 
27 #include "../../common/global_private.h"
28 
29 #if HAVE_JACK
30 
31 #include <vector>
32 #include <sstream>
33 #include <jack/jack.h>
34 
35 #include "AudioOutputDevice.h"
36 #include "../../common/ConditionServer.h"
37 
38 #if HAVE_JACK_MIDI
39 #include "../midi/MidiInputDeviceJack.h"
40 #endif
41 
42 namespace LinuxSampler {
43 
44     class JackClient;
45     class JackListener;
46 
47     /** JACK audio output driver
48      *
49      * Implements audio output to the JACK Audio Connection Kit (JACK).
50      */
51     class AudioOutputDeviceJack : public AudioOutputDevice {
52         public:
53             AudioOutputDeviceJack(std::map<String,DeviceCreationParameter*> Parameters);
54             virtual ~AudioOutputDeviceJack();
55 
56             /**
57              * Audio channel implementation for the JACK audio driver.
58              */
59             class AudioChannelJack : public AudioChannel {
60                 public:
61                     /** Audio Channel Parameter 'NAME'
62                      *
63                      * Used to assign an arbitrary name to an audio channel.
64                      */
65                     class ParameterName : public AudioChannel::ParameterName {
66                         public:
67                             ParameterName(AudioChannelJack* pChannel);
68                             virtual void OnSetValue(String s) OVERRIDE;
69                         protected:
70                             AudioChannelJack* pChannel;
71                     };
72 
73                     /** Audio Channel Parameter 'JACK_BINDINGS'
74                      *
75                      * Used to connect to other JACK clients.
76                      */
77                     class ParameterJackBindings : public DeviceRuntimeParameterStrings {
78                         public:
79                             ParameterJackBindings(AudioChannelJack* pChannel);
80                             virtual String              Description() OVERRIDE;
81                             virtual bool                Fix() OVERRIDE;
82                             virtual std::vector<String> PossibilitiesAsString() OVERRIDE;
83                             virtual void                OnSetValue(std::vector<String> vS) OVERRIDE;
84                             static String Name();
85                         protected:
86                             AudioChannelJack*   pChannel;
87                             std::vector<String> Bindings;
88                     };
89                 protected:
90                     AudioChannelJack(uint ChannelNr, AudioOutputDeviceJack* pDevice) throw (AudioOutputException);
91                     ~AudioChannelJack();
92                     void UpdateJackBuffer(uint size);
93                     friend class AudioOutputDeviceJack;
94                 private:
95                     AudioOutputDeviceJack* pDevice;
96                     jack_port_t*           hJackPort;
97                     uint                   ChannelNr;
98 
99                     float* CreateJackPort(uint ChannelNr, AudioOutputDeviceJack* pDevice) throw (AudioOutputException);
100             };
101 
102             /** Audio Device Parameter 'NAME'
103              *
104              * Used to assign an arbitrary name to the JACK client of this
105              * audio device.
106              */
107             class ParameterName : public DeviceCreationParameterString {
108                 public:
109                     ParameterName();
110                     ParameterName(String s) throw (Exception);
111                     virtual String              Description() OVERRIDE;
112                     virtual bool                Fix() OVERRIDE;
113                     virtual bool                Mandatory() OVERRIDE;
114                     virtual std::map<String,DeviceCreationParameter*> DependsAsParameters() OVERRIDE;
115                     virtual std::vector<String> PossibilitiesAsString(std::map<String,String> Parameters) OVERRIDE;
116                     virtual optional<String>    DefaultAsString(std::map<String,String> Parameters) OVERRIDE;
117                     virtual void                OnSetValue(String s) throw (Exception) OVERRIDE;
118                     static String Name();
119             };
120 
121             /** Audio Device Parameter 'SAMPLERATE'
122              *
123              * Used to retrieve the sample rate of the JACK audio output
124              * device. Even though the sample rate of the JACK server might
125              * change during runtime, the JACK API currently however does not
126              * allow clients to change the sample rate. So this parameter is
127              * read only.
128              *
129              * This base parameter class has just been overridden for this JACK
130              * driver to implement a valid default value for sample rate. The
131              * default value will simply return the sample rate of the currently
132              * running JACK server. It will return "nothing" if the JACK server
133              * is not running at that point.
134              */
135             class ParameterSampleRate : public AudioOutputDevice::ParameterSampleRate {
136                 public:
137                     ParameterSampleRate();
138                     ParameterSampleRate(String s);
139                     virtual optional<int> DefaultAsInt(std::map<String,String> Parameters) OVERRIDE;
140                     virtual void OnSetValue(int i) throw (Exception) OVERRIDE;
141             };
142 
143             // derived abstract methods from class 'AudioOutputDevice'
144             virtual void Play() OVERRIDE;
145             virtual bool IsPlaying() OVERRIDE;
146             virtual void Stop() OVERRIDE;
147             virtual uint MaxSamplesPerCycle() OVERRIDE;
148             virtual uint SampleRate() OVERRIDE;
149             virtual AudioChannel* CreateChannel(uint ChannelNr) OVERRIDE;
150             virtual String Driver() OVERRIDE;
151             virtual float latency() OVERRIDE;
152 
153             static String Name();
154 
155             static String Description();
156             static String Version();
157 
158             int Process(uint Samples);  // FIXME: should be private
159             void UpdateJackBuffers(uint size);
160             void addListener(JackListener* listener);
161             jack_client_t* jackClientHandle();
162         protected:
163             AudioOutputDeviceJack(String* AutoConnectPortIDs = NULL, uint AutoConnectPorts = 0);
164         private:
165             ConditionServer csIsPlaying;
166             uint            uiMaxSamplesPerCycle;
167             jack_client_t*  hJackClient;
168             JackClient* pJackClient;
169     };
170 
171     // Callback functions for the libjack API
172     int  linuxsampler_libjack_process_callback(jack_nframes_t nframes, void* arg);
173 
174     /** JACK client
175      *
176      * Represents a jack client. This class is shared by
177      * AudioOutputDeviceJack and MidiInputDeviceJack. The jack server
178      * calls JackClient::Process, which in turn calls
179      * AudioOutputDeviceJack::Process and/or
180      * MidiInputDeviceJack::Process.
181      */
182     class JackClient {
183         public:
184             static JackClient* CreateAudio(String Name);
185             static JackClient* CreateMidi(String Name);
186             static void ReleaseAudio(String Name);
187             static void ReleaseMidi(String Name);
188             int Process(uint Samples);
189             void Stop();
190             void SetAudioOutputDevice(AudioOutputDeviceJack* device);
191             #if HAVE_JACK_MIDI
192             void SetMidiInputDevice(MidiInputDeviceJack* device);
193             #endif
194             void addListener(JackListener* listener);
195 
196             jack_client_t* hJackClient;
197 
198         private:
199             std::vector<JackListener*> jackListeners;
200             static std::map<String, JackClient*> Clients;
201             struct config_t {
202                 AudioOutputDeviceJack* AudioDevice;
203                 #if HAVE_JACK_MIDI
204                 MidiInputDeviceJack* MidiDevice;
205                 #endif
206             };
207             SynchronizedConfig<config_t> Config;
208             SynchronizedConfig<config_t>::Reader ConfigReader;
209             bool audio;
210             bool midi;
211 
212             JackClient(String Name);
213             ~JackClient();
214 
215             // Callback functions for the libjack API
216 #if HAVE_JACK_ON_INFO_SHUTDOWN
217             static void libjackShutdownCallback(jack_status_t code, const char* reason, void *arg);
218 #else
219             static void libjackShutdownCallback(void *arg);
220 #endif
221             static int libjackSampleRateCallback(jack_nframes_t nframes, void *arg);
222             static int libjackBufferSizeCallback(jack_nframes_t nframes, void *arg);
223     };
224 
225     /**
226      * Currently not derived / instantiated by the sampler itself, however this
227      * class can be subclassed and used i.e. by a GUI build on top of the sampler,
228      * to react on JACK events. Because registering JACK callback functions through
229      * the general JACK API is not possible after the JACK client has been activated,
230      * and the latter is already the case as soon as an AudioOutputDeviceJack object
231      * has been instantiated.
232      */
233     class JackListener {
234     public:
235         virtual void onJackShutdown(jack_status_t code, const char* reason) = 0;
236     };
237 }
238 
239 #endif // HAVE_JACK
240 #endif // __LS_AUDIOOUTPUTDEVICEJACK_H__
241