1 //=========================================================
2 //  MusE
3 //  Linux Music Editor
4 //    $Id: jackaudio.h,v 1.20.2.4 2009/12/20 05:00:35 terminator356 Exp $
5 //  (C) Copyright 2002 Werner Schweer (ws@seh.de)
6 //  (C) Copyright 2015 Tim E. Real (terminator356 on sourceforge.net)
7 //
8 //  This program is free software; you can redistribute it and/or
9 //  modify it under the terms of the GNU General Public License
10 //  as published by the Free Software Foundation; version 2 of
11 //  the License, or (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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 //
22 //=========================================================
23 
24 #ifndef __JACKAUDIO_H__
25 #define __JACKAUDIO_H__
26 
27 #include <jack/jack.h>
28 #include <list>
29 #include "audiodev.h"
30 #include "operations.h"
31 
32 class QString;
33 
34 namespace MusEGlobal {
35 bool checkAudioDevice();
36 }
37 
38 namespace MusECore {
39 
40 enum JackCallbackEventType {PortRegister, PortUnregister, PortConnect, PortDisconnect, GraphChanged};
41 struct JackCallbackEvent
42 {
43   JackCallbackEventType type;
44   jack_port_id_t port_id_A;
45   jack_port_id_t port_id_B;
46   jack_port_t* port_A;
47   jack_port_t* port_B;
48 };
49 typedef std::list<JackCallbackEvent> JackCallbackEventList;
50 typedef std::list<JackCallbackEvent>::iterator iJackCallbackEvent;
51 
52 //---------------------------------------------------------
53 //   JackAudioDevice
54 //---------------------------------------------------------
55 
56 class JackAudioDevice : public AudioDevice {
57   public:
58       enum JackSyncPhases { SyncCheck = 0, SyncStarted, Syncing, Synced };
59       enum JackTimebaseMasterPhases { MasterCheck = 0, IsNotMaster, IsMaster };
60 
61   private:
62       jack_client_t* _client;
63       jack_transport_state_t transportState;
64       jack_position_t pos;
65       char jackRegisteredName[16];
66       // Free-running frame counter incremented always in process.
67       jack_nframes_t _frameCounter;
68 
69       PendingOperationList operations;
70       // Temporary, for processing callback event FIFO.
71       JackCallbackEventList jackCallbackEvents;
72 
73       void getJackPorts(const char** ports, std::list<QString>& name_list, bool midi, bool physical, int aliases);
74       static int processAudio(jack_nframes_t frames, void*);
75 
76       void processGraphChanges();
77       void processJackCallbackEvents(const Route& our_node, jack_port_t* our_port, RouteList* route_list, bool is_input);
78       void checkNewRouteConnections(jack_port_t* our_port, int channel, RouteList* route_list);
79       // Return 0: Neither disconnect nor unregister found
80       //        1: Disconnect found followed later by unregister
81       //        2: Disconnect found (with no unregister later)
82       int checkDisconnectCallback(const jack_port_t* our_port, const jack_port_t* port);
83       // Return 0: No port register found (or it was cancelled by a later unregister)
84       //        1: Port register was found.
85       int checkPortRegisterCallback(const jack_port_t* port);
86 
87       static int static_JackXRunCallback(void *);
88 
89 
90    public:
91       JackAudioDevice(jack_client_t* cl, char * jack_id_string);
92       virtual ~JackAudioDevice();
deviceType()93       virtual inline int deviceType() const { return JACK_AUDIO; }
driverName()94       virtual const char* driverName() const { return "JackAudioDevice"; }
95 
96       virtual bool start(int);
97       virtual void stop ();
98 
99       // These are meant to be called from inside process thread only.
100       virtual unsigned framesAtCycleStart() const;
101       virtual unsigned framesSinceCycleStart() const;
102 
jackClient()103       jack_client_t* jackClient() const { return _client; }
104       virtual void registerClient();
clientName()105       virtual const char* clientName() { return jackRegisteredName; }
nullify_client()106       virtual void nullify_client() { _client = 0; }
107 
108       float getDSP_Load();
109       virtual std::list<QString> outputPorts(bool midi = false, int aliases = -1);
110       virtual std::list<QString> inputPorts(bool midi = false, int aliases = -1);
111       virtual void* registerOutPort(const char* /*name*/, bool /*midi*/);
112       virtual void* registerInPort(const char* /*name*/, bool /*midi*/);
113       virtual void unregisterPort(void*);
114       virtual AudioDevice::PortType portType(void*) const;
115       virtual AudioDevice::PortDirection portDirection(void*) const;
116       virtual bool connect(void* src, void* dst);
117       virtual bool connect(const char* src, const char* dst);
118       virtual bool disconnect(void* src, void* dst);
119       virtual bool disconnect(const char* src, const char* dst);
connections(void * clientPort)120       virtual int connections(void* clientPort) { return jack_port_connected((jack_port_t*)clientPort); }
portConnectedTo(void * our_port,const char * port)121       virtual bool portConnectedTo(void* our_port, const char* port) { return jack_port_connected_to((jack_port_t*)our_port, port); }
122       // Returns true if the ports are connected.
123       virtual bool portsCanDisconnect(void* src, void* dst) const;
124       // Returns true if the ports are found and they are connected.
125       virtual bool portsCanDisconnect(const char* src, const char* dst) const;
126       // Returns true if the ports are not connected and CAN be connected.
127       virtual bool portsCanConnect(void* src, void* dst) const;
128       // Returns true if the ports are found and they are not connected and CAN be connected.
129       virtual bool portsCanConnect(const char* src, const char* dst) const;
130       // Returns true if the ports CAN be connected.
131       virtual bool portsCompatible(void* src, void* dst) const;
132       // Returns true if the ports are found and they CAN be connected.
133       virtual bool portsCompatible(const char* src, const char* dst) const;
134       virtual void setPortName(void* p, const char* n);
135       // preferred_name_or_alias: -1: No preference 0: Prefer canonical name 1: Prefer 1st alias 2: Prefer 2nd alias.
136       virtual char* portName(void* port, char* str, int str_size, int preferred_name_or_alias = -1);
canonicalPortName(void * port)137       virtual const char* canonicalPortName(void* port) { if(!port) return NULL; return jack_port_name((jack_port_t*)port); }
138       virtual void* findPort(const char* name);
139       virtual unsigned int portLatency(void* port, bool capture) const;
getBuffer(void * port,unsigned long nframes)140       virtual float* getBuffer(void* port, unsigned long nframes) {
141             return (float*)jack_port_get_buffer((jack_port_t*)port, nframes);
142             }
143 
144       // Sets the amount of time to wait before sync times out, in microseconds.
145       // Note that at least with the Jack driver, this function seems not realtime friendly.
146       virtual void setSyncTimeout(unsigned usec);
147       // The number of frames that the driver waits to switch to PLAY
148       //  mode after the audio sync function says it is ready to roll.
149       // For example Jack Transport waits one cycle while our own tranport does not.
150       virtual unsigned transportSyncToPlayDelay() const;
151       // The number of frames that the driver waits to relocate or switch to PLAY
152       //  mode after the a call to relocation or seek.
153       // For example Jack Transport waits two cycles while our own transport does not.
154       virtual unsigned transportRelocateOrPlayDelay() const;
155 
156       virtual int getState();
157       virtual unsigned int getCurFrame() const;
158       virtual unsigned framePos() const;
frameTime()159       virtual unsigned frameTime() const     { return _frameCounter; }
160       virtual uint64_t systemTimeUS() const;
isRealtime()161       virtual bool isRealtime()          { return jack_is_realtime(_client); }
162       // Jack does this for us.
setRealTime()163       virtual bool setRealTime() { return false; }
164       virtual int realtimePriority() const;
165       virtual unsigned curTransportFrame() const;
166 
167       virtual void startTransport();
168       virtual void stopTransport();
169       virtual void seekTransport(unsigned frame);
170       virtual void seekTransport(const Pos &p);
171       virtual void setFreewheel(bool f);
172       // Whether the device has its own transport (Jack transport etc.), beyond the one built into this class.
hasOwnTransport()173       virtual bool hasOwnTransport() const { return true; };
174       // Whether the device supports timebase master capabilities.
hasTimebaseMaster()175       virtual bool hasTimebaseMaster() const { return true; };
176       // Sets or resets timebase master. Returns 0 on success. Otherwise, may return an error code.
177       virtual int setMaster(bool f, bool unconditional = false);
178       jack_transport_state_t transportQuery(jack_position_t* pos);
179       bool timebaseQuery(unsigned frames, unsigned* bar, unsigned* beat, unsigned* tick, unsigned* curr_abs_tick, unsigned* next_ticks);
180 
181       void graphChanged();
182       };
183 
184 // Our own wrappers for functions we need to look up with dlsym:
185 typedef void(*jack_get_version_type)(int*, int*, int*, int*);
186 extern jack_get_version_type             jack_get_version_fp;
187 
188 typedef int(*jack_port_set_name_type)(jack_port_t*, const char*);
189 extern jack_port_set_name_type           jack_port_set_name_fp;
190 
191 typedef int(*jack_port_rename_type)(jack_client_t*, jack_port_t*, const char*);
192 extern jack_port_rename_type             jack_port_rename_fp;
193 
194 
195 } // namespace MusECore
196 
197 #endif
198 
199